After learning the calculation of circular motion, I suddenly got a flash of inspiration

I have a hobby, that is photography! Why don't I use this way to achieve a star orbit effect!!!

Your browser does not support canvas, please upgrade your browser
<html>
<body>
    <div id="canvas-container" style="width: 600px; height: 400px; position: relative; background: linear-gradient(#040e47,#040e47,#051355,#07256b,#444a82, #c8966e);">
        <canvas id="myCanvas" style="width: 600px; height: 400px; ">
            Your browser does not support canvas, please upgrade your browser
        </canvas>
        <div id="skyline" style="width: 100%; height: 135px; bottom: 0; left: 0; position: absolute; background: url(/upload/post/7208a351-7359-4d26-868c-0376d9286f9c.png) repeat-x 50% 0;"></div>
    </div>
</body>
</html>
<script>
    window.requestAnimFrame = (function () {
        return window.requestAnimationFrame ||
            window.webkitRequestAnimationFrame ||
            window.mozRequestAnimationFrame ||
            function (callback) {
                window.setTimeout(callback, 1000 / 60);
            };
    })();

    function random(min, max) {
        return Math.random() * (max - min) + min;
    }

    function setupCanvas(canvas) {
        // Get the device pixel ratio, falling back to 1.
        var dpr = window.devicePixelRatio || 1;
        // Get the size of the canvas in CSS pixels.
        var rect = canvas.getBoundingClientRect();
        // Give the canvas pixel dimensions of their CSS
        // size * the device pixel ratio.
        canvas.width = rect.width * dpr;
        canvas.height = rect.height * dpr;
        var ctx = canvas.getContext('2d');
        // Scale all drawing operations by the dpr, so you
        // don't have to worry about the difference.
        ctx.scale(dpr, dpr);
        return ctx;
    }

    var canvas = document.getElementById("myCanvas"),
        ctx = setupCanvas(canvas),
        w = canvas.clientWidth,
        h = canvas.clientHeight,
        //Center point of rotation
        centerX = w * 2 / 3,
        centerY = h * 2 / 3,
        // 
        starCount = 720,
        stars = [];

    function Star(x, y, cx, cy) {
        this.x = x;
        this.y = y;
        this.cx = cx;
        this.cy = cy;

        var angle = - 1;
        var dx = cx - x,
            dy = cy - y;
        
        //Calculate the initial radius of rotation
        this.radius = Math.sqrt(dx * dx + dy * dy);
        
        //Color value control
        this.hue = random(0, 1) > .5 ? random(0, 80) : random(160, 260);

        //Transparency control
        this.alpha = - 1;
        this.alphaDecay = random(0.001, 0.015);
        this.alphaMax = random(0, 1)
        
        //Track the past coordinates of each star to create a track effect, increase the coordinate count to create a more obvious track
        this.coordinates = [];
        this.coordinateCount = 15;
        while (this.coordinateCount--) {
            this.coordinates.push([this.x, this.y]);
        }

        this.draw = function () {
            ctx.strokeStyle = 'hsla(' + this.hue + ', 80%, ' + random(80, 100) + '%, ' + this.alpha + ')';
            ctx.lineWidth = 0.5
            
            //Draw highlights
            ctx.beginPath();
            ctx.moveTo(this.coordinates[this.coordinates.length - 1][0], this.coordinates[this.coordinates.length - 1][1]);
            ctx.lineTo(this.x, this.y);
            ctx.stroke();
            
            //Draw star anise
            if (this.radius > 100) {
                this.createPolygonalStar(this.x, this.y, 8, 1, 12, 45, 0, this.hue, this.alpha);
            }
        }

        // x : central coordinate x value
        // y : center coordinate y value
        // n : number of star angles
        // r : distance from center to concave point
        // R : Center to vertex distance
        // rotation : pre rotation angle
        // borderWidth : edge width
        // hue : color value
        // alpha : transparency
        // isFilled : fill or not
        this.createPolygonalStar = function (x, y, n, r, R, rotation, borderWidth, hue, alpha, isFilled = true) {
            ctx.save();
            ctx.fillStyle = 'hsla(' + hue + ', 80%, 60%, ' + alpha + ')';
            ctx.lineWidth = borderWidth;

            ctx.beginPath();
            for (var i = 0; i < n; i++) {
                var perDeg = 360 / n;
                var degA = perDeg / 2 / 2;
                var degB = 360 / (n - 1) / 2 - degA / 2 + degA;
                ctx.lineTo(Math.cos((degA + perDeg * i - rotation) / 180 * Math.PI) * R + (x - R) + borderWidth + R * Math.cos(degA / 180 * Math.PI),
                    -Math.sin((degA + perDeg * i - rotation) / 180 * Math.PI) * R + (y - R) + borderWidth + R);
                ctx.lineTo(Math.cos((degB + perDeg * i - rotation) / 180 * Math.PI) * r + (x - R) + borderWidth + R * Math.cos(degA / 180 * Math.PI),
                    -Math.sin((degB + perDeg * i - rotation) / 180 * Math.PI) * r + (y - R) + borderWidth + R);
            }
            ctx.closePath();

            if (!!isFilled) {
                ctx.fill();
            } else {
                ctx.stroke();
            }

            ctx.restore();
        }

        this.update = function () {
            this.coordinates.pop();
            this.coordinates.unshift([this.x, this.y]);
            
            //Coordinate calculation after rotation
            this.x = this.cx + Math.sin(angle) * this.radius;
            this.y = this.cy + Math.cos(angle) * this.radius;
            
            //Increasing radius of rotation
            this.radius += 0.05;
            
            //Stop transparency at random
            if (this.alpha <= this.alphaMax) {
                this.alpha += this.alphaDecay;
            }
            
            //Increasing rotation angle
            angle += 0.01;
        }
    }

    function loop() {
        requestAnimFrame(loop);

        ctx.save();
        ctx.globalCompositeOperation = "destination-in";
        ctx.fillStyle = 'rgba(0,0,0,.8)';
        ctx.fillRect(0, 0, w, h);
        ctx.restore();

        if (stars.length < starCount) {
            stars.push(new Star(random(0, w), centerY, centerX, centerY));
        }

        var i = stars.length;

        while (i--) {
            stars[i].draw();
            stars[i].update();
            if (stars[i].radius > 400) {
                stars.splice(i, 1);
            }
        }
    }

    loop();
</script>

All Comments

Leave a Reply Cancel Reply

Tips: Your email address will not be disclosed!

If you can't see clearly,please click to change...

Popular Posts

Collections