首页 > 解决方案 > 使用 sin 和 cos Canvas Js 增加围绕中心的旋转角度

问题描述

大家好,我正在画布上用 sin 和 cos 做一些小练习。我现在可以使用它工作的动画函数中的角度增量围绕另一个点旋转一个点,如下面的代码所示。我的目的是将角度增量放在类取景器的更新功能中

const canvas= document.getElementById('canvas');
const c= canvas.getContext("2d");

canvas.width= window.innerWidth;
canvas.height= window.innerHeight;

let angle=0;
const r=200;



/* -------------------------------------------------------------------------- */
/*                                 View Finder                                */
/* -------------------------------------------------------------------------- */

class ViewFinder {
  constructor(x,y,radius,color){
      this.x=x;
      this.y=y;
      this.radius=radius;
      this.color=color
      this.r= r;
      this.angle=angle;
      this.dx = this.r * Math.cos(this.angle);
      this.dy= this.r * Math.sin (this.angle);

  }
  draw(){
        //point 1
        c.beginPath()
        c.arc(this.x,this.y,this.radius, 0, Math.PI *2,false )
        c.fillStyle=this.color;
        c.fill();
        //point 2
        c.beginPath();
        c.arc(this.x + this.dx, this.y + this.dy,this.radius,0, Math.PI * 2, false );
        c.fillStyle=this.color;
        c.fill();
  }
  update(){
      this.draw();
  }

}


/* -------------------------------------------------------------------------- */
/*                                   Animate                                  */
/* -------------------------------------------------------------------------- */

let animationId;



function animate(){
   animationId= requestAnimationFrame(animate);
   c.fillStyle='rgba(0, 0, 0, 0.5)';
   c.fillRect(0,0,canvas.width,canvas.height);
   // calculate velocity
   viewFinder = new ViewFinder (canvas.width/2, canvas.height/2, 40, 'white');
   angle +=0.1/2;
   viewFinder.update();
}

animate();
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body style="height: 100vh;">
    <canvas id="canvas"></canvas>
    <script src="main.js"></script>
</body>
</html>

因此,如果我也这样做,但我将角度增量放在更新功能中没有任何移动.. 试着理解为什么非常感谢你的回答

const canvas= document.getElementById('canvas');
const c= canvas.getContext("2d");

canvas.width= window.innerWidth;
canvas.height= window.innerHeight;

let angle=0;
const r=200;



/* -------------------------------------------------------------------------- */
/*                                 View Finder                                */
/* -------------------------------------------------------------------------- */

class ViewFinder {
  constructor(x,y,radius,color){
      this.x=x;
      this.y=y;
      this.radius=radius;
      this.color=color
      this.r= r;
      this.angle=angle;
      this.dx = this.r * Math.cos(this.angle);
      this.dy= this.r * Math.sin (this.angle);

  }
  draw(){
        //point 1
        c.beginPath()
        c.arc(this.x,this.y,this.radius, 0, Math.PI *2,false )
        c.fillStyle=this.color;
        c.fill();
        //point 2
        c.beginPath();
        c.arc(this.x + this.dx, this.y + this.dy,this.radius,0, Math.PI * 2, false );
        c.fillStyle=this.color;
        c.fill();
  }
  update(){
      this.draw();
      this.angle +=0.1;
  }

}


/* -------------------------------------------------------------------------- */
/*                                   Animate                                  */
/* -------------------------------------------------------------------------- */

let animationId;



function animate(){
   animationId= requestAnimationFrame(animate);
   c.fillStyle='rgba(0, 0, 0, 0.5)';
   c.fillRect(0,0,canvas.width,canvas.height);
   // calculate velocity
   viewFinder = new ViewFinder (canvas.width/2, canvas.height/2, 40, 'white');
   viewFinder.update();
}




animate();
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body style="height: 100vh;">
    <canvas id="canvas"></canvas>
    <script src="main.js"></script>
</body>
</html>

标签: javascriptcanvastrigonometry

解决方案


问题是:在第一个示例中,您正在更新全局变量angle,但在第二个示例中,您正在更新this.angle,在第一种情况下,您正在viewFinder每帧重新创建对象,并且由于 的​​值angle已更改,因此dx&dy为新对象重新计算。

但是,在第二种情况下,您也在重新创建 object viewFinder,它使用全局变量angle来设置新的角度,dx但是dy 您不再更新角度,这使得元素看起来是静态的,要解决这个问题:

  1. 不要为每一帧重新创建对象,创建一次并为每一帧更新它。

  2. 更新的值dxdy更新后的值this.angle

您的代码将类似于:

const canvas = document.getElementById('canvas')
const c = canvas.getContext('2d')

canvas.width = window.innerWidth
canvas.height = window.innerHeight

let angle = 0
const r = 200

/* -------------------------------------------------------------------------- */
/*                                 View Finder                                */
/* -------------------------------------------------------------------------- */

class ViewFinder {
  constructor(x, y, radius, color) {
    this.x = x
    this.y = y
    this.radius = radius
    this.color = color
    this.r = r
    this.angle = angle
    this.dx = this.r * Math.cos(this.angle)
    this.dy = this.r * Math.sin(this.angle)
  }
  draw() {
    //point 1
    c.beginPath()
    c.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false)
    c.fillStyle = this.color
    c.fill()
    //point 2
    c.beginPath()
    c.arc(
      this.x + this.dx,
      this.y + this.dy,
      this.radius,
      0,
      Math.PI * 2,
      false
    )
    c.fillStyle = this.color
    c.fill()
  }
  update() {
    this.draw()
    this.angle += 0.1
    this.dx = this.r * Math.cos(this.angle)
    this.dy = this.r * Math.sin(this.angle)
  }
}

/* -------------------------------------------------------------------------- */
/*                                   Animate                                  */
/* -------------------------------------------------------------------------- */

let animationId

let viewFinder = new ViewFinder(canvas.width / 2, canvas.height / 2, 40, 'white')
function animate() {
  animationId = requestAnimationFrame(animate)
  c.fillStyle = 'rgba(0, 0, 0, 0.5)'
  c.fillRect(0, 0, canvas.width, canvas.height)
  // calculate velocity

  viewFinder.update()
}

animate()

推荐阅读