A continuation from a previous unanswered post in which I wanted to centre an image to the touch that is dragging it. For example if the user touches the top right corner of the image, the image will automatically move so its centre is on that touch instead.
In the first code snippet, this is the behaviour I am trying to achieve:
<!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>
But my best attempt of achieving this in my actual code is like so:
<!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>
Note:
Ignore the behaviour upon the second touch of the circles this is fixed in the main code
Here we have to use an InitialX and InitialY as in the previous example it was 0,0 (for style.left, style.top we need the change in x and y coordinates)
While this solution is nice, as it removes the offset it does not get this center functionality I want (maybe I'm being a bit to perfectionist here).
I'm pretty unsure what to do next, I have tried adding different offsets to no avail.
I have found this website quite useful though.
Please comment any improvements I can make to this question.
Edit due to answers: Please if you think you can answer this question could you make sure that your answer is in a code snippet editing the code of the latter snippet in this question. Secondly can you make sure it actually works for touch events, not drag events, touch events. Thank you.
Try this:
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.addEventListener("touchmove", function(e) {
e.preventDefault();
img.style.left=(e.touches[0].clientX-f.getBoundingClientRect().left)+"px";
img.style.top=(e.touches[0].clientY-f.getBoundingClientRect().top)+"px";
});
document.body.appendChild(d);
d.appendChild(e);
e.appendChild(f);
f.appendChild(img);
}
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%);
}