【问题标题】:How can I add a radial gradient effect to particles?如何为粒子添加径向渐变效果?
【发布时间】:2020-09-30 01:26:25
【问题描述】:

我正在使用 Canvas 和 JavaScript 创建粒子动画。在下面的示例中,粒子正在动态生成并应用颜色(红色和蓝色)到每个粒子。我想为每个粒子添加径向渐变颜色效果。 我尝试过 createRadialGradient() 方法,但它使我的浏览器窗口空白且动画无法正常工作。

我怎样才能做到这一点?任何参考都会非常有用。提前谢谢你。

(function() {
                var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame ||
                function(callback) {
                    window.setTimeout(callback, 1000 / 60);
                };
                window.requestAnimationFrame = requestAnimationFrame;
            })();

            var particleArr = [],
            canvas = document.getElementById("canvas"),
            ctx = canvas.getContext("2d"),
            flakeCount = 700,
            mouseX = -100,
            mouseY = -100,
            xMultiplier = 0.015
            
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;

            var rate = 0.07788656582264941;

            function getRandomColor() {
                // Random Color Generate
                const colorArr = ["rgba(215,88,69, 1)", "rgba(117, 161, 199, 1)"]; // Blue & Orange Color
                const randomColor = colorArr[Math.floor(Math.random() * colorArr.length)];

                return randomColor;
            }

            function flow() {
                ctx.clearRect(0, 0, canvas.width, canvas.height);
                 
                for (var i = 0; i < flakeCount; i++) {
                    var flake = particleArr[i],
                        x = mouseX,
                        y = mouseY,
                        minDist = 150,
                        x2 = flake.x,
                        y2 = flake.y;

                    var dist = Math.sqrt((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y)),
                        dx = x2 - x,
                        dy = y2 - y;
                    
                    if (dist < minDist) {
                        var force = minDist / (dist * dist),
                            xcomp = (x - x2) / dist,
                            ycomp = (y - y2) / dist,
                            deltaV = force / 2;                            
                        flake.velX -= deltaV * xcomp;
                        flake.velY -= deltaV * ycomp;

                    } else {
                        flake.velX *= .98;
                        if (flake.velY <= flake.speed) {
                            flake.velY = flake.speed
                        }
                        flake.velX += Math.cos(flake.step += .05) * flake.stepSize;
                    }
                
                    flake.y += flake.velY;
                    flake.x += flake.velX;                    
                        
                    if (flake.y >= canvas.height || flake.y <= 0) {
                        reset(flake);
                    }

                    if (flake.x >= canvas.width || flake.x <= 0) {
                        reset(flake);
                    }

                    ctx.fillStyle = particleArr[i].color;
                    
                    ctx.beginPath();
                    ctx.arc(flake.x, flake.y, flake.size, 0, Math.PI * 2);
                    ctx.fill();
                }
                
                requestAnimationFrame(flow);                
            };

            function reset(flake) {
                let temp = (Math.random() * 1) + 0.5;
                flake.x = canvas.width;
                flake.y = 50;
                flake.size = 6.692053245649504;
                flake.speed = (Math.random() * 7) + 0.5;
                flake.velY = flake.speed;
                flake.velX = -xMultiplier  * canvas.width * temp;
            }

            function init() {
                for (var i = 0; i < flakeCount; i++) {
                    var x = canvas.width,
                        y = 50,
                        size = 6.692053245649504,
                        speed = 0;
                      
                    particleArr.push({
                        speed: speed,
                        velY: speed,
                        velX: -xMultiplier  * canvas.width  * speed,
                        x: x,
                        y: y,
                        size: size,
                        stepSize: (Math.random()) / 30,
                        step: 0,
                        angle: 360,
                        color: getRandomColor()
                    });
                }

                requestAnimationFrame(flow);
            };

            canvas.addEventListener("mousemove", function(e) {
                mouseX = e.clientX,
                mouseY = e.clientY     
            });

            window.addEventListener( 'resize', onWindowResize, false );

            function onWindowResize() {
                canvas.width = window.innerWidth;
                canvas.height = window.innerHeight;
            }

            init();
canvas{
                background-color: #000000 !important;
            }

            body {
                margin: 0;
                overflow: hidden;
            }
        &lt;canvas id="canvas"&gt;&lt;/canvas&gt;

