Created
December 26, 2020 09:03
-
-
Save ayaysir/85918de4b10e1417b5ce243599ce8616 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="ko"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Document</title> | |
<style> | |
.image-container { | |
position: relative; | |
} | |
.arrow_box { | |
position: absolute; | |
background: #2e2e2e; | |
border: 2px solid #2e2e2e; | |
border-radius: 5px; | |
color: white; | |
padding: 7px; | |
font-size: 0.72em; | |
} | |
.arrow_box:after, | |
.arrow_box:before { | |
bottom: 100%; | |
left: 50%; | |
border: solid transparent; | |
content: ""; | |
height: 0; | |
width: 0; | |
position: absolute; | |
pointer-events: none; | |
} | |
.arrow_box:after { | |
border-color: rgba(140, 140, 140, 0); | |
border-bottom-color: #2e2e2e; | |
border-width: 6px; | |
margin-left: -6px; | |
} | |
.arrow_box:before { | |
border-color: rgba(77, 77, 77, 0); | |
border-bottom-color: #2e2e2e; | |
border-width: 9px; | |
margin-left: -9px; | |
} | |
</style> | |
</head> | |
<body> | |
<h1>갤러리 업로드</h1> | |
<div class="image-container" ondrop="drop(event)" ondragover="dragover(event)"> | |
<img id="preview-image" draggable="false" | |
src="https://dummyimage.com/500x500/ffffff/000000.png&text=preview+image"> | |
<input style="display: block;" type="file" id="input-image"> | |
</div> | |
<script> | |
function readImage(input) { | |
// 인풋 태그에 파일이 있는 경우 | |
if (input.files && input.files[0]) { | |
// 이미지 파일인지 검사 (생략) | |
// FileReader 인스턴스 생성 | |
const reader = new FileReader() | |
// 이미지가 로드가 된 경우 | |
reader.onload = e => { | |
const previewImage = document.getElementById("preview-image") | |
previewImage.src = e.target.result | |
} | |
// reader가 이미지 읽도록 하기 | |
reader.readAsDataURL(input.files[0]) | |
} | |
} | |
function clickHotspotImage(event) { | |
const img = event.target | |
const ratio = img.naturalWidth / img.width | |
// console.log(event.offsetX, event.offsetY) | |
// console.log(Math.floor(event.offsetX * ratio), Math.floor(event.offsetY * ratio)) | |
const tooltip = document.createElement("div") | |
tooltip.classList.add("arrow_box") | |
tooltip.setAttribute("contenteditable", "false") | |
tooltip.setAttribute("draggable", "true") | |
tooltip.setAttribute("ondragstart", "dragstart(event)") | |
tooltip.style.top = event.offsetY + "px" | |
tooltip.textContent = "이것은 무엇인가요?" | |
document.querySelector(".image-container").appendChild(tooltip) | |
//console.log(tooltip, tooltip.offsetWidth) | |
// after rendering (div 가로 길이는 화면에 렌더링 된 후 계산됨) | |
tooltip.style.left = (event.offsetX - tooltip.offsetWidth / 2) + "px" | |
} | |
// input file에 change 이벤트 부여 | |
const inputImage = document.getElementById("input-image") | |
inputImage.addEventListener("change", e => { | |
readImage(e.target) | |
}) | |
const previewImage = document.getElementById("preview-image") | |
previewImage.addEventListener("click", clickHotspotImage) | |
const imageContainer = document.querySelector(".image-container") | |
imageContainer.addEventListener("dblclick", e => { | |
e.stopPropagation() | |
e.preventDefault() | |
// console.log("dblclick", e.target, e.currentTarget) | |
if (e.target.classList.contains("arrow_box")) { | |
e.target.setAttribute("contenteditable", "true") | |
// focus 하고 커서 위치를 마지막으로 | |
const el = e.target | |
el.focus() | |
if (typeof window.getSelection != "undefined" | |
&& typeof document.createRange != "undefined") { | |
const range = document.createRange() | |
range.selectNodeContents(el) | |
range.collapse(false) | |
const sel = window.getSelection() | |
sel.removeAllRanges() | |
sel.addRange(range) | |
} else if (typeof document.body.createTextRange != "undefined") { | |
const textRange = document.body.createTextRange() | |
textRange.moveToElementText(el) | |
textRange.collapse(false) | |
textRange.select() | |
} | |
} | |
}) | |
imageContainer.addEventListener("keydown", e => { | |
// console.log(e, e.target, e.currentTarget) | |
if (e.keyCode == 13) { | |
e.target.setAttribute("contenteditable", "false") | |
} | |
}) | |
// ---------- drag and drop ---------- // | |
let movingDiv = null | |
function dragstart(event) { | |
// console.log("dragstart") | |
movingDiv = event.target | |
} | |
function dragover(evnet) { | |
event.stopPropagation(); | |
event.preventDefault(); | |
// console.log("dragover", event) | |
} | |
function drop(event) { | |
event.stopPropagation() | |
event.preventDefault() | |
// console.log(event.offsetX, event.offsetY, movingDiv) | |
movingDiv.style.left = event.offsetX + "px" | |
movingDiv.style.top = event.offsetY + "px" | |
} | |
// -------------------------------- // | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment