canvas心形动画
# 方程式
x = 16(sinθ)^3
y = 13cosθ - 5cos2θ - 2cos3θ - cos4θ
1
2
2
θ闭环为2π
# 具体实现
按照上面笛卡尔坐标,转化绘制代码如下,我们把坐标x、y同时放大15倍,并将图像翻转
function getX1(t){ //获取心型线的X坐标
// 放大x轴15倍
return 15*(16*Math.pow(Math.sin(t),3))
}
function getY1(t){ //获取心型线的Y坐标
// 设置-15放大15倍的同事反转y轴
return -15*(13*Math.cos(t)-5*Math.cos(2*t)-2*Math.cos(3*t)-Math.cos(4*t))
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
绘制代码如下:
<canvas ref="drawing" width="500" height="500"></canvas>
1
function draw(){
var drawing = document.getElementById("drawing"); //获取canvas元素
drawing.width = '500'; //设置画布大小
drawing.height = '500';
if (drawing.getContext){ //获取绘图上下文
var content = drawing.getContext("2d"),
radian = 0, //设置初始弧度
radian_add = Math.PI/30; //设置弧度增量
// 清空画板
content.clearRect(0, 0, canvas.width, canvas.height)
content.beginPath(); //开始绘图
content.translate(250,250); //设置绘图原点
content.moveTo(getX(radian),getY(radian)); //移动绘图游标至原点
while(radian <= (Math.PI*2)){ //每增加一次弧度,绘制一条线
radian += radian_add;
X = getX1(radian);
Y = getY1(radian);
// X = getX2(radian);
// Y = getY2(radian);
content.lineTo(X,Y);
}
content.strokeStyle = "red"; //设置描边样式
content.stroke(); //对路径描边
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 动态绘制
上述代码为静态一次绘制,实际场景中需要逐点动态绘制,这里我们借助requestAnimationFrame方法实现逐帧绘制坐标点
同理使用setTimeout亦可实现动态效果
function draw {
if (!drawing.value) return
const canvas = drawing.value
canvas.width = 500
canvas.height = 500
const content = canvas.getContext('2d')
if (content) {
content.clearRect(0, 0, canvas.width, canvas.height)
let radian = 0
const radian_add = Math.PI / 180
content.beginPath()
content.translate(250 + getX1(radian), 250 + getY1(radian))
content.strokeStyle = 'red'
let timer: number
const lineFunc = () => {
if (radian <= Math.PI * 2) {
const X = getX1(radian)
const Y = getY1(radian)
content.lineTo(X, Y)
content.stroke()
radian += radian_add
timer = requestAnimationFrame(lineFunc)
} else {
cancelAnimationFrame(timer)
}
}
lineFunc()
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
效果如下:

上次更新: 2025/09/05, 8:09:00