javascriptanimationsvgcanvaskeyframe

How to add timing and delay to requestAnimationFrame?


I have a design that includes a SVG rectangle and a canvas that draws an arc. I am making an animation where the rectangle will grow first and after that the arc will.

I am almost there but both my elements animate at the same time.

I am using css keyframes for the animation of the rectangle and used requestAnimationFrame to animate the arc while draw.

  .ss{

animation: myframes 3s ease-in-out 

}

@keyframes myframes {

from {

height: 0px;
}

to{
  height: 315px;
}

}
<svg  height="350" width="800">
    <rect  class="ss" x="415" y="51" filter="#008080" stroke-miterlimit="10" width="110" height="413">
    </rect>
</svg>
<canvas style="display: block;" id="bar" width="600" height="500">
</canvas>
var canvas = document.getElementById('bar'),
    width = canvas.width,
    height = canvas.height;


var ctx = canvas.getContext('2d');
ctx.lineWidth = 110;
ctx.strokeStyle = '#000';
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.shadowBlur = 10;


var x = width / 2,
    y = height / 98,
    radius = 170,
    circum = Math.PI * 2,
    start = Math.PI / -44, // Start position (top)
    finish = 37, // Finish (in %)
    curr = 0; // Current position (in %)

var raf =
    window.requestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.msRequestAnimationFrame ||
    function(f){return setTimeout(f, 9000/60)};

window.requestAnimationFrame = raf;


function animate(draw_to) {
  ctx.clearRect(0, 0, width, height);
  ctx.beginPath();
  ctx.arc(x, y, radius, start, draw_to, false);
  ctx.stroke();
  curr++;
  if (curr < finish + 1) {
    requestAnimationFrame(function () {
      animate(circum * curr /100 + start);
    });
  }
}

animate();

I want to keep the rectangle animate they way it is now but the arc will start to animate when rectangle is done(add delay) and I want the animation of the arc slower(add timing)

Adding a fiddle below: https://jsfiddle.net/r9t2v6g5/


Solution

  • For such requirement it would have been best if there was a callback for the stoke method so that we know when the drawing is complete. However we don't have any such implementation. One easy solution for your case would be to start the animation of arc after around 3 seconds as you have explicitly mentioned 3 seconds time for rendering the vertical bar. See the updated fiddle: https://jsfiddle.net/cLrxhdnf/ You can adjust the arc animation speed as per your liking, I just added a placeholder.

    function animateArc(angle) {
        console.log("animateArc : "+ angle);
      ctx.clearRect(width, height, width, height);
    
      ctx.beginPath();
    
      ctx.arc(x, y, radius, start, angle, false);
    
      ctx.stroke();
    
      curr++;
    
      if (angle < Math.PI) {
        requestAnimationFrame(function () {
          animateArc(angle + 0.05);
        });
      }
    }
    
    animate();
    setTimeout(function() { animateArc(0.05)}, 2500);