Using CSS transforms to translate/rotate sprite using arrow key inputs. Problem updating position












2














I am trying to control a Sprite using the arrow keys (UP/DOWN for Translation & LEFT/RIGHT for Rotation).



I need the sprite to translate in the direction it has been rotated in.
The issue is that when the sprite is rotated after the sprite has been translated, the position of the sprite resets to where it was originally. I have tried using one div for rotation and one div for translation to no success.



The problem I am facing is a little different to the usual "moving div around screen" issue because I need to move the div at angles and continue to move at that angle.



I feel I am overlooking a simple solution, I would really appreciate if someone could point me in the right direction! Is there an easier alternative to what I am attempting to do that someone could make me aware of?



I have created a JSFiddle to demonstrate what is going on:



CSS transform sprite fiddle






var r = document.getElementById("image2");

document.addEventListener("keyup", checkKeyUp);
document.addEventListener("keydown", checkKey);

var trany = 0;
var rotate = 0;

function checkKey(e) {
e = e || window.event;
if (e.keyCode == '38') {
// up arrow
trany = trany-1;
r.style.transform = 'rotate('+rotate+'deg)translateY('+trany+'vmin)';
}
else if (e.keyCode == '40') {
// down arrow
trany = trany+1;
r.style.transform = 'rotate('+rotate+'deg)translateY('+trany+'vmin)';
}
else if (e.keyCode == '37') {
// left arrow
rotate = rotate-.8;
r.style.transform = 'translateY('+trany+'vmin)rotate('+rotate+'deg)';
}
else if (e.keyCode == '39') {
// right arrow
rotate = rotate+.8;
r.style.transform = 'translateY('+trany+'vmin)rotate('+rotate+'deg)';
}
}

function checkKeyUp(e) {
e = e || window.event;
if (e.keyCode == '38') {
// up arrow
}
else if (e.keyCode == '40') {
// down arrow
}
else if (e.keyCode == '37') {
// left arrow
r.style.transform = 'translateY('+trany+'vmin)rotate('+rotate+'deg)';
}
else if (e.keyCode == '39') {
// right arrow
r.style.transform = 'translateY('+trany+'vmin)rotate('+rotate+'deg)';
}
}

#myAnimation {
top:250px;
left:250px;
position: absolute;
}
#image2 {
width:40%
}

img {
width: 30%;
}

<!DOCTYPE html>
<html>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<body>

<div id ="myContainer">
<div id="image1" style="height:300px;width:500px; background-
color:red;"></div>
</div>

<div id ="myAnimation">
<image id="image2" src="https://banner2.kisspng.com/20180415/pge/kisspng-arrow-desktop-wallpaper-symbol-clip-art-up-arrow-5ad37ddc82f384.4572004515238097565364.jpg" style="bottom:0px;width:10%"></image>
</div>

</body>
</html>












share|improve this question
























  • Tried to open the link and I get dialog containing "IE is not supported", my IE version is 11.0.9600.19155, add some error handling to your script.
    – SPlatten
    Nov 12 at 11:34












  • That's now fixed, however instead of a dialog, now it displays "IE is not supported" in the center of the browser window.
    – SPlatten
    Nov 12 at 11:41










  • The "Run code snippet" works as long as you go to Full page.
    – SPlatten
    Nov 12 at 11:44










  • Looks like you are only tracking y and using y for both x and y.
    – SPlatten
    Nov 12 at 11:45










  • You are switching between px and vmin units for your translateY value - you sure that’s what you want …?
    – misorude
    Nov 12 at 11:49


















2














I am trying to control a Sprite using the arrow keys (UP/DOWN for Translation & LEFT/RIGHT for Rotation).



I need the sprite to translate in the direction it has been rotated in.
The issue is that when the sprite is rotated after the sprite has been translated, the position of the sprite resets to where it was originally. I have tried using one div for rotation and one div for translation to no success.



The problem I am facing is a little different to the usual "moving div around screen" issue because I need to move the div at angles and continue to move at that angle.



I feel I am overlooking a simple solution, I would really appreciate if someone could point me in the right direction! Is there an easier alternative to what I am attempting to do that someone could make me aware of?



I have created a JSFiddle to demonstrate what is going on:



CSS transform sprite fiddle






var r = document.getElementById("image2");

document.addEventListener("keyup", checkKeyUp);
document.addEventListener("keydown", checkKey);

var trany = 0;
var rotate = 0;

function checkKey(e) {
e = e || window.event;
if (e.keyCode == '38') {
// up arrow
trany = trany-1;
r.style.transform = 'rotate('+rotate+'deg)translateY('+trany+'vmin)';
}
else if (e.keyCode == '40') {
// down arrow
trany = trany+1;
r.style.transform = 'rotate('+rotate+'deg)translateY('+trany+'vmin)';
}
else if (e.keyCode == '37') {
// left arrow
rotate = rotate-.8;
r.style.transform = 'translateY('+trany+'vmin)rotate('+rotate+'deg)';
}
else if (e.keyCode == '39') {
// right arrow
rotate = rotate+.8;
r.style.transform = 'translateY('+trany+'vmin)rotate('+rotate+'deg)';
}
}

function checkKeyUp(e) {
e = e || window.event;
if (e.keyCode == '38') {
// up arrow
}
else if (e.keyCode == '40') {
// down arrow
}
else if (e.keyCode == '37') {
// left arrow
r.style.transform = 'translateY('+trany+'vmin)rotate('+rotate+'deg)';
}
else if (e.keyCode == '39') {
// right arrow
r.style.transform = 'translateY('+trany+'vmin)rotate('+rotate+'deg)';
}
}

#myAnimation {
top:250px;
left:250px;
position: absolute;
}
#image2 {
width:40%
}

img {
width: 30%;
}

<!DOCTYPE html>
<html>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<body>

<div id ="myContainer">
<div id="image1" style="height:300px;width:500px; background-
color:red;"></div>
</div>

<div id ="myAnimation">
<image id="image2" src="https://banner2.kisspng.com/20180415/pge/kisspng-arrow-desktop-wallpaper-symbol-clip-art-up-arrow-5ad37ddc82f384.4572004515238097565364.jpg" style="bottom:0px;width:10%"></image>
</div>

</body>
</html>












share|improve this question
























  • Tried to open the link and I get dialog containing "IE is not supported", my IE version is 11.0.9600.19155, add some error handling to your script.
    – SPlatten
    Nov 12 at 11:34












  • That's now fixed, however instead of a dialog, now it displays "IE is not supported" in the center of the browser window.
    – SPlatten
    Nov 12 at 11:41










  • The "Run code snippet" works as long as you go to Full page.
    – SPlatten
    Nov 12 at 11:44










  • Looks like you are only tracking y and using y for both x and y.
    – SPlatten
    Nov 12 at 11:45










  • You are switching between px and vmin units for your translateY value - you sure that’s what you want …?
    – misorude
    Nov 12 at 11:49
