【问题讨论】:

    标签: javascript jquery css html5-canvas particles.js


    【解决方案1】:

    fillStyle 设置为您创建的渐变,不要忘记添加色标:

    let grad = ctx.createRadialGradient(flake.x, flake.y, 0, flake.x, flake.y, flake.size);
    grad.addColorStop(0, 'blue');
    grad.addColorStop(1, 'red');
    ctx.fillStyle = grad;
                        
    ctx.beginPath();
    ctx.arc(flake.x, flake.y, flake.size, 0, Math.PI * 2);
    ctx.fill();
    
    

    (function() {
                    var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame ||
                    function(callback) {
                        window.setTimeout(callback, 1000 / 60);
                    };
                    window.requestAnimationFrame = requestAnimationFrame;
                })();
    
                var particleArr = [],
                canvas = document.getElementById("canvas"),
                ctx = canvas.getContext("2d"),
                flakeCount = 700,
                mouseX = -100,
                mouseY = -100,
                xMultiplier = 0.015
                
                canvas.width = window.innerWidth;
                canvas.height = window.innerHeight;
    
                var rate = 0.07788656582264941;
    
                function getRandomColor() {
                    // Random Color Generate
                    const colorArr = ["rgba(215,88,69, 1)", "rgba(117, 161, 199, 1)"]; // Blue & Orange Color
                    const randomColor = colorArr[Math.floor(Math.random() * colorArr.length)];
    
                    return randomColor;
                }
    
                function flow() {
                    ctx.clearRect(0, 0, canvas.width, canvas.height);
                     
                    for (var i = 0; i < flakeCount; i++) {
                        var flake = particleArr[i],
                            x = mouseX,
                            y = mouseY,
                            minDist = 150,
                            x2 = flake.x,
                            y2 = flake.y;
    
                        var dist = Math.sqrt((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y)),
                            dx = x2 - x,
                            dy = y2 - y;
                        
                        if (dist < minDist) {
                            var force = minDist / (dist * dist),
                                xcomp = (x - x2) / dist,
                                ycomp = (y - y2) / dist,
                                deltaV = force / 2;                            
                            flake.velX -= deltaV * xcomp;
                            flake.velY -= deltaV * ycomp;
    
                        } else {
                            flake.velX *= .98;
                            if (flake.velY <= flake.speed) {
                                flake.velY = flake.speed
                            }
                            flake.velX += Math.cos(flake.step += .05) * flake.stepSize;
                        }
                    
                        flake.y += flake.velY;
                        flake.x += flake.velX;                    
                            
                        if (flake.y >= canvas.height || flake.y <= 0) {
                            reset(flake);
                        }
    
                        if (flake.x >= canvas.width || flake.x <= 0) {
                            reset(flake);
                        }
    
                        let grad = ctx.createRadialGradient(flake.x, flake.y, 0, flake.x, 
                        flake.y, flake.size);
                        grad.addColorStop(0, 'blue');
                        grad.addColorStop(1, 'red');
                        ctx.fillStyle = grad;
                  
                        ctx.beginPath();
                        ctx.arc(flake.x, flake.y, flake.size, 0, Math.PI * 2);
                        ctx.fill();
                    }
                    
                    requestAnimationFrame(flow);                
                };
    
                function reset(flake) {
                    let temp = (Math.random() * 1) + 0.5;
                    flake.x = canvas.width;
                    flake.y = 50;
                    flake.size = 6.692053245649504;
                    flake.speed = (Math.random() * 7) + 0.5;
                    flake.velY = flake.speed;
                    flake.velX = -xMultiplier  * canvas.width * temp;
                }
    
                function init() {
                    for (var i = 0; i < flakeCount; i++) {
                        var x = canvas.width,
                            y = 50,
                            size = 6.692053245649504,
                            speed = 0;
                          
                        particleArr.push({
                            speed: speed,
                            velY: speed,
                            velX: -xMultiplier  * canvas.width  * speed,
                            x: x,
                            y: y,
                            size: size,
                            stepSize: (Math.random()) / 30,
                            step: 0,
                            angle: 360,
                            color: getRandomColor()
                        });
                    }
    
                    requestAnimationFrame(flow);
                };
    
                canvas.addEventListener("mousemove", function(e) {
                    mouseX = e.clientX,
                    mouseY = e.clientY     
                });
    
                window.addEventListener( 'resize', onWindowResize, false );
    
                function onWindowResize() {
                    canvas.width = window.innerWidth;
                    canvas.height = window.innerHeight;
                }
    
                init();
    canvas{
                    background-color: #000000 !important;
                }
    
                body {
                    margin: 0;
                    overflow: hidden;
                }
    &lt;canvas id="canvas"&gt;&lt;/canvas&gt;

    请注意,即使它看起来像每个粒子上的两个圆圈(一个红色和一个较小的蓝色在顶部),实际上也有一个渐变,并且调整可以修复这种靶心外观。为了证明它将粒度更改为更大(75+)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-11-06
      • 1970-01-01
      • 1970-01-01
      • 2011-06-28
      • 1970-01-01
      • 1970-01-01
      • 2021-08-26
      相关资源
      最近更新 更多