|
@@ -0,0 +1,96 @@
|
|
1
|
+function Animation(selector, option) {
|
|
2
|
+ this.canvas = this.init(selector);
|
|
3
|
+ this.fireflies = new Array(option.count).fill({}).map(function () {
|
|
4
|
+ return new Firefly(option);
|
|
5
|
+ });
|
|
6
|
+}
|
|
7
|
+
|
|
8
|
+Animation.prototype.init = function (canvas) {
|
|
9
|
+ var resize = function () {
|
|
10
|
+ canvas.width = window.innerWidth;
|
|
11
|
+ canvas.height = window.innerHeight;
|
|
12
|
+ }
|
|
13
|
+
|
|
14
|
+ resize();
|
|
15
|
+ window.addEventListener('resize', resize);
|
|
16
|
+
|
|
17
|
+ return canvas;
|
|
18
|
+}
|
|
19
|
+
|
|
20
|
+Animation.prototype.draw = function () {
|
|
21
|
+ var drawer = this.draw.bind(this);
|
|
22
|
+
|
|
23
|
+ this.redraw();
|
|
24
|
+ window.requestAnimationFrame(drawer);
|
|
25
|
+}
|
|
26
|
+
|
|
27
|
+Animation.prototype.redraw = function () {
|
|
28
|
+ var ctx = this.canvas.getContext('2d');
|
|
29
|
+
|
|
30
|
+ ctx.clearRect(0, 0, window.innerWidth, window.innerHeight);
|
|
31
|
+ this.fireflies.forEach(function (firefly) {
|
|
32
|
+ firefly.fly();
|
|
33
|
+ firefly.flicker();
|
|
34
|
+
|
|
35
|
+ ctx.beginPath();
|
|
36
|
+ ctx.arc(firefly.x, firefly.y, firefly.radius, 0, Math.PI * 2);
|
|
37
|
+ ctx.closePath();
|
|
38
|
+ ctx.fillStyle = firefly.color;
|
|
39
|
+ ctx.shadowBlur = firefly.radius * 5;
|
|
40
|
+ ctx.shadowColor = "yellow";
|
|
41
|
+ ctx.fill();
|
|
42
|
+ })
|
|
43
|
+}
|
|
44
|
+
|
|
45
|
+export default Animation;
|
|
46
|
+
|
|
47
|
+function Firefly(option) {
|
|
48
|
+ this.x = random(window.innerWidth, option.radius, true);
|
|
49
|
+ this.y = random(window.innerHeight, option.radius, true);
|
|
50
|
+ this.radius = random(option.radius + 0.5, option.radius - 0.5);
|
|
51
|
+ this.veer = false;
|
|
52
|
+ this.angle = random(360, 0, true);
|
|
53
|
+ this.rate = random(30 / 1000, 6 / 1000);
|
|
54
|
+ this.speed = random(option.speed, option.speed / 8);
|
|
55
|
+ this.opacity = random(1, 0.001);
|
|
56
|
+ this.flare = this.opacity > 0.5;
|
|
57
|
+ this.color = option.color;
|
|
58
|
+}
|
|
59
|
+
|
|
60
|
+Firefly.prototype.fly = function () {
|
|
61
|
+ if (this.angle >= 360 || this.angle <= 0 || Math.random() * 360 < 6) {
|
|
62
|
+ this.veer = !this.veer;
|
|
63
|
+ }
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+ this.angle -= this.veer ? -this.speed : this.speed;
|
|
67
|
+ this.x += Math.sin((Math.PI / 180) * this.angle) * this.speed;
|
|
68
|
+ this.y += Math.cos((Math.PI / 180) * this.angle) * this.speed;
|
|
69
|
+
|
|
70
|
+ if (this.x < 0) this.x += window.innerWidth;
|
|
71
|
+ if (this.x > window.innerWidth) this.x -= window.innerWidth;
|
|
72
|
+ if (this.y < 0) this.y += window.innerHeight;
|
|
73
|
+ if (this.y > window.innerHeight) this.y -= window.innerHeight;
|
|
74
|
+}
|
|
75
|
+
|
|
76
|
+Firefly.prototype.flicker = function () {
|
|
77
|
+ if (this.opacity >= 1 || this.opacity <= 0.001) {
|
|
78
|
+ this.flare = !this.flare;
|
|
79
|
+ }
|
|
80
|
+
|
|
81
|
+ this.opacity -= this.flare ? -this.rate : this.rate;
|
|
82
|
+ this.color = setOpacity(this.color, this.opacity.toFixed(3));
|
|
83
|
+}
|
|
84
|
+
|
|
85
|
+function random(max, min, isInt) {
|
|
86
|
+ return isInt
|
|
87
|
+ ? Math.floor((Math.random() * (max - min) + min))
|
|
88
|
+ : Number((Math.random() * (max - min) + min).toFixed(3));
|
|
89
|
+}
|
|
90
|
+
|
|
91
|
+function setOpacity(color, opacity) {
|
|
92
|
+ var colors = color.match(/^rgba\((\d+),\s*(\d+),\s*(\d+),\s*(\S+)\)$/);
|
|
93
|
+
|
|
94
|
+ return "rgba(" + colors[1] + ", " + colors[2] + ", " + colors[3] + ", " + opacity + ")";
|
|
95
|
+}
|
|
96
|
+
|