2












2








2


1





I am trying to control a Sprite using the arrow keys (UP/DOWN for Translation & LEFT/RIGHT for Rotation).



I need the sprite to translate in the direction it has been rotated in.
The issue is that when the sprite is rotated after the sprite has been translated, the position of the sprite resets to where it was originally. I have tried using one div for rotation and one div for translation to no success.



The problem I am facing is a little different to the usual "moving div around screen" issue because I need to move the div at angles and continue to move at that angle.



I feel I am overlooking a simple solution, I would really appreciate if someone could point me in the right direction! Is there an easier alternative to what I am attempting to do that someone could make me aware of?



I have created a JSFiddle to demonstrate what is going on:



CSS transform sprite fiddle






var r = document.getElementById("image2");

document.addEventListener("keyup", checkKeyUp);
document.addEventListener("keydown", checkKey);

var trany = 0;
var rotate = 0;

function checkKey(e) {
e = e || window.event;
if (e.keyCode == '38') {
// up arrow
trany = trany-1;
r.style.transform = 'rotate('+rotate+'deg)translateY('+trany+'vmin)';
}
else if (e.keyCode == '40') {
// down arrow
trany = trany+1;
r.style.transform = 'rotate('+rotate+'deg)translateY('+trany+'vmin)';
}
else if (e.keyCode == '37') {
// left arrow
rotate = rotate-.8;
r.style.transform = 'translateY('+trany+'vmin)rotate('+rotate+'deg)';
}
else if (e.keyCode == '39') {
// right arrow
rotate = rotate+.8;
r.style.transform = 'translateY('+trany+'vmin)rotate('+rotate+'deg)';
}
}

function checkKeyUp(e) {
e = e || window.event;
if (e.keyCode == '38') {
// up arrow
}
else if (e.keyCode == '40') {
// down arrow
}
else if (e.keyCode == '37') {
// left arrow
r.style.transform = 'translateY('+trany+'vmin)rotate('+rotate+'deg)';
}
else if (e.keyCode == '39') {
// right arrow
r.style.transform = 'translateY('+trany+'vmin)rotate('+rotate+'deg)';
}
}

#myAnimation {
top:250px;
left:250px;
position: absolute;
}
#image2 {
width:40%
}

img {
width: 30%;
}

<!DOCTYPE html>
<html>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<body>

<div id ="myContainer">
<div id="image1" style="height:300px;width:500px; background-
color:red;"></div>
</div>

<div id ="myAnimation">
<image id="image2" src="https://banner2.kisspng.com/20180415/pge/kisspng-arrow-desktop-wallpaper-symbol-clip-art-up-arrow-5ad37ddc82f384.4572004515238097565364.jpg" style="bottom:0px;width:10%"></image>
</div>

</body>
</html>












share|improve this question















I am trying to control a Sprite using the arrow keys (UP/DOWN for Translation & LEFT/RIGHT for Rotation).



I need the sprite to translate in the direction it has been rotated in.
The issue is that when the sprite is rotated after the sprite has been translated, the position of the sprite resets to where it was originally. I have tried using one div for rotation and one div for translation to no success.



The problem I am facing is a little different to the usual "moving div around screen" issue because I need to move the div at angles and continue to move at that angle.



I feel I am overlooking a simple solution, I would really appreciate if someone could point me in the right direction! Is there an easier alternative to what I am attempting to do that someone could make me aware of?



I have created a JSFiddle to demonstrate what is going on:



CSS transform sprite fiddle






var r = document.getElementById("image2");

document.addEventListener("keyup", checkKeyUp);
document.addEventListener("keydown", checkKey);

var trany = 0;
var rotate = 0;

function checkKey(e) {
e = e || window.event;
if (e.keyCode == '38') {
// up arrow
trany = trany-1;
r.style.transform = 'rotate('+rotate+'deg)translateY('+trany+'vmin)';
}
else if (e.keyCode == '40') {
// down arrow
trany = trany+1;
r.style.transform = 'rotate('+rotate+'deg)translateY('+trany+'vmin)';
}
else if (e.keyCode == '37') {
// left arrow
rotate = rotate-.8;
r.style.transform = 'translateY('+trany+'vmin)rotate('+rotate+'deg)';
}
else if (e.keyCode == '39') {
// right arrow
rotate = rotate+.8;
r.style.transform = 'translateY('+trany+'vmin)rotate('+rotate+'deg)';
}
}

function checkKeyUp(e) {
e = e || window.event;
if (e.keyCode == '38') {
// up arrow
}
else if (e.keyCode == '40') {
// down arrow
}
else if (e.keyCode == '37') {
// left arrow
r.style.transform = 'translateY('+trany+'vmin)rotate('+rotate+'deg)';
}
else if (e.keyCode == '39') {
// right arrow
r.style.transform = 'translateY('+trany+'vmin)rotate('+rotate+'deg)';
}
}

#myAnimation {
top:250px;
left:250px;
position: absolute;
}
#image2 {
width:40%
}

img {
width: 30%;
}

<!DOCTYPE html>
<html>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<body>

<div id ="myContainer">
<div id="image1" style="height:300px;width:500px; background-
color:red;"></div>
</div>

<div id ="myAnimation">
<image id="image2" src="https://banner2.kisspng.com/20180415/pge/kisspng-arrow-desktop-wallpaper-symbol-clip-art-up-arrow-5ad37ddc82f384.4572004515238097565364.jpg" style="bottom:0px;width:10%"></image>
</div>

</body>
</html>








var r = document.getElementById("image2");

document.addEventListener("keyup", checkKeyUp);
document.addEventListener("keydown", checkKey);

var trany = 0;
var rotate = 0;

function checkKey(e) {
e = e || window.event;
if (e.keyCode == '38') {
// up arrow
trany = trany-1;
r.style.transform = 'rotate('+rotate+'deg)translateY('+trany+'vmin)';
}
else if (e.keyCode == '40') {
// down arrow
trany = trany+1;
r.style.transform = 'rotate('+rotate+'deg)translateY('+trany+'vmin)';
}
else if (e.keyCode == '37') {
// left arrow
rotate = rotate-.8;
r.style.transform = 'translateY('+trany+'vmin)rotate('+rotate+'deg)';
}
else if (e.keyCode == '39') {
// right arrow
rotate = rotate+.8;
r.style.transform = 'translateY('+trany+'vmin)rotate('+rotate+'deg)';
}
}

