Using CSS transforms to translate/rotate sprite using arrow key inputs. Problem updating position
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>
javascript html css css3 css-transforms
|
show 1 more comment
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>
javascript html css css3 css-transforms
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 betweenpx
andvmin
units for yourtranslateY
value - you sure that’s what you want …?
– misorude
Nov 12 at 11:49
|
show 1 more comment
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>
javascript html css css3 css-transforms
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
javascript html css css3 css-transforms
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 betweenpx
andvmin
units for yourtranslateY
value - you sure that’s what you want …?
– misorude
Nov 12 at 11:49
|
show 1 more comment
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 betweenpx
andvmin
units for yourtranslateY
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
|
show 1 more comment
2 Answers
2
active
oldest
votes
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/
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
|
show 2 more comments
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;">
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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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/
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
|
show 2 more comments
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/
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
|
show 2 more comments
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/
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/
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
|
show 2 more comments
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
|
show 2 more comments
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;">
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
add a comment |
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;">
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
add a comment |
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;">
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;">
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
add a comment |
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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
andvmin
units for yourtranslateY
value - you sure that’s what you want …?– misorude
Nov 12 at 11:49