美文网首页
Confetti效果实现

Confetti效果实现

作者: CODERLIHAO | 来源:发表于2020-08-05 09:57 被阅读0次
    2020-07-29 20.40.22.gif

    构建confetti粒子对象

    随机初始化x的坐标,y的坐标是在屏幕的上方初始化,随机初始化宽度
    随机初始化倾斜长度

       function confettiParticle(color) {
            this.x = Math.random() * W;
            this.y = Math.random() * H - H;
            this.r = RandomFromTo(20, 40);
            this.color = color;
            this.tilt = Math.floor(10 * Math.random()) - 10;
            this.tiltAngleIncremental = .07 * Math.random() + .05;
            this.tiltAngle = 0;
            this.draw = function () {
                ctx.beginPath();
                ctx.lineWidth = this.r / 2;
                ctx.strokeStyle = this.color;
                ctx.moveTo(this.x + this.tilt + this.r / 4, this.y);
                ctx.lineTo(this.x + this.tilt, this.y + this.tilt + this.r / 4);
                ctx.stroke();
            }
        }
    

    开始初始化,构建一定数量的粒子

       function InitializeConfetti() {
            particles = [];
            for (let i = 0; i < mp; i++) {
                let color = particleColors.getColor();
                particles.push(new confettiParticle(color))
            }
            StartConfetti()
        }
    

    开始做动画

       function StartConfetti() {
            W = window.innerWidth;
            H = window.innerHeight;
            canvas1.width = W;
            canvas1.height = H;
            Draw();
            requestAnimFrame(StartConfetti.bind(this))
        }
    

    画出每个粒子

        function Draw() {
            ctx.clearRect(0, 0, W, H);
            for (let i = 0; i < mp; i++) {
                particles[i].draw()
            }
            Update();
        }
    

    angle开始增加,这样particle的x就会正弦变化了 particle.x += Math.sin(angle);

    
        function Update() {
            let particle = undefined;
            angle += .01;
            tiltAngle += .1;
            for (let n = 0; n < mp; n++) {
                particle = particles[n];
                stepParticle(particle, n);
                CheckForReposition(particle);
            }
        }
    
        function CheckForReposition(particle) {
            // 判断粒子有没有超出屏幕
            if (particle.x > W + 20 || particle.x < -20 || particle.y > H) {
                 // 重新初始化新的位置
                repositionParticle(particle, Math.random() * W, -10, Math.floor(10 * Math.random()) - 10)
            }
        }
    
        function stepParticle(particle, i) {
            particle.tiltAngle += particle.tiltAngleIncremental;
            //y的位置余弦变化
            particle.y += (Math.cos(angle) + particle.r / 2) / 2;
            //x的位置正弦变化
            particle.x += Math.sin(angle);
            particle.tilt = 15 * Math.sin(particle.tiltAngle);
        }
    
        function repositionParticle(particle, x, y, tilt) {
            particle.x = x;
            particle.y = y;
            particle.tilt = tilt;
        }
    

    下面给出全部代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <canvas id="canvas" width="1129" height="768"></canvas>
    <script>
        let canvas1, ctx, W, H;
        let mp = 0;
        if (screen.width >= 988) {
            mp = 150
        } else {
            mp = 75
        }
    
        let particles = [];
        let angle = 0;
        let tiltAngle = 0;
        let particleColors = {
            colorOptions: ["DodgerBlue", "OliveDrab", "Gold", "pink", "SlateBlue", "lightblue", "Violet", "PaleGreen", "SteelBlue", "SandyBrown", "Chocolate", "Crimson"],
            colorIndex: 0,
            colorIncrementer: 0,
            colorThreshold: 10,
            getColor: function () {
                return this.colorIncrementer >= 10 && (this.colorIncrementer = 0, this.colorIndex++, this.colorIndex >= this.colorOptions.length && (this.colorIndex = 0)), this.colorIncrementer++, this.colorOptions[this.colorIndex]
            }
        };
    
        function confettiParticle(color) {
            this.x = Math.random() * W;
            this.y = Math.random() * H - H;
            this.r = RandomFromTo(10, 30);
            this.color = color;
            this.tilt = Math.floor(10 * Math.random()) - 10;
            this.tiltAngleIncremental = .07 * Math.random() + .05;
            this.tiltAngle = 0;
            this.draw = function () {
                ctx.beginPath();
                ctx.lineWidth = this.r / 2;
                ctx.strokeStyle = this.color;
                ctx.moveTo(this.x + this.tilt + this.r / 4, this.y);
                ctx.lineTo(this.x + this.tilt, this.y + this.tilt + this.r / 4);
                ctx.stroke();
            }
        }
    
    
        function SetGlobals() {
            canvas1 = document.getElementById("canvas");
            ctx = canvas1.getContext("2d");
            W = window.innerWidth;
            H = window.innerHeight;
            canvas1.width = W;
            canvas1.height = H;
        }
    
        function InitializeConfetti() {
            particles = [];
            for (let i = 0; i < mp; i++) {
                let color = particleColors.getColor();
                particles.push(new confettiParticle(color))
            }
            StartConfetti()
        }
    
        function Draw() {
            ctx.clearRect(0, 0, W, H);
            for (let i = 0; i < mp; i++) {
                particles[i].draw()
            }
            Update();
        }
    
        /**
         * @return {number}
         */
        function RandomFromTo(t, i) {
            return Math.floor(Math.random() * (i - t + 1) + t)
        }
    
        function Update() {
            let particle = undefined;
            angle += .01;
            tiltAngle += .1;
            for (let n = 0; n < mp; n++) {
                particle = particles[n];
                stepParticle(particle, n);
                CheckForReposition(particle);
            }
        }
    
        function CheckForReposition(particle) {
            if (particle.x > W + 20 || particle.x < -20 || particle.y > H) {
                repositionParticle(particle, Math.random() * W, -10, Math.floor(10 * Math.random()) - 10)
            }
        }
    
        function stepParticle(particle, i) {
            particle.tiltAngle += particle.tiltAngleIncremental;
            particle.y += (Math.cos(angle) + particle.r / 2) / 2;
            particle.x += Math.sin(angle);
            particle.tilt = 15 * Math.sin(particle.tiltAngle);
        }
    
        function repositionParticle(particle, x, y, tilt) {
            particle.x = x;
            particle.y = y;
            particle.tilt = tilt;
        }
    
        function StartConfetti() {
            W = window.innerWidth;
            H = window.innerHeight;
            canvas1.width = W;
            canvas1.height = H;
            Draw();
            requestAnimFrame(StartConfetti.bind(this))
        }
    
        window.requestAnimFrame = window.requestAnimationFrame ||
            window.webkitRequestAnimationFrame ||
            window.mozRequestAnimationFrame ||
            window.oRequestAnimationFrame ||
            window.msRequestAnimationFrame || function (t) {
                return window.setTimeout(t, 1e3 / 60)
            };
    
        SetGlobals();
        InitializeConfetti();
    </script>
    </body>
    </html>
    

    参考:https://github.com/Agezao/confetti-js

    相关文章

      网友评论

          本文标题:Confetti效果实现

          本文链接:https://www.haomeiwen.com/subject/mfikrktx.html