# 绘制梅花树背景
测试渲染 Vue 组件
<template>
<canvas ref="el" />
</template>
<script>
export default {
name: 'PlumDemo',
data() {
return {
el: null,
framesCount: 0,
pendingTasks: [],
}
},
computed: {
ctx() {
return this.el.getContext('2d');
}
},
mounted() {
this.el = this.$refs.el;
this.init()
this.startFrame()
},
methods: {
init() {
this.ctx.strokeStyle = '#fff5'
this.step({
start: { x: 0, y: 150 },
length: 10,
theta: -Math.PI / 5,
})
},
frame() {
const tasks = []
this.pendingTasks = this.pendingTasks.filter(i => {
if (Math.random() > 0.4) {
tasks.push(i)
return false
}
return true
})
tasks.forEach(fn => fn())
},
startFrame() {
requestAnimationFrame(() => {
this.framesCount += 1
if (this.framesCount % 3 === 0) {
this.frame()
}
this.startFrame()
})
},
lineTo(p1, p2) {
this.ctx.beginPath()
this.ctx.moveTo(p1.x, p1.y)
this.ctx.lineTo(p2.x, p2.y)
this.ctx.stroke()
},
getEndPoint(b) {
return {
x: b.start.x + b.length * Math.cos(b.theta),
y: b.start.y + b.length * Math.sin(b.theta)
}
},
drawBranch(b) {
this.lineTo(b.start, this.getEndPoint(b))
},
step(b, depth = 0) {
const end = this.getEndPoint(b)
this.drawBranch(b)
if (depth < 4 || Math.random() < 0.5) {
this.pendingTasks.push(() => this.step({
start: end,
length: b.length + (Math.random() * 2 - 1),
theta: b.theta - 0.2 * Math.random(),
}, depth + 1))
}
if (depth < 4 || Math.random() < 0.5) {
this.pendingTasks.push(() => this.step({
start: end,
length: b.length + (Math.random() * 2 - 1),
theta: b.theta + 0.2 * Math.random(),
}, depth + 1))
}
}
}
}
</script>
<style scoped>
canvas {
width: 200px;
height: 200px;
background-color: #000;
border: 1px solid #000;
transform-origin: top left;
}
</style>
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
显示代码