javascript - 使用 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>
解决方案
问题是:在第一个示例中,您正在更新全局变量angle
,但在第二个示例中,您正在更新this.angle
,在第一种情况下,您正在viewFinder
每帧重新创建对象,并且由于 的值angle
已更改,因此dx
&dy
为新对象重新计算。
但是,在第二种情况下,您也在重新创建 object viewFinder
,它使用全局变量angle
来设置新的角度,dx
但是dy
您不再更新角度,这使得元素看起来是静态的,要解决这个问题:
不要为每一帧重新创建对象,创建一次并为每一帧更新它。
更新的值
dx
和dy
更新后的值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()
推荐阅读
- django - 在 Django REST Framework 中向 get_queryset 请求添加参数
- react-native - 子组件中的 React-Native-Maps 标记数组
- node.js - Mongoose 使用条件填充子文档并更新那些
- google-cloud-platform - 如何使用谷歌云平台 DLP API
- python - 输入语句的问题
- python - 从 (m,w,l) 到 (w,m,l) 维度的 Numpy 重塑
- javascript - 如果我使用 jQuery 或 javascript 在一个搜索栏或文本框中输入相同的名称或单词两次,则提醒我一条消息
- python - 基本 Python BeautifulSoup 网络抓取 Tripadvisor 评论和数据清理
- python - [Python]如何使用递归编辑嵌套数组配置值
- github - 有没有办法分阶段配置 Travis GitHub Pages Deployment?