function checkKeyUp(e) {
e = e || window.event;
if (e.keyCode == '38') {
// up arrow
}
else if (e.keyCode == '40') {
// down arrow
}
else if (e.keyCode == '37') {
// left arrow
r.style.transform = 'translateY('+trany+'vmin)rotate('+rotate+'deg)';
}
else if (e.keyCode == '39') {
// right arrow
r.style.transform = 'translateY('+trany+'vmin)rotate('+rotate+'deg)';
}
}

#myAnimation {
top:250px;
left:250px;
position: absolute;
}
#image2 {
width:40%
}

img {
width: 30%;
}

<!DOCTYPE html>
<html>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<body>

<div id ="myContainer">
<div id="image1" style="height:300px;width:500px; background-
color:red;"></div>
</div>

<div id ="myAnimation">
<image id="image2" src="https://banner2.kisspng.com/20180415/pge/kisspng-arrow-desktop-wallpaper-symbol-clip-art-up-arrow-5ad37ddc82f384.4572004515238097565364.jpg" style="bottom:0px;width:10%"></image>
</div>

</body>
</html>





var r = document.getElementById("image2");

document.addEventListener("keyup", checkKeyUp);
document.addEventListener("keydown", checkKey);

var trany = 0;
var rotate = 0;

function checkKey(e) {
e = e || window.event;
if (e.keyCode == '38') {
// up arrow
trany = trany-1;
r.style.transform = 'rotate('+rotate+'deg)translateY('+trany+'vmin)';
}
else if (e.keyCode == '40') {
// down arrow
trany = trany+1;
r.style.transform = 'rotate('+rotate+'deg)translateY('+trany+'vmin)';
}
else if (e.keyCode == '37') {
// left arrow
rotate = rotate-.8;
r.style.transform = 'translateY('+trany+'vmin)rotate('+rotate+'deg)';
}
else if (e.keyCode == '39') {
// right arrow
rotate = rotate+.8;
r.style.transform = 'translateY('+trany+'vmin)rotate('+rotate+'deg)';
}
}

function checkKeyUp(e) {
e = e || window.event;
if (e.keyCode == '38') {
// up arrow
}
else if (e.keyCode == '40') {
// down arrow
}
else if (e.keyCode == '37') {
// left arrow
r.style.transform = 'translateY('+trany+'vmin)rotate('+rotate+'deg)';
}
else if (e.keyCode == '39') {
// right arrow
r.style.transform = 'translateY('+trany+'vmin)rotate('+rotate+'deg)';
}
}

#myAnimation {
top:250px;
left:250px;
position: absolute;
}
#image2 {
width:40%
}

img {
width: 30%;
}

<!DOCTYPE html>
<html>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<body>

<div id ="myContainer">
<div id="image1" style="height:300px;width:500px; background-
color:red;"></div>
</div>

<div id ="myAnimation">
<image id="image2" src="https://banner2.kisspng.com/20180415/pge/kisspng-arrow-desktop-wallpaper-symbol-clip-art-up-arrow-5ad37ddc82f384.4572004515238097565364.jpg" style="bottom:0px;width:10%"></image>
</div>

</body>
</html>






javascript html css css3 css-transforms






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 12 at 12:57

























asked Nov 12 at 11:21









evandarcy

113




113












  • Tried to open the link and I get dialog containing "IE is not supported", my IE version is 11.0.9600.19155, add some error handling to your script.
    – SPlatten
    Nov 12 at 11:34












  • That's now fixed, however instead of a dialog, now it displays "IE is not supported" in the center of the browser window.
    – SPlatten
    Nov 12 at 11:41










  • The "Run code snippet" works as long as you go to Full page.
    – SPlatten
    Nov 12 at 11:44










  • Looks like you are only tracking y and using y for both x and y.
    – SPlatten
    Nov 12 at 11:45










  • You are switching between px and vmin units for your translateY value - you sure that’s what you want …?
    – misorude
    Nov 12 at 11:49




















  • Tried to open the link and I get dialog containing "IE is not supported", my IE version is 11.0.9600.19155, add some error handling to your script.
    – SPlatten
    Nov 12 at 11:34












  • That's now fixed, however instead of a dialog, now it displays "IE is not supported" in the center of the browser window.
    – SPlatten
    Nov 12 at 11:41










  • The "Run code snippet" works as long as you go to Full page.
    – SPlatten
    Nov 12 at 11:44










  • Looks like you are only tracking y and using y for both x and y.
    – SPlatten
    Nov 12 at 11:45










  • You are switching between px and vmin units for your translateY value - you sure that’s what you want …?
    – misorude
    Nov 12 at 11:49


















Tried to open the link and I get dialog containing "IE is not supported", my IE version is 11.0.9600.19155, add some error handling to your script.
– SPlatten
Nov 12 at 11:34






Tried to open the link and I get dialog containing "IE is not supported", my IE version is 11.0.9600.19155, add some error handling to your script.
– SPlatten
Nov 12 at 11:34














That's now fixed, however instead of a dialog, now it displays "IE is not supported" in the center of the browser window.
– SPlatten
Nov 12 at 11:41




That's now fixed, however instead of a dialog, now it displays "IE is not supported" in the center of the browser window.
– SPlatten
Nov 12 at 11:41












The "Run code snippet" works as long as you go to Full page.
– SPlatten
Nov 12 at 11:44




The "Run code snippet" works as long as you go to Full page.
– SPlatten
Nov 12 at 11:44












Looks like you are only tracking y and using y for both x and y.
– SPlatten
Nov 12 at 11:45




Looks like you are only tracking y and using y for both x and y.
– SPlatten
Nov 12 at 11:45












You are switching between px and vmin units for your translateY value - you sure that’s what you want …?
– misorude
Nov 12 at 11:49






You are switching between px and vmin units for your translateY value - you sure that’s what you want …?
– misorude
Nov 12 at 11:49














2 Answers
2






active

oldest

votes


















1














To fix this problem we need to understand how transform works. It does each step one by one. If we want, for example to move diagonally, first we need to rotate, then translate. If we want to make the next move, our previous steps need to be saved. If we don't remember them, the arrow will be animated from the beginning.
So, on each animation end (key up) we need to save all the previous steps.
The next step is all the previous steps + translate/rotate.



Here is your code that I think is working correctly:



var r = document.getElementById("image2");

document.addEventListener("keyup", checkKeyUp);
document.addEventListener("keydown", checkKey);

var saved_moves = '';

var trany = 0;
var rotate = 0;

