[canvas] 仿明日方舟向上缓缓飘动的粒子效果

439 阅读1分钟

最近看游戏网站有点上头,所以对动画特效方面的兴趣,再次油然而生了。所以,过过手瘾,简单的模仿一下。这样也方便后面开发时候复用。这个效果确实比较简单。不过对于我这个新手来说,还是踩了不少坑。

明日方舟官网ak.hypergryph.com/

javascript代码,如下: js代码的对应描述已经写在代码中了。

function createCanvas(){
    let canvas = document.querySelector('canvas');
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    
    window.addEventListener('resize', ()=>{
      canvas.width = window.innerWidth;
      canvas.height = window.innerHeight;
    })
    
    let ctx = canvas.getContext('2d');

    let num = 25; // 元素数量

    let elementArr = [];
    /* 组合元素信息 */
    const createArc = (num) => {
        for (let i = 0; i < num; i++) {
            elementArr.push({
                x: canvas.clientWidth * Math.random(), // x轴坐标
                y: canvas.clientHeight + canvas.clientHeight*Math.random(), // y轴坐标
                v: Math.random() + 0.1,   // 移动速度
                minY: canvas.clientHeight * Math.random(), // 最小的y值,小于等于minY元素消失
                r: 2, // 生成圆点的半径
                opacity: 1, // 元素的透明度
            })
        }

    };

    /* canvas渲染元素,通过组合元素信息进行 */
    const renderEle = (element) => {
        ctx.beginPath();
        // 设置径向渐变的时候,如果是给元素设置,那么原点就是元素的圆心位置。如果圆心为canvas的中心,那么就是根据canvas的径向渐变
        let grd = ctx.createRadialGradient(element.x, element.y, 0, element.x, element.y, 2);
        grd.addColorStop(0, '#ffffff');
        grd.addColorStop(1, '#ffffff1f');
        ctx.globalAlpha= element.opacity; // 透明度
        ctx.arc(element.x, element.y, element.r, 0,  Math.PI*2);
        ctx.fillStyle= grd;
        ctx.closePath();
        ctx.fill();
        
    };

    /* 每个元素的移动 */
    const updateEle = (element) => {
        element.y -= element.v;
        if(element.y<element.minY+element.minY*0.2){
          element.opacity-=0.01;
        }
        if(element.y <= element.minY - element.r*2){
            let key = elementArr.indexOf(element);
            elementArr.splice(key, 1); // 移除一个粒子
            createArc(1);  // 初始化一个粒子
        }
    };

    /* canvas渲染元素以及位移 */
    const render = () => {
        ctx.clearRect(0, 0, canvas.clientWidth, canvas.clientHeight);
        for(const ele of elementArr){
            renderEle(ele);
            updateEle(ele);
        }
        requestAnimationFrame(() => {render();});
    };

    createArc(num);  // 初始化粒子
    render();  // 开始渲染
};

createCanvas();

废话不多说了,看效果吧。

文章仅供参,有什么问题的话,可以反馈给我,一起讨论成长,不喜勿喷。

我也忘记从哪里看到的这么一段鸡汤,不过听着很有道理。勉励我继续逆风前行。

舞台再大,你不上台,永远是个观众。平台再好,你不参与,永远是局外人。能力再大,你不行动,只能看别人成功。没有人关心你付出多少努力,撑的累不累,摔得痛不痛,他们只会看你最后站在什么位置,然后羡慕或是鄙夷。