javascript - 如何使用javascript在动画完成后旋转对象?

标签 javascript html css canvas

我正在尝试在完成花瓣后旋转一朵花。 如何实现仅对花朵缓慢连续旋转的效果? 我进行了很多搜索,所有搜索的结果都是每次都清除框架并重新绘制。

下面是我尝试过的代码。

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>

谢谢

最佳答案

这是我建议您做的...
重构您的代码,使每个圆圈都是列表中的一个对象,然后我们清除 Canvas 并在每个帧上重新绘制所有内容。

参见下面的示例:

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>

完成后,现在您可以控制每个圆圈并创建更复杂的动画,例如使花朵像打开或关闭一样展开或收缩,或者向上移动,就像它正在生长一样。

关于javascript - 如何使用javascript在动画完成后旋转对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62919670/

相关文章:

javascript - 在 shiny 中,是否可以根据客户端 Web 浏览器输入更新输入选择?

javascript - Looper.js 与 codeigniter 中的控件

javascript - 为什么点击任意一个按钮所有 div 都会打开?

javascript - 如何在单击时水平滚动到特定的 div

css - 调节CSS中子元素的不透明度

javascript - jQuery UI 菜单,如何访问选项?

javascript - 无法覆盖 JavaScript 对象的属性

javascript - 如何将参数从 razor 发送到 JavaScript 函数

javascript - 隐藏文件扩展名

javascript - 在面板中添加关闭图标