-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
137 lines (115 loc) · 3.39 KB
/
index.js
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
const canvas = document.querySelector('canvas')
const ctx = canvas.getContext('2d')
const _w = canvas.width = 800
const _h = canvas.height = 500
const space = 8
const cols = ~~(_w / space)
const rows = ~~(_h / space)
const dots = []
let towPoint
let down = false
const mouse = {
x: 0,
y: 0
}
/*
* 偏移 .5px
* 为了更好的绘制线条:https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Applying_styles_and_colors
*/
ctx.translate(.5, .5)
function Dot(row, col) {
this.row = row
this.col = col
this.x = col * space
this.y = row * space
this.vx = 0
this.vy = 0
this.sx = this.x
this.sy = this.y
this.ax = 0
this.ay = 0
this.rate = .3 // a = f/m = kx/m = rate * x
this.damping = .3 // 阻尼系数
}
Dot.prototype = {
throb() {
if (towPoint == this) return
if (this.row == 0 || this.row == rows) return
if (this.col == 0 || this.col == cols) return
let up, down, left, right,
cx, cy
up = dots[(this.row - 1) * (cols + 1) + this.col]
down = dots[(this.row + 1) * (cols + 1) + this.col]
left = dots[this.row * (cols + 1) + this.col - 1]
right = dots[this.row * (cols + 1) + this.col + 1]
cx = (up.x + down.x + left.x + right.x) * .25
cy = (up.y + down.y + left.y + right.y) * .25
this.ax = (cx - this.x) * this.rate
this.ay = (cy - this.y) * this.rate
this.vx += this.ax
this.vy += this.ay
// 衰减
this.attenuate()
},
attenuate() {
const ax = Math.abs(this.ax) * this.damping
const ay = Math.abs(this.ay) * this.damping
// 速度衰减
this.vx > 0 ? this.vx -= ax : null
this.vx < 0 ? this.vx += ax : null
this.vy > 0 ? this.vy -= ay : null
this.vy < 0 ? this.vy += ay : null
}
}
for (let j = 0; j <= rows; j++)
for (let k = 0; k <= cols; k++)
dots.push(new Dot(j, k))
const draw = () => {
ctx.clearRect(0, 0, _w, _h)
ctx.strokeStyle = 'green'
ctx.lineWidth = .8
for (let i = 0; i < dots.length; i++) {
if (i % (cols + 1) == cols) continue
dots[i].throb()
ctx.beginPath()
ctx.moveTo(
dots[i].x += dots[i].vx,
dots[i].y += dots[i].vy
)
ctx.lineTo(
dots[i+1].x += dots[i+1].vx,
dots[i+1].y += dots[i+1].vy
)
ctx.stroke()
if (i + cols + 1 >= dots.length) continue
ctx.beginPath()
ctx.moveTo(
dots[i].x += dots[i].vx,
dots[i].y += dots[i].vy
)
ctx.lineTo(
dots[i+cols+1].x += dots[i+cols+1].vx,
dots[i+cols+1].y += dots[i+cols+1].vy
)
ctx.stroke()
}
requestAnimationFrame(draw)
}
document.addEventListener('mouseup', () => {
down = false
towPoint = null
})
canvas.addEventListener('mousedown', e => {
down = true
const i = ~~(e.offsetY / space) * (cols + 1) +
~~(e.offsetX / space)
towPoint = dots[i]
mouse.x = e.offsetX
mouse.y = e.offsetY
})
canvas.addEventListener('mousemove', e => {
if (!down) return
towPoint.x = towPoint.sx + e.offsetX - mouse.x
towPoint.y = towPoint.sy + e.offsetY - mouse.y
})
draw()