-
Notifications
You must be signed in to change notification settings - Fork 0
/
animated_background.js
126 lines (120 loc) · 3.36 KB
/
animated_background.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
document.addEventListener("DOMContentLoaded", (event) => {
const animatedBackgroundWrapper = document.getElementById(
"animated-background-wrapper",
)
for (const item of bgConfig) {
createDiv(
animatedBackgroundWrapper,
item.imgPath,
item.speed,
item.possibleAngle,
item.possibleBlur,
)
}
})
const createDiv = (
animatedBackgroundWrapper,
imgPath,
speed,
possibleAngle,
possibleBlur,
) => {
const imgLoader = new Image() // create a new image object
imgLoader.onload = () => {
// assign onload handler
// Create the div and assign initial style
const div = document.createElement("div")
div.style.width = `${imgLoader.width}px`
div.style.height = `${imgLoader.height}px`
div.style.backgroundImage = `url(${imgPath})`
div.style.position = "fixed"
div.style.top = `${makeNewPosition(div)[1]}px`
div.style.left = `${makeNewPosition(div)[0]}px`
const initialRotation = makeNewRotation(possibleAngle)
div.style.transform = `rotate(${initialRotation}deg)`
const initialBlur = makeNewBlur(possibleBlur)
div.style.filter = `blur(${initialBlur}px)`
// Add the div to the end of the wrapper
animatedBackgroundWrapper.appendChild(div)
// Animate the div
animateDiv(
div,
speed,
initialRotation,
initialBlur,
possibleAngle,
possibleBlur,
)
}
imgLoader.src = imgPath // set the image source
}
const animateDiv = (
element,
speed,
initialRotation,
initialBlur,
possibleAngle,
possibleBlur,
) => {
const rect = element.getBoundingClientRect()
const oldPosition = {
top: rect.top + window.scrollY,
left: rect.left + window.scrollX,
}
const newPosition = makeNewPosition(element)
const duration = calcDuration(
[oldPosition.top, oldPosition.left],
newPosition,
speed,
)
let rotation = initialRotation
const finalRotation = makeNewRotation(possibleAngle)
const stepRotation = (finalRotation - rotation) / (duration / 13) // angle to change for each step = total rotations to achieve / number of animation steps
let blur = initialBlur
const finalBlur = makeNewBlur(possibleBlur)
const stepBlur = (finalBlur - blur) / (duration / 13)
Velocity(
element,
{ left: newPosition[0], top: newPosition[1] }, // destination point
{
duration: duration,
step: () => {
rotation += stepRotation
element.style.transform = `rotate(${rotation}deg)`
blur += stepBlur
element.style.filter = `blur(${blur}px)`
},
complete: () => {
animateDiv(element, speed, rotation, blur, possibleAngle, possibleBlur)
},
},
)
}
const makeNewPosition = (element) => {
// Get viewport dimensions (remove the dimension of the div)
const w = window.innerWidth - parseInt(element.style.width, 10)
const h = window.innerHeight - parseInt(element.style.height, 10)
const nw = Math.floor(Math.random() * w)
const nh = Math.floor(Math.random() * h)
return [nw, nh]
}
const makeNewRotation = (possibleAngle) => {
const angle =
Math.floor(Math.random() * (possibleAngle[1] - possibleAngle[0])) +
possibleAngle[0]
return angle
}
const makeNewBlur = (possibleBlur) => {
const blur =
Math.floor(Math.random() * (possibleBlur[1] - possibleBlur[0]) * 100) /
100 +
possibleBlur[0]
return blur
}
const calcDuration = (prev, next, speed) => {
const x = Math.abs(prev[0] - next[0])
const y = Math.abs(prev[1] - next[1])
const greatest = x > y ? x : y
const duration = Math.ceil((greatest / speed) * 100)
return duration
}