[WEB] 播放序列帧动画

451 阅读2分钟

记录一下我写序列帧动画的方式。 目的:方便日后重复使用;同时想看看大家有没有其他好的方式,可以一起讨论一下。 这里是图片资源

jgg_hint_entity_sprites.png 首先,写一个序列帧动画的配置文件。

/* 配置文件 */
const effectConfig = {
    jggCard:{
        image: "../../static/image/jgg_hint_entity_sprites.png",
        imgW: 426,
        imgH: 254,
        spritesTotalW: 3408,
        spritesTotalH: 254,
        closePage: true,
        loop: true,
        timeInterval: 80, // ms
        maxNumber: 8,
        moveDistance:{
            1: {x:-426 * 0, y:0},
            2: {x:-426 * 1, y:0},
            3: {x:-426 * 2, y:0},
            4: {x:-426 * 3, y:0},
            5: {x:-426 * 4, y:0},
            6: {x:-426 * 5, y:0},
            7: {x:-426 * 6, y:0},
            8: {x:-426 * 7, y:0},
        }
    },
}

实现帧动画播放的逻辑

    let frame, timerOut;
    jggCardEffect(className){
        className = '.jgg_card_effect'
        
        let effectDom = document.querySelector(className);
        let moveNum = 1;
        let moveMaxNum = effectConfig.jggCard.maxNumber;
        
        effectDom.style.setProperty("width", `${effectConfig.jggCard.width}px`);  
        effectDom.style.setProperty("height", `${effectConfig.jggCard.height}px`);  
        effectDom.style.setProperty("background", `url(${effectConfig.jggCard.image}} 100% no-repeat`);

        const aniFrame = () => {
            effectDom.style.setProperty('background-position', effectConfig.jggCard.moveDistance[moveNum].x + 'px');
            moveNum++;
            return frame = requestAnimationFrame(() => {
                // 由于显示器刷新率太高,所以使用延时器控制每帧之间的间隔
                timerOut = setTimeout(()=>{
                    if(moveNum>moveMaxNum) {
                        // 这里是重复执行的判断
                        cancelAnimationFrame(frame); // 结束上一次完整流程
                        moveNum = 1; // 回到最开始的位置
                        if(effectConfig.jggCard.loop) frame = requestAnimationFrame(aniFrame); // 开始新一轮执行, loop为true就执行,没有的话,就不执行。
                    }else {
                        // 只执行一次
                        frame = requestAnimationFrame(aniFrame);
                    }
                    clearTimeout(timerOut);
                }, effectConfig.jggCard.timeInterval);
            })
        };
        frame = requestAnimationFrame(aniFrame);  
        return frame;
    }
    
    stopFrameAnimationEffect(){  
        cancelAnimationFrame(frame);  
        clearTimeout(timerOut);  
    }
    
    jggCardEffect();

效果展示

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

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

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