function checkKey(e) {
e = e || window.event;
if (e.keyCode == '38') {
// up arrow
trany = trany-1;
r.style.transform = saved_moves + 'translateY('+trany+'vmin)';
}
else if (e.keyCode == '40') {
// down arrow
trany = trany+1;
r.style.transform = saved_moves + 'translateY('+trany+'vmin)';
}
else if (e.keyCode == '37') {
// left arrow
rotate = rotate-2;
r.style.transform = saved_moves + 'rotate('+rotate+'deg)';
}
else if (e.keyCode == '39') {
// right arrow
rotate = rotate+2;
r.style.transform = saved_moves + 'rotate('+rotate+'deg)';
}
}

function checkKeyUp(e) {
e = e || window.event;
if (e.keyCode == '37' || e.keyCode == '38' || e.keyCode == '39' || e.keyCode == '40') {
// every arrow
saved_moves = r.style.transform;
// reset trany and rotate values
trany = 0;
rotate = 0;
}
}


You can check this jsfiddle https://jsfiddle.net/cyv0j1du/49/



EDIT
Becouse the solution above would create a very long transform, I've came up with different solution. When you release the key, app is reading the matrix value, and then it changes the arrow top and left value. Now only rotate value is remembered.



// Based on the absolute position you've chosen
var left = 250;
var top = 250;

function checkKeyUp(e) {
e = e || window.event;
if (e.keyCode == '37' || e.keyCode == '38' || e.keyCode == '39' || e.keyCode == '40') {

var matrix = window.getComputedStyle(r).getPropertyValue('transform');

matrix = matrix.slice(0, -1);

var values = matrix.split(',');
var x = values[4];
var y = values[5];

top += parseInt(y);
left += parseInt(x);

r.style.top = top + 'px';
r.style.left = left + 'px';

r.style.transform = 'rotateZ('+rotate+'deg)';

trany = 0;
}
}


I've also deleted #myAnimation



#image2 {
width: 20%;
position: absolute;
top: 250px;
left: 250px;
}


so I've deleted the div



 <image id="image2" src="https://banner2.kisspng.com/20180415/pge/kisspng-arrow-desktop-wallpaper-symbol-clip-art-up-arrow-5ad37ddc82f384.4572004515238097565364.jpg" style="bottom:0px;width:10%"></image>


You can check how it works here:
https://jsfiddle.net/w1ox240m/57/






share|improve this answer























  • intresting solution but we will end with a HUGE tranform after a lot of movements
    – Temani Afif
    Nov 12 at 12:41










  • Hey man, thanks so much for this! It helps A LOT. I completely understand the code too, it's a smart solution, thanks again.
    – evandarcy
    Nov 12 at 12:42










  • How much will the added transforms affect performance though?
    – evandarcy
    Nov 12 at 12:42










  • @TemaniAfif agreed
    – evandarcy
    Nov 12 at 12:44










  • @evandarcy you can test and see. It depends on how the browser will handle this, A big transform will at the end be converted to one matrix, so you need to see if the conversion is taking a lot of time or not
    – Temani Afif
    Nov 12 at 12:45





















0














what you want to achieve is to move your element independently from its previous state and this cannot be achieved using only transform since transform always consider the initial state in order to move your element.



An idea is to consider using bottom/left to move the element and use only transform to rotate the element. The angle of rotation will define how you will adjust the bottom and left properties:






var r = document.getElementById("image2");

document.addEventListener("keydown", checkKey);

var rotate = 0;
var left=0;
var bottom= 0;

function checkKey(e) {
e = e || window.event;
if (e.keyCode == '38') {
// up arrow
r.style.left = left + Math.sin(rotate*Math.PI/180) + 'px';
r.style.bottom = bottom + Math.cos(rotate*Math.PI/180) + 'px';
} else if (e.keyCode == '40') {
// down arrow
r.style.left = left - Math.sin(rotate*Math.PI/180) + 'px';
r.style.bottom = bottom - Math.cos(rotate*Math.PI/180) + 'px';
} else if (e.keyCode == '37') {
// left arrow
rotate = rotate - .8;
r.style.transform = 'rotate(' + rotate + 'deg)';
} else if (e.keyCode == '39') {
// right arrow
rotate = rotate + .8;
r.style.transform = 'rotate(' + rotate + 'deg)';
}
left = parseFloat(r.style.left);
bottom = parseFloat(r.style.bottom);
}

#image2 {
width: 40px;
position: absolute;
}

<img id="image2" src="https://banner2.kisspng.com/20180415/pge/kisspng-arrow-desktop-wallpaper-symbol-clip-art-up-arrow-5ad37ddc82f384.4572004515238097565364.jpg" style="left:0;bottom:0;">








share|improve this answer























  • Another nice solution, thank you Temani. I had attempted to implement this before but gave up as I did not like the movement at an angle. It is not smooth and kind of wiggles a pixel or two side to side as it moves.
    – evandarcy
    Nov 12 at 12:54










  • @evandarcy yes, changing left/bottom will not be as smooth as translate but it remains another way that we can probably improve ;)
    – Temani Afif
    Nov 12 at 13:05










  • of course! I appreciate your answer, it's very helpful :-)
    – evandarcy
    Nov 12 at 13:09











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53261116%2fusing-css-transforms-to-translate-rotate-sprite-using-arrow-key-inputs-problem%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














To fix this problem we need to understand how transform works. It does each step one by one. If we want, for example to move diagonally, first we need to rotate, then translate. If we want to make the next move, our previous steps need to be saved. If we don't remember them, the arrow will be animated from the beginning.
So, on each animation end (key up) we need to save all the previous steps.
The next step is all the previous steps + translate/rotate.



Here is your code that I think is working correctly:



var r = document.getElementById("image2");

document.addEventListener("keyup", checkKeyUp);
document.addEventListener("keydown", checkKey);

var saved_moves = '';

var trany = 0;
var rotate = 0;

function checkKey(e) {
e = e || window.event;
if (e.keyCode == '38') {
// up arrow
trany = trany-1;
r.style.transform = saved_moves + 'translateY('+trany+'vmin)';
}
else if (e.keyCode == '40') {
// down arrow
trany = trany+1;
r.style.transform = saved_moves + 'translateY('+trany+'vmin)';
}
else if (e.keyCode == '37') {
// left arrow
rotate = rotate-2;
r.style.transform = saved_moves + 'rotate('+rotate+'deg)';
}
else if (e.keyCode == '39') {
// right arrow
rotate = rotate+2;
r.style.transform = saved_moves + 'rotate('+rotate+'deg)';
}
}

function checkKeyUp(e) {
e = e || window.event;
if (e.keyCode == '37' || e.keyCode == '38' || e.keyCode == '39' || e.keyCode == '40') {
// every arrow
saved_moves = r.style.transform;
// reset trany and rotate values
trany = 0;
rotate = 0;
}
}


You can check this jsfiddle https://jsfiddle.net/cyv0j1du/49/



