How to rotate a object after the animation is completed using javascript?

Viewed 54

I am trying to rotate a flower after completing the petals. How do I achieve a slow continuous rotate effect only to the flower? I have search a lot and all search is resulting to clear the frame and redraw every time.

Below is the code that I have tried.

const canvas = document.getElementById("flower");
const ctx = canvas.getContext("2d");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var a = 0,n = 0,r = 0,c = 6;
var x = 0, y = 0;
var w = window.innerWidth, h = window.innerHeight;
var cx = w/2, cy = h/2, rot = 1;

//draw stem
ctx.beginPath();
ctx.moveTo(cx, h);
ctx.lineWidth = 10;
ctx.strokeStyle = "darkgreen";
ctx.quadraticCurveTo(cx+250, cy+100, cx, cy);
ctx.stroke();
ctx.lineWidth = 1;

//start rotating
const startRotate = () =>{
  setInterval(function () {
    ctx.save();
    ctx.translate(cx, cy);
    ctx.rotate(Math.PI / 180 * (rot += 5));
    ctx.restore(); 
  }, 100);
}

const startDrawing = () =>{
  if(n < 50){   //draw bud
    a =  (n * 137.5)*(180/Math.PI);
    r = c * Math.sqrt(n);
    x = r * Math.cos(a*(180/Math.PI)) + cx;
    y = r * Math.sin(a*(180/Math.PI)) + cy;
    ctx.beginPath();
    ctx.arc(x, y, 6, 0, 2 * Math.PI, true);
    ctx.strokeStyle = "lime";
    ctx.fillStyle = 'yellow';
    ctx.fill();
    ctx.stroke();
  }else{ //draw petals
    a =  (n * 137.5)*(180/Math.PI);
    r = c * Math.sqrt(n);
    x = r * Math.cos(a*(180/Math.PI)) + cx;
    y = r * Math.sin(a*(180/Math.PI)) + cy;
    ctx.beginPath();
    ctx.arc(x, y, 6, 0, 2 * Math.PI, true);
    ctx.strokeStyle = "black";
    ctx.fillStyle = 'hsl('+ a%256 +',100%,50%)';
    ctx.fill();
    ctx.stroke();
  }
  n++;
  if(n < 300) requestAnimationFrame(startDrawing);
  else startRotate();
}
startDrawing();
<canvas id="flower"></canvas>
<script src="main.js"></script>

Thank you

1 Answers

Here is what I would recommend you to do ...
Refactor your code so each circle is an object in a list, then we clear the canvas and re-draw everything on every frame.

See example below:

class circle {
  constructor(n) {
    let a = (n * 137.5) * (180 / Math.PI);
    let r = 6 * Math.sqrt(n);
    this.x = r * Math.cos(a * (180 / Math.PI));
    this.y = r * Math.sin(a * (180 / Math.PI));
    this.radius = 6
    this.id = n
    if (n < 50) {
      this.strokeStyle = "lime";
      this.fillStyle = 'yellow';
    } else {
      this.strokeStyle = "black";
      this.fillStyle = 'hsl(' + a % 256 + ',100%,50%)';
    }
  }

  draw(ctx) {
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI, true);
    ctx.strokeStyle = this.strokeStyle;
    ctx.fillStyle = this.fillStyle;
    ctx.fill();
    ctx.stroke();
  }
}

const canvas = document.getElementById("flower");
const ctx = canvas.getContext("2d");
var w = canvas.width = window.innerWidth;
var h = canvas.height = window.innerHeight;
ctx.translate(w / 2, h / 2);
var circles = []
var n = 0;

const startRotate = () => {  
  setInterval(function() {
    ctx.clearRect(-w, -h, w*2, h*2);
    ctx.rotate(0.1)
    circles.forEach(c => { 
      c.draw(ctx);
      if (c.id > 160) {
        c.radius += Math.random() - 0.51;
        c.radius = Math.min(Math.max(c.radius, 2), 10)
      }
    });
  }, 100);
}

const startDrawing = () => {
  circles.push(new circle(n))
  ctx.clearRect(-w, -h, w*2, h*2);
  circles.forEach(c => { c.draw(ctx) });
  n++;
  
  if (n < 300) 
    requestAnimationFrame(startDrawing);
  else 
    startRotate();
}

startDrawing();
<canvas id="flower"></canvas>

With that in place, now you can control each circle and create more complex animations, like making the flower expand or contract like it opened or closed, or move it up as if it was growing.

Related