13

I am trying to animate a div moving 200px horizontally in JavaScript.

The code below makes it jump the pixels, but is there a way to make it look animated without using jQuery?

function () {
    var div = document.getElementById('challengeOneImageJavascript');
    div.style.left = "200px";
}
Chris McFarland
  • 6,059
  • 5
  • 43
  • 63
CUDA
  • 165
  • 1
  • 2
  • 9

7 Answers7

46

Here is a basic animation setup:

function animate(elem,style,unit,from,to,time) {
    if( !elem) return;
    var start = new Date().getTime(),
        timer = setInterval(function() {
            var step = Math.min(1,(new Date().getTime()-start)/time);
            elem.style[style] = (from+step*(to-from))+unit;
            if( step == 1) clearInterval(timer);
        },25);
    elem.style[style] = from+unit;
}

To use:

animate(
    document.getElementById('challengeOneImageJavascript'),
    "left","px",0,200,1000
);

This example will animate the given element to slide linearly from 0px to 200px over a time of 1 second (1000 ms).

Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
  • very thorough implementation with lots of features... like it – Billy Moon Jun 26 '12 at 18:12
  • If this answer solved your problem, please consider marking it as Accepted by clicking the big check mark right underneath the vote score ;) – Niet the Dark Absol Jun 26 '12 at 18:29
  • This works great, thank you! How would you implement easing into it? – p0pps May 29 '13 at 04:34
  • 2
    Well, this all was written before I discovered CSS3 transitions. At this point in time I highly recommend you use transitions over manually animating, as this gives you an [unlimited range of functions](http://cubic-bezier.com/) to animate with. With this, you'd just need JavaScript to do `document.getElementById('...').style.left = '200px';` and it will animate automatically. – Niet the Dark Absol May 29 '13 at 05:49
  • That said, if you would like to maintain support in IE9 and below, you should continue to use this function. You can run `step` through some mathematical function with the following requirements: The function should be continuous in the range 0-1, and pass through (0,0) and (1,1). Start with just `Math.pow(step,2)` and go from there. – Niet the Dark Absol May 29 '13 at 05:51
  • This is a great solution for a project that requires no CSS stylesheet. I'm curious, was there any reason you chose 25 ms as your delay time? – ayjay Mar 17 '15 at 23:22
  • @ayjay 25ms yields 50fps, which is usually pretty good. You're free to adjust this as desired, but ideally `requestAnimationFrame` should be used now instead of timers. – Niet the Dark Absol Mar 18 '15 at 09:14
  • Please add fiddle too in the answer. – Sushan Jan 01 '16 at 04:55
  • @NiettheDarkAbsol after removing last line `elem.style[style] = from+unit;` it still works.. is that line really needed? – neoDev Oct 10 '17 at 00:16
  • 1
    @neoDev That line serves as the first "frame" of animation, since the interval doesn't run at that point. If the element is already in the correct position for the first frame, it will have no visible effect. – Niet the Dark Absol Oct 10 '17 at 09:53
  • Is there an easier way to do this for transform: rotate(xdeg)? – k1st Jan 12 '22 at 11:30
10

You can easily do this through CSS3-Transition :

#challengeOneImageJavascript {
    -webkit-transition: left .2s;
       -moz-transition: left .2s;
         -o-transition: left .2s;
            transition: left .2s;
}

Though, it is not supported by IE9 and earlier browser versions.

Asif
  • 4,980
  • 8
  • 38
  • 53
Calvein
  • 2,111
  • 13
  • 28
2

I did a ton of research, and I finally learned how to do it really well.

I like to place my program in a window.onload function, that way it dosn't run the code until the page has finished loading.

To do the animation, make a function(I'll call it the draw function) and call it what ever you want except reserved words, then at the very end of the draw function call the requestAnimationFrame function and give it the name of the function to be called next frame.

Before the requestAnimationFrame function can be used it must be declared.

See the code below:

window.onload = function() {
  function draw() { //  declare animation function
    context.fillStyle = "white";
    context.fillRect(0, 0, 400, 400);
    requestAnimationFrame(draw); // make another frame
  }
  var requestAnimationFrame = // declare the 
    window.requestAnimationFrame || // requestAnimationFrame
    window.mozRequestAnimationFrame || // function
    window.webkitRequestAnimationFrame ||
    window.msRequestAnimationFrame;
  draw(); // call draw function
}

Note: Nothing after the line that calls the draw function will run, so you need to put everything you want to run before the line that calls the draw function.

Mo.
  • 26,306
  • 36
  • 159
  • 225
1

With JavaScript, you will have to use setInterval function or this is how it can be done in jQuery:

$('#challengeOneImageJavascript').animate({left: '=-5'});

Adust value (5) as per your needs as well as direction via =- or =+

With Vanilla JavaScript:

var interval;
var animate = function(id, direction, value, end, speed){
    var div = document.getElementById(id);
    interval = setInterval(function() {
       if (+(div.style) === end) {
          clearInterval(interval);
          return false;
       }
       div.style[direction] += value; // or -= as per your needs
    }, speed);
}

And you can use it like:

animate('challengeOneImageJavascript', 'left', 5, 500, 200);

To stop animation any time, you would do:

clearInterval(interval);

Note: This just a very quick way to do it to give you an idea.

Blaster
  • 9,414
  • 1
  • 29
  • 25
1

You would have to use a javascript timeout function, and change the css value a little at a time. The easiest way would be to increment by a set amount each time until a threshold is reached, which would give you a linear animation, which would look clunky and amateurish compared to jQuery's default swing animation which follows a bezier curve approximately like an s-curve.

Untested code should do the linear animation

var lefty = 0;
var animate = function(){
    lefty += 20;
    var div = document.getElementById('challengeOneImageJavascript');
    div.style.left = lefty +"px";
    if(lefty < 200)
      setTimeout(animate(),100);
}

animate()

n.b. there are lots of improvements to make to that block of code, but it should get you going...

Billy Moon
  • 57,113
  • 24
  • 136
  • 237
  • I got it to work with JQuery(which is a better option obviously) but Im trying to learn Javascript and the best way I know how is to try and get things working the hard way first – CUDA Jun 26 '12 at 18:18
0

Simplest way via css.

https://jsfiddle.net/pablodarde/5hc6x3r4/

translate3d uses hardware acceleration running on GPU. http://blog.teamtreehouse.com/increase-your-sites-performance-with-hardware-accelerated-css

HTML

<div class="movingBox"></div>

CSS

.movingBox {
  width: 100px;
  height: 40px;
  background: #999;
  transform: translate3d(0,0,0);
  transition: all 0.5s;
}

.moving {
  transform: translate3d(200px,0,0);
  background: #f00;
}

JavaScript

const box = document.getElementsByClassName('movingBox')[0];

setTimeout(() => {
    box.className += ' moving';
}, 1000);
Pablo Darde
  • 5,844
  • 10
  • 37
  • 55
0

CustomAnimation is a small libary for animating html elements which is written in pure js.You can use this libary.

Chinmoy Samanta
  • 1,376
  • 7
  • 17
  • Please explain more. – Farhad Aug 16 '17 at 06:55
  • You can check the samples which are provided in [CustomAnimation](https://github.com/SamantaChinmoy/CustomAnimation) repo. For example to animate one element, you have to call animate method in following pattern. animate(elementObj,styleObj,duration); – Chinmoy Samanta Aug 16 '17 at 10:30
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. – Farhad Aug 16 '17 at 10:39