EDIT
Becouse the solution above would create a very long transform, I've came up with different solution. When you release the key, app is reading the matrix value, and then it changes the arrow top and left value. Now only rotate value is remembered.



// Based on the absolute position you've chosen
var left = 250;
var top = 250;

function checkKeyUp(e) {
e = e || window.event;
if (e.keyCode == '37' || e.keyCode == '38' || e.keyCode == '39' || e.keyCode == '40') {

var matrix = window.getComputedStyle(r).getPropertyValue('transform');

matrix = matrix.slice(0, -1);

var values = matrix.split(',');
var x = values[4];
var y = values[5];

top += parseInt(y);
left += parseInt(x);

r.style.top = top + 'px';
r.style.left = left + 'px';

r.style.transform = 'rotateZ('+rotate+'deg)';

trany = 0;
}
}


I've also deleted #myAnimation



#image2 {
width: 20%;
position: absolute;
top: 250px;
left: 250px;
}


so I've deleted the div



 <image id="image2" src="https://banner2.kisspng.com/20180415/pge/kisspng-arrow-desktop-wallpaper-symbol-clip-art-up-arrow-5ad37ddc82f384.4572004515238097565364.jpg" style="bottom:0px;width:10%"></image>


You can check how it works here:
https://jsfiddle.net/w1ox240m/57/






share|improve this answer























  • intresting solution but we will end with a HUGE tranform after a lot of movements
    – Temani Afif
    Nov 12 at 12:41










  • Hey man, thanks so much for this! It helps A LOT. I completely understand the code too, it's a smart solution, thanks again.
    – evandarcy
    Nov 12 at 12:42










  • How much will the added transforms affect performance though?
    – evandarcy
    Nov 12 at 12:42










  • @TemaniAfif agreed
    – evandarcy
    Nov 12 at 12:44










  • @evandarcy you can test and see. It depends on how the browser will handle this, A big transform will at the end be converted to one matrix, so you need to see if the conversion is taking a lot of time or not
    – Temani Afif
    Nov 12 at 12:45


















1














To fix this problem we need to understand how transform works. It does each step one by one. If we want, for example to move diagonally, first we need to rotate, then translate. If we want to make the next move, our previous steps need to be saved. If we don't remember them, the arrow will be animated from the beginning.
So, on each animation end (key up) we need to save all the previous steps.
The next step is all the previous steps + translate/rotate.



Here is your code that I think is working correctly:



var r = document.getElementById("image2");

document.addEventListener("keyup", checkKeyUp);
document.addEventListener("keydown", checkKey);

var saved_moves = '';

var trany = 0;
var rotate = 0;

function checkKey(e) {
e = e || window.event;
if (e.keyCode == '38') {
// up arrow
trany = trany-1;
r.style.transform = saved_moves + 'translateY('+trany+'vmin)';
}
else if (e.keyCode == '40') {
// down arrow
trany = trany+1;
r.style.transform = saved_moves + 'translateY('+trany+'vmin)';
}
else if (e.keyCode == '37') {
// left arrow
rotate = rotate-2;
r.style.transform = saved_moves + 'rotate('+rotate+'deg)';
}
else if (e.keyCode == '39') {
// right arrow
rotate = rotate+2;
r.style.transform = saved_moves + 'rotate('+rotate+'deg)';
}
}

function checkKeyUp(e) {
e = e || window.event;
if (e.keyCode == '37' || e.keyCode == '38' || e.keyCode == '39' || e.keyCode == '40') {
// every arrow
saved_moves = r.style.transform;
// reset trany and rotate values
trany = 0;
rotate = 0;
}
}


You can check this jsfiddle https://jsfiddle.net/cyv0j1du/49/



EDIT
Becouse the solution above would create a very long transform, I've came up with different solution. When you release the key, app is reading the matrix value, and then it changes the arrow top and left value. Now only rotate value is remembered.



// Based on the absolute position you've chosen
var left = 250;
var top = 250;

function checkKeyUp(e) {
e = e || window.event;
if (e.keyCode == '37' || e.keyCode == '38' || e.keyCode == '39' || e.keyCode == '40') {

var matrix = window.getComputedStyle(r).getPropertyValue('transform');

matrix = matrix.slice(0, -1);

var values = matrix.split(',');
var x = values[4];
var y = values[5];

top += parseInt(y);
left += parseInt(x);

r.style.top = top + 'px';
r.style.left = left + 'px';

r.style.transform = 'rotateZ('+rotate+'deg)';

trany = 0;
}
}


I've also deleted #myAnimation



#image2 {
width: 20%;
position: absolute;
top: 250px;
left: 250px;
}


so I've deleted the div



 <image id="image2" src="https://banner2.kisspng.com/20180415/pge/kisspng-arrow-desktop-wallpaper-symbol-clip-art-up-arrow-5ad37ddc82f384.4572004515238097565364.jpg" style="bottom:0px;width:10%"></image>


You can check how it works here:
https://jsfiddle.net/w1ox240m/57/






share|improve this answer























  • intresting solution but we will end with a HUGE tranform after a lot of movements
    – Temani Afif
    Nov 12 at 12:41










  • Hey man, thanks so much for this! It helps A LOT. I completely understand the code too, it's a smart solution, thanks again.
    – evandarcy
    Nov 12 at 12:42










  • How much will the added transforms affect performance though?
    – evandarcy
    Nov 12 at 12:42










  • @TemaniAfif agreed
    – evandarcy
    Nov 12 at 12:44










  • @evandarcy you can test and see. It depends on how the browser will handle this, A big transform will at the end be converted to one matrix, so you need to see if the conversion is taking a lot of time or not
    – Temani Afif
    Nov 12 at 12:45
















1












1








1






To fix this problem we need to understand how transform works. It does each step one by one. If we want, for example to move diagonally, first we need to rotate, then translate. If we want to make the next move, our previous steps need to be saved. If we don't remember them, the arrow will be animated from the beginning.
So, on each animation end (key up) we need to save all the previous steps.
The next step is all the previous steps + translate/rotate.



Here is your code that I think is working correctly:



var r = document.getElementById("image2");

document.addEventListener("keyup", checkKeyUp);
document.addEventListener("keydown", checkKey);

var saved_moves = '';

var trany = 0;
var rotate = 0;

function checkKey(e) {
e = e || window.event;
if (e.keyCode == '38') {
// up arrow
trany = trany-1;
r.style.transform = saved_moves + 'translateY('+trany+'vmin)';
}
else if (e.keyCode == '40') {
// down arrow
trany = trany+1;
r.style.transform = saved_moves + 'translateY('+trany+'vmin)';
}
else if (e.keyCode == '37') {
// left arrow
rotate = rotate-2;
r.style.transform = saved_moves + 'rotate('+rotate+'deg)';
}
else if (e.keyCode == '39') {
// right arrow
rotate = rotate+2;
r.style.transform = saved_moves + 'rotate('+rotate+'deg)';
}
}

