-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
98 lines (82 loc) · 2.94 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
import { Oscillator, TWO_PI } from "./src/wave.js"
import { bezier } from "./src/curve.js"
class Blob {
constructor(radius, center, points, options) {
this.radius = radius
this.center = center
this.options = options
this.points = points
this.oscillators = []
this.initialize()
}
tick() {
const translatedPoints = []
for (let i = 0; i < this.points; i++) {
this.oscillators[i].tick()
translatedPoints.push(this.translatePoint(i))
}
let pathString = `M ${translatedPoints[0][0]}, ${translatedPoints[0][1]} `
pathString += bezier({
prev2: translatedPoints[translatedPoints.length - 1],
prev1: translatedPoints[0],
current: translatedPoints[1],
next: translatedPoints[2]
}, 0.2)
for (let i = 2; i < this.points - 1; i++) {
pathString += bezier({
prev2: translatedPoints[i - 2],
prev1: translatedPoints[i - 1],
current: translatedPoints[i],
next: translatedPoints[i + 1]
}, 0.2)
}
pathString += bezier({
prev2: translatedPoints[translatedPoints.length - 3],
prev1: translatedPoints[translatedPoints.length - 2],
current: translatedPoints[translatedPoints.length - 1],
next: translatedPoints[0]
}, 0.2)
pathString += bezier({
prev2: translatedPoints[translatedPoints.length - 2],
prev1: translatedPoints[translatedPoints.length - 1],
current: translatedPoints[0],
next: translatedPoints[1]
}, 0.2)
pathString += "Z"
return pathString
}
initialize() {
const increment = TWO_PI / this.points
let angle = 0
for (let i = 0; i < this.points; i++) {
this.oscillators.push(new Oscillator(
[Math.cos(angle) * this.radius, Math.sin(angle) * this.radius], angle,
this.options.minSpeed, this.options.maxSpeed, this.options.minHeight, this.options.maxHeight
))
angle += increment
}
}
translatePoint(index) {
const oscillator = this.oscillators[index]
const position = oscillator.position
const offsetAngle = oscillator.offset
const height = oscillator.height
const circleAngle = oscillator.angle
return [
this.center[0] + position[0] + (Math.sin(offsetAngle) * height) * Math.cos(circleAngle),
this.center[1] + position[1] + (Math.sin(offsetAngle) * height) * Math.sin(circleAngle)
]
}
}
const path = document.getElementById("path")
const blob = new Blob(30, [50, 50], 15, {
minHeight: 4,
maxHeight: 4,
minSpeed: 0.02,
maxSpeed: 0.03
})
function animate() {
path.setAttribute("d", blob.tick())
window.requestAnimationFrame(animate)
}
animate()