Skip to content

Commit 8529d2e

Browse files
committed
add animated background and click effects
1 parent 3f80932 commit 8529d2e

File tree

5 files changed

+270
-0
lines changed

5 files changed

+270
-0
lines changed

_includes/animated-background.html

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<div id="animation">
2+
<div class="animation-circle"></div>
3+
<div class="animation-circle"></div>
4+
<div class="animation-circle"></div>
5+
<div class="animation-circle"></div>
6+
<div class="animation-circle"></div>
7+
<div class="animation-circle"></div>
8+
<div class="animation-circle"></div>
9+
<div class="animation-circle"></div>
10+
<div class="animation-circle"></div>
11+
<div class="animation-circle"></div>
12+
<div class="animation-circle"></div>
13+
<div class="animation-circle"></div>
14+
<div class="animation-circle"></div>
15+
<div class="animation-circle"></div>
16+
<div class="animation-circle"></div>
17+
<div class="animation-circle"></div>
18+
<div class="animation-circle"></div>
19+
<div class="animation-circle"></div>
20+
<div class="animation-circle"></div>
21+
<div class="animation-circle"></div>
22+
<div class="animation-circle"></div>
23+
<div class="animation-circle"></div>
24+
<div class="animation-circle"></div>
25+
<div class="animation-circle"></div>
26+
<div class="animation-circle"></div>
27+
<div class="animation-circle"></div>
28+
<div class="animation-circle"></div>
29+
<div class="animation-circle"></div>
30+
<div class="animation-circle"></div>
31+
<div class="animation-circle"></div>
32+
<div class="animation-circle"></div>
33+
<div class="animation-circle"></div>
34+
<div class="animation-circle"></div>
35+
<div class="animation-circle"></div>
36+
<div class="animation-circle"></div>
37+
<div class="animation-circle"></div>
38+
<div class="animation-circle"></div>
39+
<div class="animation-circle"></div>
40+
<div class="animation-circle"></div>
41+
<div class="animation-circle"></div>
42+
<div class="animation-circle"></div>
43+
<div class="animation-circle"></div>
44+
<div class="animation-circle"></div>
45+
<div class="animation-circle"></div>
46+
<div class="animation-circle"></div>
47+
<div class="animation-circle"></div>
48+
<div class="animation-circle"></div>
49+
<div class="animation-circle"></div>
50+
<div class="animation-circle"></div>
51+
<div class="animation-circle"></div>
52+
</div>

_includes/head.html

+1
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@
118118

119119
<script src="{{ site.data.assets[origin].jquery.js | relative_url }}"></script>
120120
<script async src="//cdn.jsdelivr.net/npm/socket.io-client@2/dist/socket.io.min.js"></script>
121+
<script async src="/assets/js/lib/fireworks.js"></script>
121122

122123
{% unless site.theme_mode %}
123124
{% include mode-toggle.html %}

_layouts/default.html

+2
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@
6666

6767
{% include js-selector.html %}
6868

69+
{% include animated-background.html %}
70+
6971
</body>
7072

7173
</html>

_sass/addon/commons.scss

+61
Original file line numberDiff line numberDiff line change
@@ -1777,3 +1777,64 @@ details {
17771777
animation: infirot 1s linear infinite;
17781778
-webkit-animation: infirot 1s linear infinite;
17791779
}
1780+
1781+
@function random_range($min, $max) {
1782+
$rand: random();
1783+
$random_range: $min + floor($rand * (($max - $min) + 1));
1784+
@return $random_range;
1785+
}
1786+
1787+
#animation {
1788+
position: fixed;
1789+
top: 0;
1790+
left: 0;
1791+
width: 100%;
1792+
height: 100%;
1793+
overflow: hidden;
1794+
pointer-events: none;
1795+
1796+
@keyframes animate {
1797+
0% {
1798+
transform: translateY(0) rotate(0deg);
1799+
opacity: 1;
1800+
border-radius: 0;
1801+
}
1802+
100% {
1803+
transform: translateY(-1200px) rotate(720deg);
1804+
opacity: 0;
1805+
border-radius: 50%;
1806+
}
1807+
}
1808+
1809+
@media all and (min-width: 1200px) {
1810+
.animation-circle {
1811+
position: absolute;
1812+
left: var(--circle-left);
1813+
bottom: -300px;
1814+
display: block;
1815+
background: var(--circle-background);
1816+
width: var(--circle-side-length);
1817+
height: var(--circle-side-length);
1818+
animation: animate 25s linear infinite;
1819+
animation-duration: var(--circle-time);
1820+
animation-delay: var(--circle-delay);
1821+
pointer-events: none;
1822+
1823+
@for $i from 0 through 50 {
1824+
&:nth-child(#{$i}) {
1825+
--circle-left: #{random_range(0%, 100%)};
1826+
--circle-background: rgba(#{random_range(0, 255)}, #{random_range(0, 255)}, #{random_range(0, 255)}, 0.15);
1827+
--circle-side-length: #{random_range(20px, 200px)};
1828+
--circle-time: #{random_range(10s, 45s)};
1829+
--circle-delay: #{random_range(0s, 25s)};
1830+
}
1831+
}
1832+
}
1833+
}
1834+
1835+
@media all and (max-width: 1199px) {
1836+
.animation-circle {
1837+
display: none;
1838+
}
1839+
}
1840+
}