function checkKeyUp(e) {
e = e || window.event;
if (e.keyCode == '37' || e.keyCode == '38' || e.keyCode == '39' || e.keyCode == '40') {
// every arrow
saved_moves = r.style.transform;
// reset trany and rotate values
trany = 0;
rotate = 0;
}
}


You can check this jsfiddle https://jsfiddle.net/cyv0j1du/49/



EDIT
Becouse the solution above would create a very long transform, I've came up with different solution. When you release the key, app is reading the matrix value, and then it changes the arrow top and left value. Now only rotate value is remembered.



// Based on the absolute position you've chosen
var left = 250;
var top = 250;

function checkKeyUp(e) {
e = e || window.event;
if (e.keyCode == '37' || e.keyCode == '38' || e.keyCode == '39' || e.keyCode == '40') {

var matrix = window.getComputedStyle(r).getPropertyValue('transform');

matrix = matrix.slice(0, -1);

var values = matrix.split(',');
var x = values[4];
var y = values[5];

top += parseInt(y);
left += parseInt(x);

r.style.top = top + 'px';
r.style.left = left + 'px';

r.style.transform = 'rotateZ('+rotate+'deg)';

trany = 0;
}
}


I've also deleted #myAnimation



#image2 {
width: 20%;
position: absolute;
top: 250px;
left: 250px;
}


so I've deleted the div



 <image id="image2" src="https://banner2.kisspng.com/20180415/pge/kisspng-arrow-desktop-wallpaper-symbol-clip-art-up-arrow-5ad37ddc82f384.4572004515238097565364.jpg" style="bottom:0px;width:10%"></image>


You can check how it works here:
https://jsfiddle.net/w1ox240m/57/






share|improve this answer














To fix this problem we need to understand how transform works. It does each step one by one. If we want, for example to move diagonally, first we need to rotate, then translate. If we want to make the next move, our previous steps need to be saved. If we don't remember them, the arrow will be animated from the beginning.
So, on each animation end (key up) we need to save all the previous steps.
The next step is all the previous steps + translate/rotate.



Here is your code that I think is working correctly:



var r = document.getElementById("image2");

document.addEventListener("keyup", checkKeyUp);
document.addEventListener("keydown", checkKey);

var saved_moves = '';

var trany = 0;
var rotate = 0;

function checkKey(e) {
e = e || window.event;
if (e.keyCode == '38') {
// up arrow
trany = trany-1;
r.style.transform = saved_moves + 'translateY('+trany+'vmin)';
}
else if (e.keyCode == '40') {
// down arrow
trany = trany+1;
r.style.transform = saved_moves + 'translateY('+trany+'vmin)';
}
else if (e.keyCode == '37') {
// left arrow
rotate = rotate-2;
r.style.transform = saved_moves + 'rotate('+rotate+'deg)';
}
else if (e.keyCode == '39') {
// right arrow
rotate = rotate+2;
r.style.transform = saved_moves + 'rotate('+rotate+'deg)';
}
}

function checkKeyUp(e) {
e = e || window.event;
if (e.keyCode == '37' || e.keyCode == '38' || e.keyCode == '39' || e.keyCode == '40') {
// every arrow
saved_moves = r.style.transform;
// reset trany and rotate values
trany = 0;
rotate = 0;
}
}


You can check this jsfiddle https://jsfiddle.net/cyv0j1du/49/



EDIT
Becouse the solution above would create a very long transform, I've came up with different solution. When you release the key, app is reading the matrix value, and then it changes the arrow top and left value. Now only rotate value is remembered.



// Based on the absolute position you've chosen
var left = 250;
var top = 250;

function checkKeyUp(e) {
e = e || window.event;
if (e.keyCode == '37' || e.keyCode == '38' || e.keyCode == '39' || e.keyCode == '40') {

var matrix = window.getComputedStyle(r).getPropertyValue('transform');

matrix = matrix.slice(0, -1);

var values = matrix.split(',');
var x = values[4];
var y = values[5];

top += parseInt(y);
left += parseInt(x);

r.style.top = top + 'px';
r.style.left = left + 'px';

r.style.transform = 'rotateZ('+rotate+'deg)';

trany = 0;
}
}


I've also deleted #myAnimation



#image2 {
width: 20%;
position: absolute;
top: 250px;
left: 250px;
}


so I've deleted the div



 <image id="image2" src="https://banner2.kisspng.com/20180415/pge/kisspng-arrow-desktop-wallpaper-symbol-clip-art-up-arrow-5ad37ddc82f384.4572004515238097565364.jpg" style="bottom:0px;width:10%"></image>


You can check how it works here:
https://jsfiddle.net/w1ox240m/57/







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 12 at 13:56

























answered Nov 12 at 12:17









KusioDev

114




114












  • intresting solution but we will end with a HUGE tranform after a lot of movements
    – Temani Afif
    Nov 12 at 12:41










  • Hey man, thanks so much for this! It helps A LOT. I completely understand the code too, it's a smart solution, thanks again.
    – evandarcy
    Nov 12 at 12:42










  • How much will the added transforms affect performance though?
    – evandarcy
    Nov 12 at 12:42










  • @TemaniAfif agreed
    – evandarcy
    Nov 12 at 12:44










  • @evandarcy you can test and see. It depends on how the browser will handle this, A big transform will at the end be converted to one matrix, so you need to see if the conversion is taking a lot of time or not
    – Temani Afif
    Nov 12 at 12:45




















  • intresting solution but we will end with a HUGE tranform after a lot of movements
    – Temani Afif
    Nov 12 at 12:41










  • Hey man, thanks so much for this! It helps A LOT. I completely understand the code too, it's a smart solution, thanks again.
    – evandarcy
    Nov 12 at 12:42










  • How much will the added transforms affect performance though?
    – evandarcy
    Nov 12 at 12:42










  • @TemaniAfif agreed
    – evandarcy
    Nov 12 at 12:44










  • @evandarcy you can test and see. It depends on how the browser will handle this, A big transform will at the end be converted to one matrix, so you need to see if the conversion is taking a lot of time or not
    – Temani Afif
    Nov 12 at 12:45


















intresting solution but we will end with a HUGE tranform after a lot of movements
– Temani Afif
Nov 12 at 12:41




intresting solution but we will end with a HUGE tranform after a lot of movements
– Temani Afif
Nov 12 at 12:41












Hey man, thanks so much for this! It helps A LOT. I completely understand the code too, it's a smart solution, thanks again.
– evandarcy
Nov 12 at 12:42




