Reputation: 5384
I was trying to move an image to the left continuously (with a time delay) but I am unable to get the smoothness effect. I am getting jerky effect. I am using requestAnimationFrame inside the setTimeout as below.
<!DOCTYPE html>
<html>
<head>
<title>Moving Screen Saver</title>
<style>
html, body {
background-image: url("https://s14.postimg.cc/jei3ov2nl/moon_bg.png");
background-repeat: no-repeat;
background-size: cover;
position: relative;
height: 100%;
width: 100%;
}
#poster {
background-image: url("https://s14.postimg.cc/582ctpzj5/gladiator.png");
position: absolute;
background-position:right 20px bottom 20px;
background-repeat: no-repeat;
width: 100%;
height: 100%;
z-index: 99999;
background-color: transparent;
}
</style>
</head>
<body>
<div id="poster"></div>
<script>
var poster = document.getElementById('poster');
var animate;
function moveLeft()
{
poster.style.left = poster.style.left || 0;
poster.style.left = parseInt(poster.style.left) - 10 + 'px';
setTimeout(function() {
requestAnimationFrame(moveLeft);
}, 50);
//requestAnimationFrame(moveLeft);
}
moveLeft();
</script>
</body>
</html>
If I change the interval to 10 in setTimeout() (or if I just use requestAnimationFrame instead of timeout), the movement is smooth but it is too fast and user can't see properly. Can anyone please let me know is there anyway to achieve the smooth effect with slow moving?
Below is the jsfiddle link
https://jsfiddle.net/un45c6s3/7/
Upvotes: 0
Views: 1027
Reputation: 1
As pointed out in a comment, this simple effect is better done using CSS transition, however, for the sake of learning:
Using setTimeout
will always make things jerky, as setTimeout
timing is not exactly consistent
The code below uses only requestAnmationFrame
, and the speed is adjustable (specified in pixels per second)
Note: parseInt changed to parseFloat - because you can have fractional positioning of elements
var poster = document.getElementById('poster');
var animate;
var previousMs = 0;
var speed = 100; // pixels per second
function moveLeft(ms) {
if (previousMs !== 0) {
var delta = ms - previousMs;
// lets say we want to move 100px per second
// we have d milliseconds, so speed*delta/1000;
poster.style.left = poster.style.left || 0;
poster.style.left = parseFloat(poster.style.left) - (speed * delta / 1000) + 'px';
}
previousMs = ms;
requestAnimationFrame(moveLeft);
}
requestAnimationFrame(moveLeft);
html,
body {
background-image: url("https://s14.postimg.cc/jei3ov2nl/moon_bg.png");
background-repeat: no-repeat;
background-size: cover;
position: relative;
height: 100%;
width: 100%;
}
#poster {
background-image: url("https://s14.postimg.cc/582ctpzj5/gladiator.png");
position: absolute;
background-position: right 20px bottom 20px;
background-repeat: no-repeat;
width: 100%;
height: 100%;
z-index: 99999;
background-color: transparent;
}
<div id="poster"></div>
Now, you mention in the comment you want to do something when the animation is done
You can do so using CSS transitions and events
window.addEventListener('load', () => {
var poster = document.getElementById('poster');
poster.classList.add('move');
var done = function() {
poster.classList.toggle('move');
};
poster.addEventListener('transitionend', done);
});
html,
body {
background-image: url("https://s14.postimg.cc/jei3ov2nl/moon_bg.png");
background-repeat: no-repeat;
background-size: cover;
position: relative;
height: 100%;
width: 100%;
padding:0;
margin:0;
}
#poster {
background-image: url("https://s14.postimg.cc/582ctpzj5/gladiator.png");
position: absolute;
background-position: right 20px bottom 20px;
background-repeat: no-repeat;
width: 100%;
height: 100%;
z-index: 99999;
background-color: transparent;
left:0;
transition:left 5s linear;
}
#poster.move {
left:-100%;
}
<div id="poster"></div>
Upvotes: 2
Reputation: 159
Why do it in javascript ? can you use CSS ?
the animations in CSS are amazing and are quite supported by the browsers, try it this way
Click on image for animate.
html, body {
background-image: url("https://s14.postimg.cc/jei3ov2nl/moon_bg.png");
background-repeat: no-repeat;
background-size: cover;
position: relative;
height: 100%;
width: 100%;
}
#poster {
background-image: url("https://s14.postimg.cc/582ctpzj5/gladiator.png");
position: absolute;
background-position:right 20px bottom 20px;
background-repeat: no-repeat;
width: 100%;
height: 100%;
z-index: 99999;
background-color: transparent;
/* transition animation slow */
transition: right 1000ms ease;
/* set init of animation */
right:0%;
}
.posterToLeft{
right: 100% !important;
/* for example end of animation-transition */
}
<div id="poster" onclick='this.className +=" posterToLeft";'></div>
Upvotes: 1