Skip to content

Commit 8420b14

Browse files
committed
feat: Add new canvas effect "Moving Gradation"
1 parent d888da0 commit 8420b14

File tree

8 files changed

+178
-0
lines changed

8 files changed

+178
-0
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ There will be continuous updates in the future. Thank you!
4040

4141
### Canvas
4242

43+
- [Moving Gradation](https://github.com/Dev-JeromeBaek/awesome-web-styling/tree/master/canvas/moving-gradation)
44+
4345
- [Rotating Polygons](https://github.com/Dev-JeromeBaek/awesome-web-styling/tree/master/canvas/rotating-polygons)
4446

4547
- [Wavy Layer](https://github.com/Dev-JeromeBaek/awesome-web-styling/tree/master/canvas/wavy-layer)

canvas/README.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Awesome Canvas 😀
22

3+
- [Moving Gradation](https://github.com/Dev-JeromeBaek/awesome-web-styling/tree/master/canvas/moving-gradation)
4+
35
- [Rotating Polygons](https://github.com/Dev-JeromeBaek/awesome-web-styling/tree/master/canvas/rotating-polygons)
46

57
- [Wavy Layer](https://github.com/Dev-JeromeBaek/awesome-web-styling/tree/master/canvas/wavy-layer)

canvas/moving-gradation/README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## Moving Gradation Canvas
2+
3+
![Edit [Web] Moving Gradation](../../gifs/canvas/moving-gradation.gif)

canvas/moving-gradation/app.js

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import { GlowParticle } from "./glowparticle.js";
2+
3+
const COLORS = [
4+
{ r: 45, g: 74, b: 227 }, // blue
5+
{ r: 250, g: 255, b: 89 }, // yellow
6+
{ r: 255, g: 104, b: 248 }, // pupple
7+
{ r: 44, g: 209, b: 252 }, // skyblue
8+
{ r: 54, g: 233, b: 84 }, // green
9+
];
10+
11+
class App {
12+
constructor() {
13+
this.canvas = document.createElement("canvas");
14+
document.body.appendChild(this.canvas);
15+
this.ctx = this.canvas.getContext("2d");
16+
17+
this.pixelRatio = window.devicePixelRatio > 1 ? 2 : 1;
18+
19+
this.totalParticles = 15;
20+
this.particles = [];
21+
this.maxRadius = 900;
22+
this.minRadius = 400;
23+
24+
window.addEventListener("resize", this.resize.bind(this));
25+
this.resize();
26+
window.requestAnimationFrame(this.animate.bind(this));
27+
}
28+
29+
resize() {
30+
this.stageWidth = document.body.clientWidth;
31+
this.stageHeight = document.body.clientHeight;
32+
33+
this.canvas.width = this.stageWidth * this.pixelRatio;
34+
this.canvas.height = this.stageHeight * this.pixelRatio;
35+
this.ctx.scale(this.pixelRatio, this.pixelRatio);
36+
37+
this.ctx.globalCompositeOperation = "saturation";
38+
39+
this.createParticles();
40+
}
41+
42+
createParticles() {
43+
let curColor = 0;
44+
this.particles = [];
45+
46+
for (let i = 0; i < this.totalParticles; i++) {
47+
const item = new GlowParticle(
48+
Math.random() * this.stageWidth,
49+
Math.random() * this.stageHeight,
50+
Math.random() * (this.maxRadius - this.minRadius) + this.minRadius,
51+
COLORS[curColor]
52+
);
53+
54+
if (++curColor >= COLORS.length) {
55+
curColor = 0;
56+
}
57+
58+
this.particles[i] = item;
59+
}
60+
}
61+
62+
animate() {
63+
window.requestAnimationFrame(this.animate.bind(this));
64+
65+
this.ctx.clearRect(0, 0, this.stageWidth, this.stageHeight);
66+
67+
for (let i = 0; i < this.totalParticles; i++) {
68+
const item = this.particles[i];
69+
item.animate(this.ctx, this.stageWidth, this.stageHeight);
70+
}
71+
}
72+
}
73+
74+
window.onload = () => {
75+
new App();
76+
};
+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
const PI2 = Math.PI * 2;
2+
3+
export class GlowParticle {
4+
constructor(x, y, radius, rgb) {
5+
this.x = x;
6+
this.y = y;
7+
this.radius = radius;
8+
this.rgb = rgb;
9+
10+
this.vx = Math.random() * 4;
11+
this.vy = Math.random() * 4;
12+
13+
this.sinValue = Math.random();
14+
}
15+
16+
animate(ctx, stageWidth, stageHeight) {
17+
this.sinValue += 0.01;
18+
19+
this.radius += Math.sin(this.sinValue);
20+
21+
this.x += this.vx;
22+
this.y += this.vy;
23+
24+
if (this.x < 0) {
25+
this.vx *= -1;
26+
this.x += 10;
27+
} else if (this.x > stageWidth) {
28+
this.vx *= -1;
29+
this.x -= 10;
30+
}
31+
32+
if (this.y < 0) {
33+
this.vy *= -1;
34+
this.y += 10;
35+
} else if (this.y > stageHeight) {
36+
this.vy *= -1;
37+
this.y -= 10;
38+
}
39+
40+
ctx.beginPath();
41+
42+
const g = ctx.createRadialGradient(
43+
this.x,
44+
this.y,
45+
this.radius * 0.01,
46+
this.x,
47+
this.y,
48+
this.radius
49+
);
50+
g.addColorStop(0, `rgba(${this.rgb.r}, ${this.rgb.g}, ${this.rgb.b}, 1)`);
51+
g.addColorStop(1, `rgba(${this.rgb.r}, ${this.rgb.g}, ${this.rgb.b}, 0)`);
52+
ctx.fillStyle = g;
53+
ctx.arc(this.x, this.y, this.radius, 0, PI2, false);
54+
ctx.fill();
55+
}
56+
}

canvas/moving-gradation/index.html

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<!-- https://www.youtube.com/watch?v=D6EiRSRhsbQ -->
6+
<meta charset="UTF-8">
7+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
8+
<meta http-equiv="X-UA-Compatible" content="ie=edge">
9+
<title>Moving Gradation</title>
10+
<link rel="shortcut icon" href="../../favicon.ico">
11+
<link rel="stylesheet" type="text/css" href="style.css">
12+
</head>
13+
14+
<body>
15+
<script type="module" src="app.js"></script>
16+
</body>
17+
18+
</html>

canvas/moving-gradation/style.css

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
* {
2+
outline: 0;
3+
margin: 0;
4+
padding: 0;
5+
}
6+
7+
html {
8+
width: 100%;
9+
height: 100%;
10+
}
11+
12+
body {
13+
width: 100%;
14+
height: 100%;
15+
background-color: #ffffff;
16+
}
17+
18+
canvas {
19+
width: 100%;
20+
height: 100%;
21+
}

gifs/canvas/moving-gradation.gif

6.03 MB
Loading

0 commit comments

Comments
 (0)