Hey man, thanks so much for this! It helps A LOT. I completely understand the code too, it's a smart solution, thanks again.
– evandarcy
Nov 12 at 12:42












How much will the added transforms affect performance though?
– evandarcy
Nov 12 at 12:42




How much will the added transforms affect performance though?
– evandarcy
Nov 12 at 12:42












@TemaniAfif agreed
– evandarcy
Nov 12 at 12:44




@TemaniAfif agreed
– evandarcy
Nov 12 at 12:44












@evandarcy you can test and see. It depends on how the browser will handle this, A big transform will at the end be converted to one matrix, so you need to see if the conversion is taking a lot of time or not
– Temani Afif
Nov 12 at 12:45






@evandarcy you can test and see. It depends on how the browser will handle this, A big transform will at the end be converted to one matrix, so you need to see if the conversion is taking a lot of time or not
– Temani Afif
Nov 12 at 12:45















0














what you want to achieve is to move your element independently from its previous state and this cannot be achieved using only transform since transform always consider the initial state in order to move your element.



An idea is to consider using bottom/left to move the element and use only transform to rotate the element. The angle of rotation will define how you will adjust the bottom and left properties:






var r = document.getElementById("image2");

document.addEventListener("keydown", checkKey);

var rotate = 0;
var left=0;
var bottom= 0;

function checkKey(e) {
e = e || window.event;
if (e.keyCode == '38') {
// up arrow
r.style.left = left + Math.sin(rotate*Math.PI/180) + 'px';
r.style.bottom = bottom + Math.cos(rotate*Math.PI/180) + 'px';
} else if (e.keyCode == '40') {
// down arrow
r.style.left = left - Math.sin(rotate*Math.PI/180) + 'px';
r.style.bottom = bottom - Math.cos(rotate*Math.PI/180) + 'px';
} else if (e.keyCode == '37') {
// left arrow
rotate = rotate - .8;
r.style.transform = 'rotate(' + rotate + 'deg)';
} else if (e.keyCode == '39') {
// right arrow
rotate = rotate + .8;
r.style.transform = 'rotate(' + rotate + 'deg)';
}
left = parseFloat(r.style.left);
bottom = parseFloat(r.style.bottom);
}

#image2 {
width: 40px;
position: absolute;
}

<img id="image2" src="https://banner2.kisspng.com/20180415/pge/kisspng-arrow-desktop-wallpaper-symbol-clip-art-up-arrow-5ad37ddc82f384.4572004515238097565364.jpg" style="left:0;bottom:0;">








share|improve this answer























  • Another nice solution, thank you Temani. I had attempted to implement this before but gave up as I did not like the movement at an angle. It is not smooth and kind of wiggles a pixel or two side to side as it moves.
    – evandarcy
    Nov 12 at 12:54










  • @evandarcy yes, changing left/bottom will not be as smooth as translate but it remains another way that we can probably improve ;)
    – Temani Afif
    Nov 12 at 13:05










  • of course! I appreciate your answer, it's very helpful :-)
    – evandarcy
    Nov 12 at 13:09
















0














what you want to achieve is to move your element independently from its previous state and this cannot be achieved using only transform since transform always consider the initial state in order to move your element.



An idea is to consider using bottom/left to move the element and use only transform to rotate the element. The angle of rotation will define how you will adjust the bottom and left properties:






var r = document.getElementById("image2");

document.addEventListener("keydown", checkKey);

var rotate = 0;
var left=0;
var bottom= 0;

function checkKey(e) {
e = e || window.event;
if (e.keyCode == '38') {
// up arrow
r.style.left = left + Math.sin(rotate*Math.PI/180) + 'px';
r.style.bottom = bottom + Math.cos(rotate*Math.PI/180) + 'px';
} else if (e.keyCode == '40') {
// down arrow
r.style.left = left - Math.sin(rotate*Math.PI/180) + 'px';
r.style.bottom = bottom - Math.cos(rotate*Math.PI/180) + 'px';
} else if (e.keyCode == '37') {
// left arrow
rotate = rotate - .8;
r.style.transform = 'rotate(' + rotate + 'deg)';
} else if (e.keyCode == '39') {
// right arrow
rotate = rotate + .8;
r.style.transform = 'rotate(' + rotate + 'deg)';
}
left = parseFloat(r.style.left);
bottom = parseFloat(r.style.bottom);
}

#image2 {
width: 40px;
position: absolute;
}

<img id="image2" src="https://banner2.kisspng.com/20180415/pge/kisspng-arrow-desktop-wallpaper-symbol-clip-art-up-arrow-5ad37ddc82f384.4572004515238097565364.jpg" style="left:0;bottom:0;">








share|improve this answer























  • Another nice solution, thank you Temani. I had attempted to implement this before but gave up as I did not like the movement at an angle. It is not smooth and kind of wiggles a pixel or two side to side as it moves.
    – evandarcy
    Nov 12 at 12:54










  • @evandarcy yes, changing left/bottom will not be as smooth as translate but it remains another way that we can probably improve ;)
    – Temani Afif
    Nov 12 at 13:05










  • of course! I appreciate your answer, it's very helpful :-)
    – evandarcy
    Nov 12 at 13:09














0












0








0






what you want to achieve is to move your element independently from its previous state and this cannot be achieved using only transform since transform always consider the initial state in order to move your element.



An idea is to consider using bottom/left to move the element and use only transform to rotate the element. The angle of rotation will define how you will adjust the bottom and left properties:






var r = document.getElementById("image2");

document.addEventListener("keydown", checkKey);

var rotate = 0;
var left=0;
var bottom= 0;

function checkKey(e) {
e = e || window.event;
if (e.keyCode == '38') {
// up arrow
r.style.left = left + Math.sin(rotate*Math.PI/180) + 'px';
r.style.bottom = bottom + Math.cos(rotate*Math.PI/180) + 'px';
} else if (e.keyCode == '40') {
// down arrow
r.style.left = left - Math.sin(rotate*Math.PI/180) + 'px';
r.style.bottom = bottom - Math.cos(rotate*Math.PI/180) + 'px';
} else if (e.keyCode == '37') {
// left arrow
rotate = rotate - .8;
r.style.transform = 'rotate(' + rotate + 'deg)';
} else if (e.keyCode == '39') {
// right arrow
rotate = rotate + .8;
r.style.transform = 'rotate(' + rotate + 'deg)';
}
left = parseFloat(r.style.left);
bottom = parseFloat(r.style.bottom);
}

#image2 {
width: 40px;
position: absolute;
}

<img id="image2" src="https://banner2.kisspng.com/20180415/pge/kisspng-arrow-desktop-wallpaper-symbol-clip-art-up-arrow-5ad37ddc82f384.4572004515238097565364.jpg" style="left:0;bottom:0;">








