forked from Orangetronic/brighton-generator-website
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathhorsify.js
134 lines (104 loc) Β· 2.99 KB
/
horsify.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
const styles = document.createElement("style")
styles.innerText = `
.falling-horse {
position: absolute;
top: 0;
left: 0;
pointer-events: none;
}
`
document.head.appendChild(styles)
// we can keep horsen in this set
const horsen = new Set()
const G = 0.05
const terminalV = 10
const breeds = ["π¦", "π΄", "π", "π¦", "π", "π "]
class Horse {
constructor (x, y) {
const size = Math.random() * 5
const rotation = Math.random() * 2
const element = document.createElement("div")
element.classList = "falling-horse"
element.innerText = breeds[Math.floor(Math.random() * breeds.length)]
this.size = size
this.rotation = rotation
this.x = x
this.y = y
this.domNode = element
this.v = {
x: (Math.random() * 10) - 5,
y: (Math.random() * 5) - 2.5,
rot: (Math.random() * 0.2) - 0.1
}
this.deltaV = {
x (prevX) { return prevX * 0.9 },
y (prevY) {
// if we've hit terminal velocity, stop accelerating
if (prevY >= terminalV) return terminalV
if (prevY <= -terminalV) return -terminalV
// grow the velocity in the Y direction by the force of gravity
return prevY + G // make gravity bigger for bigger horses. this will make a parallax effect
}
}
this.setPosition()
document.body.appendChild(element)
}
setPosition () {
// I'm using try catch, because sometimes this seems to fire after the
// domNode has already been removed
try {
this.domNode.style=`transform: translate(${this.x}px, ${this.y}px) rotate(${this.rotation}rad); font-size: ${this.size}em;`
} catch (_e) {
}
}
move () {
if (!horsen.has(this)) return // we've already been removed
// if this horse has fallen off the bottom of the screen, remove it from the DOM
// and delete it from the set of all horses
// otherwise, set it's new position
if (this.y > document.body.getBoundingClientRect().height - 150) {
this.v.y = -0.8 * this.v.y
this.v.rot = (Math.random() * 0.2) - 0.1
// horses that have slowed down sufficiently are retired.
if (this.v.y > -0.3) {
horsen.delete(this)
// I'm using try catch, because sometimes this seems to fire after the
// domNode has already been removed
try {
document.body.removeChild(this.domNode)
} catch (_e) {
}
}
}
// move the horse according to current velocity
this.x = this.x + this.v.x
this.y = this.y + this.v.y
this.rotation = this.rotation + this.v.rot
// accelerate the horse
this.v.x = this.deltaV.x(this.v.x)
this.v.y = this.deltaV.y(this.v.y)
this.setPosition()
}
}
let animationRunning = false
const handler = function (e) {
const horse = new Horse(e.pageX - 5, e.pageY - 5)
horsen.add(horse)
if (!animationRunning) runAnimation()
}
document.body.addEventListener("mousedown", handler)
function frame () {
for (const horse of horsen) {
horse.move()
}
if (horsen.size == 0) {
animationRunning = false
}
if (animationRunning) {
window.requestAnimationFrame(frame)
}
}
function runAnimation () {
animationRunning = true
frame()
}