assets/js/lib/fireworks.js

+154
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
class Circle {
2+
constructor({ origin, speed, color, angle, context }) {
3+
this.origin = origin
4+
this.position = { ...this.origin }
5+
this.color = color
6+
this.speed = speed
7+
this.angle = angle
8+
this.context = context
9+
this.renderCount = 0
10+
}
11+
12+
draw() {
13+
this.context.fillStyle = this.color
14+
this.context.beginPath()
15+
this.context.arc(this.position.x, this.position.y, 2, 0, Math.PI * 2)
16+
this.context.fill()
17+
}
18+
19+
move() {
20+
this.position.x = (Math.sin(this.angle) * this.speed) + this.position.x
21+
this.position.y = (Math.cos(this.angle) * this.speed) + this.position.y + (this.renderCount * 0.3)
22+
this.renderCount++
23+
}
24+
}
25+
26+
class Boom {
27+
constructor({ origin, context, circleCount = 16, area }) {
28+
this.origin = origin
29+
this.context = context
30+
this.circleCount = circleCount
31+
this.area = area
32+
this.stop = false
33+
this.circles = []
34+
}
35+
36+
randomArray(range) {
37+
const length = range.length
38+
const randomIndex = Math.floor(length * Math.random())
39+
return range[randomIndex]
40+
}
41+
42+
randomColor() {
43+
const range = ['8', '9', 'A', 'B', 'C', 'D', 'E', 'F']
44+
return '#' + this.randomArray(range) + this.randomArray(range) + this.randomArray(range) + this.randomArray(range) + this.randomArray(range) + this.randomArray(range)
45+
}
46+
47+
randomRange(start, end) {
48+
return (end - start) * Math.random() + start
49+
}
50+
51+
init() {
52+
for (let i = 0; i < this.circleCount; i++) {
53+
const circle = new Circle({
54+
context: this.context,
55+
origin: this.origin,
56+
color: this.randomColor(),
57+
angle: this.randomRange(Math.PI - 1, Math.PI + 1),
58+
speed: this.randomRange(1, 6)
59+
})
60+
this.circles.push(circle)
61+
}
62+
}
63+
64+
move() {
65+
this.circles.forEach((circle, index) => {
66+
if (circle.position.x > this.area.width || circle.position.y > this.area.height) {
67+
return this.circles.splice(index, 1)
68+
}
69+
circle.move()
70+
})
71+
if (this.circles.length == 0) {
72+
this.stop = true
73+
}
74+
}
75+
76+
draw() {
77+
this.circles.forEach(circle => circle.draw())
78+
}
79+
}
80+
81+
class CursorSpecialEffects {
82+
constructor() {
83+
this.computerCanvas = document.createElement('canvas')
84+
this.renderCanvas = document.createElement('canvas')
85+
86+
this.computerContext = this.computerCanvas.getContext('2d')
87+
this.renderContext = this.renderCanvas.getContext('2d')
88+
89+
this.globalWidth = window.innerWidth
90+
this.globalHeight = window.innerHeight
91+
92+
this.booms = []
93+
this.running = false
94+
}
95+
96+
handleMouseDown(e) {
97+
const boom = new Boom({
98+
origin: { x: e.clientX, y: e.clientY },
99+
context: this.computerContext,
100+
area: {
101+
width: this.globalWidth,
102+
height: this.globalHeight
103+
}
104+
})
105+
boom.init()
106+
this.booms.push(boom)
107+
this.running || this.run()
108+
}
109+
110+
handlePageHide() {
111+
this.booms = []
112+
this.running = false
113+
}
114+
115+
init() {
116+
const style = this.renderCanvas.style
117+
style.position = 'fixed'
118+
style.top = style.left = 0
119+
style.zIndex = '999999999999999999999999999999999999999999'
120+
style.pointerEvents = 'none'
121+
122+
style.width = this.renderCanvas.width = this.computerCanvas.width = this.globalWidth
123+
style.height = this.renderCanvas.height = this.computerCanvas.height = this.globalHeight
124+
125+
document.body.append(this.renderCanvas)
126+
127+
window.addEventListener('mousedown', this.handleMouseDown.bind(this))
128+
window.addEventListener('pagehide', this.handlePageHide.bind(this))
129+
}
130+
131+
run() {
132+
this.running = true
133+
if (this.booms.length == 0) {
134+
return this.running = false
135+
}
136+
137+
requestAnimationFrame(this.run.bind(this))
138+
139+
this.computerContext.clearRect(0, 0, this.globalWidth, this.globalHeight)
140+
this.renderContext.clearRect(0, 0, this.globalWidth, this.globalHeight)
141+
142+
this.booms.forEach((boom, index) => {
143+
if (boom.stop) {
144+
return this.booms.splice(index, 1)
145+
}
146+
boom.move()
147+
boom.draw()
148+
})
149+
this.renderContext.drawImage(this.computerCanvas, 0, 0, this.globalWidth, this.globalHeight)
150+
}
151+
}
152+
153+
const cursorSpecialEffects = new CursorSpecialEffects()
154+
cursorSpecialEffects.init()

0 commit comments

Comments
 (0)