share|improve this answer














what you want to achieve is to move your element independently from its previous state and this cannot be achieved using only transform since transform always consider the initial state in order to move your element.



An idea is to consider using bottom/left to move the element and use only transform to rotate the element. The angle of rotation will define how you will adjust the bottom and left properties:






var r = document.getElementById("image2");

document.addEventListener("keydown", checkKey);

var rotate = 0;
var left=0;
var bottom= 0;

function checkKey(e) {
e = e || window.event;
if (e.keyCode == '38') {
// up arrow
r.style.left = left + Math.sin(rotate*Math.PI/180) + 'px';
r.style.bottom = bottom + Math.cos(rotate*Math.PI/180) + 'px';
} else if (e.keyCode == '40') {
// down arrow
r.style.left = left - Math.sin(rotate*Math.PI/180) + 'px';
r.style.bottom = bottom - Math.cos(rotate*Math.PI/180) + 'px';
} else if (e.keyCode == '37') {
// left arrow
rotate = rotate - .8;
r.style.transform = 'rotate(' + rotate + 'deg)';
} else if (e.keyCode == '39') {
// right arrow
rotate = rotate + .8;
r.style.transform = 'rotate(' + rotate + 'deg)';
}
left = parseFloat(r.style.left);
bottom = parseFloat(r.style.bottom);
}

#image2 {
width: 40px;
position: absolute;
}

<img id="image2" src="https://banner2.kisspng.com/20180415/pge/kisspng-arrow-desktop-wallpaper-symbol-clip-art-up-arrow-5ad37ddc82f384.4572004515238097565364.jpg" style="left:0;bottom:0;">








var r = document.getElementById("image2");

document.addEventListener("keydown", checkKey);

var rotate = 0;
var left=0;
var bottom= 0;

function checkKey(e) {
e = e || window.event;
if (e.keyCode == '38') {
// up arrow
r.style.left = left + Math.sin(rotate*Math.PI/180) + 'px';
r.style.bottom = bottom + Math.cos(rotate*Math.PI/180) + 'px';
} else if (e.keyCode == '40') {
// down arrow
r.style.left = left - Math.sin(rotate*Math.PI/180) + 'px';
r.style.bottom = bottom - Math.cos(rotate*Math.PI/180) + 'px';
} else if (e.keyCode == '37') {
// left arrow
rotate = rotate - .8;
r.style.transform = 'rotate(' + rotate + 'deg)';
} else if (e.keyCode == '39') {
// right arrow
rotate = rotate + .8;
r.style.transform = 'rotate(' + rotate + 'deg)';
}
left = parseFloat(r.style.left);
bottom = parseFloat(r.style.bottom);
}

#image2 {
width: 40px;
position: absolute;
}

<img id="image2" src="https://banner2.kisspng.com/20180415/pge/kisspng-arrow-desktop-wallpaper-symbol-clip-art-up-arrow-5ad37ddc82f384.4572004515238097565364.jpg" style="left:0;bottom:0;">





var r = document.getElementById("image2");

document.addEventListener("keydown", checkKey);

var rotate = 0;
var left=0;
var bottom= 0;

function checkKey(e) {
e = e || window.event;
if (e.keyCode == '38') {
// up arrow
r.style.left = left + Math.sin(rotate*Math.PI/180) + 'px';
r.style.bottom = bottom + Math.cos(rotate*Math.PI/180) + 'px';
} else if (e.keyCode == '40') {
// down arrow
r.style.left = left - Math.sin(rotate*Math.PI/180) + 'px';
r.style.bottom = bottom - Math.cos(rotate*Math.PI/180) + 'px';
} else if (e.keyCode == '37') {
// left arrow
rotate = rotate - .8;
r.style.transform = 'rotate(' + rotate + 'deg)';
} else if (e.keyCode == '39') {
// right arrow
rotate = rotate + .8;
r.style.transform = 'rotate(' + rotate + 'deg)';
}
left = parseFloat(r.style.left);
bottom = parseFloat(r.style.bottom);
}

#image2 {
width: 40px;
position: absolute;
}

<img id="image2" src="https://banner2.kisspng.com/20180415/pge/kisspng-arrow-desktop-wallpaper-symbol-clip-art-up-arrow-5ad37ddc82f384.4572004515238097565364.jpg" style="left:0;bottom:0;">






share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 12 at 12:43

























answered Nov 12 at 12:37









Temani Afif

65k93775




65k93775












  • Another nice solution, thank you Temani. I had attempted to implement this before but gave up as I did not like the movement at an angle. It is not smooth and kind of wiggles a pixel or two side to side as it moves.
    – evandarcy
    Nov 12 at 12:54










  • @evandarcy yes, changing left/bottom will not be as smooth as translate but it remains another way that we can probably improve ;)
    – Temani Afif
    Nov 12 at 13:05










  • of course! I appreciate your answer, it's very helpful :-)
    – evandarcy
    Nov 12 at 13:09


















  • Another nice solution, thank you Temani. I had attempted to implement this before but gave up as I did not like the movement at an angle. It is not smooth and kind of wiggles a pixel or two side to side as it moves.
    – evandarcy
    Nov 12 at 12:54










  • @evandarcy yes, changing left/bottom will not be as smooth as translate but it remains another way that we can probably improve ;)
    – Temani Afif
    Nov 12 at 13:05










  • of course! I appreciate your answer, it's very helpful :-)
    – evandarcy
    Nov 12 at 13:09
















Another nice solution, thank you Temani. I had attempted to implement this before but gave up as I did not like the movement at an angle. It is not smooth and kind of wiggles a pixel or two side to side as it moves.
– evandarcy
Nov 12 at 12:54




Another nice solution, thank you Temani. I had attempted to implement this before but gave up as I did not like the movement at an angle. It is not smooth and kind of wiggles a pixel or two side to side as it moves.
– evandarcy
Nov 12 at 12:54












@evandarcy yes, changing left/bottom will not be as smooth as translate but it remains another way that we can probably improve ;)
– Temani Afif
Nov 12 at 13:05




@evandarcy yes, changing left/bottom will not be as smooth as translate but it remains another way that we can probably improve ;)
– Temani Afif
Nov 12 at 13:05












of course! I appreciate your answer, it's very helpful :-)
– evandarcy
Nov 12 at 13:09




of course! I appreciate your answer, it's very helpful :-)
– evandarcy
Nov 12 at 13:09


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53261116%2fusing-css-transforms-to-translate-rotate-sprite-using-arrow-key-inputs-problem%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Florida Star v. B. J. F.

Danny Elfman

Retrieve a Users Dashboard in Tumblr with R and TumblR. Oauth Issues