Easing Animations in Canvas

Easing Animations in Canvas

css-tricks.com css-tricks.com2 years ago in #Dev Love24

The element in HTML and Canvas API in JavaScript combine to form one of the main raster graphics and animation possibilities on the web. A common canvas use-case is programmatically generating images for websites, particularly games. That’s exactly what I’ve done in a website I built for playing Solitaire. The cards, including all their movement, is all done in canvas. In this article, let’s look specifically at animation in canvas and techniques to make them look smoother. We’ll look specifically at easing transitions — like “ease-in” and “ease-out” — that do not come for free in canvas like they do in CSS. Let’s start with a static canvas. I’ve drawn to the canvas a single playing card that I grabbed out of the DOM: Let’s start with a basic animation: moving that playing card on the canvas. Even for fairly basic things like requires working from scratch in canvas, so we’ll have to start building out functions we can use. First, we’ll create functions to help calculate X and Y coordinates: function getX(params) {   let distance = params.xTo – params.xFrom;   let steps = params.frames;   let progress = params.frame;   return distance / steps * progress; } 
 function getY(params) {   let distance = params.yTo – params.yFrom;   let steps = params.frames;   let progress = params.frame;   return distance / steps * progress; } This will help us update the position values as the image gets animated. Then we’ll keep re-rendering the canvas until the animation is complete. We do this by adding the following code to our addImage() method. if (params.frame < params.frames) {   params.frame = params.frame 1;   window.requestAnimationFrame(drawCanvas);   window.requestAnimationFrame(addImage.bind(null, params)) } Now we have animation! We’re steadily incrementing by 1 unit each time, which we call a linear animation. You can see how the shape moves from point A to point B in a linear fashion, maintaining the same consistent speed between points. It’s functional, but lacks realism. The start and stop is jarring. What we want is for the object to accelerate (ease-in) and decelerate (ease-out), so it mimics what a real-world object would do when things like friction and gravity come into play. A JavaScript easing function We’ll achieve this with a “cubic” ease-in and ease-out transition. We’ve modified one of the equations found in Robert Penner’s Flash easing functions, to be suitable for what we want to do here. function getEase(currentProgress, start, distance, steps) {   currentProgress /= steps/2;   if (currentProgress < 1) {     return (distance/2)*(Math.pow(currentProgress, 3)) start;   }   currentProgress -= 2;   return distance/2*(Math.pow(currentProgress, 3) 2) start; } Inserting this into our code, which is a cubic ease, we get a much smoother result. Notice how the card speeds towards the center of the space, then slows down as it reaches the end. Advanced easing with JavaScript We can get a slower acceleration with either a quadratic or sinusoidal ease. function getQuadraticEase(currentProgress, start, distance, steps) {   currentProgress /= steps/2;   if (currentProgress  » Read More

Like to keep reading?

This article first appeared on css-tricks.com. If you'd like to keep reading, follow the white rabbit.

View Full Article

Leave a Reply