是之前未答复的post的延续,其中我想将图像居中于拖动它的触摸位置。例如,如果用户触摸图像的右上角,图像将自动移动,因此其中心位于该触摸上。
在第一个代码片段中,这是我试图实现的行为:
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content=width=device-width,user-scalable=no>
<meta charset="UTF-8">
</head>
<body>
<script>
let shiftX;
let shiftY;
let img = document.createElement('img');
img.src = "https://upload.wikimedia.org/wikipedia/commons/thumb/3/35/Location_dot_blue.svg/1200px-Location_dot_blue.svg.png";
img.style.position = "absolute";
img.style.height = "20%";
img.addEventListener('touchstart', function(e) {
start = e.target.parentNode.id;
img.style.zIndex = 1;
});
img.addEventListener("touchmove", function(e) {
e.preventDefault();
img.style.left=e.touches[0].clientX-img.width/2+"px";
img.style.top=e.touches[0].clientY-img.height/2+"px";
});
document.body.appendChild(img);
</script>
</body>
</html>
但是我在实际代码中实现这一目标的最佳尝试是这样的:
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content=width=device-width,user-scalable=no>
<meta charset="UTF-8">
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
}
@media screen and (orientation: landscape) {
.chessboard {
height: 90%;
aspect-ratio : 1 / 1;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
}
@media screen and (orientation: portrait) {
.chessboard {
width: 90%;
aspect-ratio : 1 / 1;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
}
.row{
height: 12.5%;
width: 100%;
display: flex;
}
.square {
height: 100%;
width: 12.5%;
position: relative;
box-sizing: border-box;
}
.white {
background-color: #f1d8b0;
}
img{
position: absolute;
width: 90%;
height: 90%;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
</style>
</head>
<body>
<script>
let initialX;
let initialY;
let d = document.createElement('div');
d.setAttribute('class','chessboard')
for (let i = 0; i <8; i++){
let e = document.createElement('div');
e.setAttribute('class','row');
let f = document.createElement('div');
f.setAttribute('class','square white');
let img = document.createElement('img');
img.src = "https://upload.wikimedia.org/wikipedia/commons/thumb/3/35/Location_dot_blue.svg/1200px-Location_dot_blue.svg.png";
img.addEventListener('touchstart', function(e) {
start = e.target.parentNode.id;
img.style.zIndex = 1;
initialX = e.touches[0].clientX;
initialY = e.touches[0].clientY;
});
img.addEventListener("touchmove", function(e) {
e.preventDefault();
img.style.left=(e.touches[0].clientX-initialX)+img.width/2+"px";
img.style.top=(e.touches[0].clientY-initialY)+img.height/2+"px";
});
document.body.appendChild(d);
d.appendChild(e);
e.appendChild(f);
f.appendChild(img);
}
</script>
</body>
</html>
注:
忽略第二次触摸圆圈时的行为,这是在主代码中修复的
这里我们必须使用InitialX和InitialY,就像前面的例子一样,它是0,0(对于style.left,style.top,我们需要改变x和y坐标)
虽然这个解决方案很好,但因为它消除了偏移,所以它没有获得我想要的中心功能(也许我在这里有点完美主义)。
我很不确定下一步该做什么,我尝试添加不同的偏移量但无济于事。
我发现这个网站非常有用。
请评论我可以对此问题做出的任何改进。
一种可能的解决方案是使用
touchstart
、touchmove
和 touchend
事件来模拟拖放功能。您可以使用 getBoundingClientRect
方法获取元素的位置和大小,并将它们与触摸坐标进行比较以检测重叠。
还可以尝试使用
translate
属性相对于原始位置移动图像,并将其调整到触摸点。
let initialX, initialY, offsetX, offsetY;
let img = document.querySelector('img');
let divs = document.querySelectorAll('div');
img.addEventListener('touchstart', function(e) {
e.preventDefault();
let rect = img.getBoundingClientRect();
initialX = e.touches[0].clientX - rect.left;
initialY = e.touches[0].clientY - rect.top;
offsetX = rect.left;
offsetY = rect.top;
img.style.zIndex = 1;
});
img.addEventListener('touchmove', function(e) {
e.preventDefault();
let x = e.touches[0].clientX - initialX;
let y = e.touches[0].clientY - initialY;
img.style.transform = `translate(${x}px, ${y}px)`;
});
img.addEventListener('touchend', function(e) {
e.preventDefault();
let rect = img.getBoundingClientRect();
let target = null;
for (let div of divs) {
let divRect = div.getBoundingClientRect();
if (rect.left < divRect.right && rect.right > divRect.left && rect.top < divRect.bottom && rect.bottom > divRect.top) {
target = div;
break;
}
}
if (target) {
let temp = target.innerHTML;
target.innerHTML = img.outerHTML;
img.outerHTML = temp;
img = document.querySelector('img');
img.addEventListener('touchstart', touchstart);
img.addEventListener('touchmove', touchmove);
img.addEventListener('touchend', touchend);
}
img.style.transform = 'none';
img.style.zIndex = 0;
});