PageSourceSearch

https://dsso.kr/js/shootingstar.js

js dsso.kr collected 2026-09-24 11:49:13 UTC 7,686 bytes, 250 lines download raw bytes

1"use strict";
2window.onload = function() {
3    setTimeout(start, 200);
4};
5
6function start() {
7
8    //Helpers
9    function lineToAngle(x1, y1, length, radians) {
10        var x2 = x1 + length * Math.cos(radians),
11            y2 = y1 + length * Math.sin(radians);
12        return { x: x2, y: y2 };
13    }
14
15    function randomRange(min, max) {
16        return min + Math.random() * (max - min);
17    }
18
19    function degreesToRads(degrees) {
20        return degrees / 180 * Math.PI;
21    }
22
23    //Particle
24    var particle = {
25        x: 0,
26        y: 0,
27        vx: 0,
28        vy: 0,
29        radius: 0,
30
31        create: function(x, y, speed, direction) {
32            var obj = Object.create(this);
33            obj.x = x;
34            obj.y = y;
35            obj.vx = Math.cos(direction) * speed;
36            obj.vy = Math.sin(direction) * speed;
37            return obj;
38        },
39
40        getSpeed: function() {
41            return Math.sqrt(this.vx * this.vx + this.vy * this.vy);
42        },
43
44        setSpeed: function(speed) {
45            var heading = this.getHeading();
46            this.vx = Math.cos(heading) * speed;
47            this.vy = Math.sin(heading) * speed;
48        },
49
50        getHeading: function() {
51            return Math.atan2(this.vy, this.vx);
52        },
53
54        setHeading: function(heading) {
55            var speed = this.getSpeed();
56            this.vx = Math.cos(heading) * speed;
57            this.vy = Math.sin(heading) * speed;
58        },
59
60        update: function() {
61            this.x += this.vx;
62            this.y += this.vy;
63        }
64    };
65
66    //Canvas and settings
67    var canvas = document.getElementById("canvas"),
68        context = canvas.getContext("2d"),
69        width = canvas.width = window.innerWidth,
70        height = canvas.height = window.innerHeight,
71        stars = [],
72        shootingStars = [],
73        layers = [
74            { speed: 0.015, scale: 0.2, count: 320 },
75            { speed: 0.03, scale: 0.5, count: 50 },
76            { speed: 0.05, scale: 0.75, count: 30 }
77        ],
78        starsAngle = 145,
79        shootingStarSpeed = {
80            min: 15,
81            max: 20
82        },
83        shootingStarOpacityDelta = 0.01,
84        trailLengthDelta = 0.01,
85        shootingStarEmittingInterval = 2000,
86        shootingStarLifeTime = 500,
87        maxTrailLength = 300,
88        starBaseRadius = 2,
89        shootingStarRadius = 3,
90        paused = false;
91
92    //Create all stars
93    for (var j = 0; j < layers.length; j += 1) {
94        var layer = layers[j];
95        for (var i = 0; i < layer.count; i += 1) {
96            var star = particle.create(randomRange(0, width), randomRange(0, height), 0, 0);
97            star.radius = starBaseRadius * layer.scale;
98            star.setSpeed(layer.speed);
99            star.setHeading(degreesToRads(starsAngle));
100            stars.push(star);
101        }
102    }
103
104    function createShootingStar() {
105        var shootingStar = particle.create(randomRange(width / 2, width), randomRange(0, height / 2), 0, 0);
106        shootingStar.setSpeed(randomRange(shootingStarSpeed.min, shootingStarSpeed.max));
107        shootingStar.setHeading(degreesToRads(starsAngle));
108        shootingStar.radius = shootingStarRadius;
109        shootingStar.opacity = 0;
110        shootingStar.trailLengthDelta = 0;
111        shootingStar.isSpawning = true;
112        shootingStar.isDying = false;
113        shootingStars.push(shootingStar);
114    }
115
116    function killShootingStar(shootingStar) {
117        setTimeout(function() {
118            shootingStar.isDying = true;
119        }, shootingStarLifeTime);
120    }
121
122    function update() {
123        if (!paused) {
124            context.clearRect(0, 0, width, height);
125            context.fillStyle = "rgba(255, 255, 255, 0)";
126            context.fillRect(0, 0, width, height);
127            context.fill();
128
129            for (var i = 0; i < stars.length; i += 1) {
130                var star = stars[i];
131                star.update();
132                drawStar(star);
133                if (star.x > width) {
134                    star.x = 0;
135                }
136                if (star.x < 0) {
137                    star.x = width;
138                }
139                if (star.y > height) {
140                    star.y = 0;
141                }
142                if (star.y < 0) {
143                    star.y = height;
144                }
145            }
146
147            for (i = 0; i < shootingStars.length; i += 1) {
148                var shootingStar = shootingStars[i];
149                if (shootingStar.isSpawning) {
150                    shootingStar.opacity += shootingStarOpacityDelta;
151                    if (shootingStar.opacity >= 1.0) {
152                        shootingStar.isSpawning = false;
153                        killShootingStar(shootingStar);
154                    }
155                }
156                if (shootingStar.isDying) {
157                    shootingStar.opacity -= shootingStarOpacityDelta;
158                    if (shootingStar.opacity <= 0.0) {
159                        shootingStar.isDying = false;
160                        shootingStar.isDead = true;
161                    }
162                }
163                shootingStar.trailLengthDelta += trailLengthDelta;
164
165                shootingStar.update();
166                if (shootingStar.opacity > 0.0) {
167                    drawShootingStar(shootingStar);
168                }
169            }
170
171            //Delete dead shooting shootingStars
172            for (i = shootingStars.length -1; i >= 0 ; i--){
173                if (shootingStars[i].isDead){
174                    shootingStars.splice(i, 1);
175                }
176            }
177        }
178        requestAnimationFrame(update);
179    }
180
181    function drawStar(star) {
182        context.fillStyle = "rgb(255, 221, 157)";
183        context.beginPath();
184        context.arc(star.x, star.y, star.radius, 0, Math.PI * 2, false);
185        context.fill();
186    }
187
188    function drawShootingStar(p) {
189        var x = p.x,
190            y = p.y,
191            currentTrailLength = (maxTrailLength * p.trailLengthDelta),
192            pos = lineToAngle(x, y, -currentTrailLength, p.getHeading());
193
194        context.fillStyle = "rgba(255, 255, 255, " + p.opacity + ")";
195        // context.beginPath();
196        // context.arc(x, y, p.radius, 0, Math.PI * 2, false);
197        // context.fill();
198        var starLength = 5;
199        context.beginPath();
200        context.moveTo(x - 1, y + 1);
201
202        context.lineTo(x, y + starLength);
203        context.lineTo(x + 1, y + 1);
204
205        context.lineTo(x + starLength, y);
206        context.lineTo(x + 1, y - 1);
207
208        context.lineTo(x, y + 1);
209        context.lineTo(x, y - starLength);
210
211        context.lineTo(x - 1, y - 1);
212        context.lineTo(x - starLength, y);
213
214        context.lineTo(x - 1, y + 1);
215        context.lineTo(x - starLength, y);
216
217        context.closePath();
218        context.fill();
219
220        //trail
221        context.fillStyle = "rgba(255, 221, 157, " + p.opacity + ")";
222        context.beginPath();
223        context.moveTo(x - 1, y - 1);
224        context.lineTo(pos.x, pos.y);
225        context.lineTo(x + 1, y + 1);
226        context.closePath();
227        context.fill();
228    }
229
230    //Run
231    update();
232
233    //Shooting stars
234    setInterval(function() {
235        if (paused) return;
236        createShootingStar();
237    }, shootingStarEmittingInterval);
238
239    window.onfocus = function () {
240      paused = false;
241    };
242
243    window.onblur = function () {
244      paused = true;
245    };
246
247}
248
249
250/* 출처 : https://codepen.io/frexuz/pen/BvHsk */

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.