用canvas+png实现动图,告别gif

本文介绍了一种使用HTML5 Canvas和requestAnimationFrame实现流畅动画的方法。通过自定义计时器和循环更新渲染,结合spritesheet动画技巧,展示了如何在浏览器中创建平滑的动画效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

直接贴代码了:


export const timer = () =>{
    var lastTime = 0;
    var vendors = ['ms', 'moz', 'webkit', 'o'];
    for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
        window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
        window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame'];
    };
    if (!window.requestAnimationFrame) {
        window.requestAnimationFrame = function (callback) {
            var currTime = new Date().getTime();
            var timeToCall = Math.max(0, 16 - (currTime - lastTime));
            var id = window.setTimeout(function () { callback(currTime + timeToCall); }, timeToCall);
            lastTime = currTime + timeToCall;
            return id;
        };
    };
    if (!window.cancelAnimationFrame) {
        window.cancelAnimationFrame = function (id) {
            clearTimeout(id);
        };
    };
}
export const canvasStart = (imgSrc) => {
    if (!imgSrc) return;
    var flash, coinImage, canvas;
    // 为了下面可以清除循环定义
    var loopname;
    // 循环
    function loop() {
        loopname = window.requestAnimationFrame(loop);
        flash.update();
        flash.render();
    }
    // 取消循环
    // function cancelloop() {
    //     window.cancelAnimationFrame(loopname);
    // };

    // 初始化canvas
    function init() {
        flash.render();
    }

    // 
    function sprite(options) {
        var that = {},
            // 首帧位置
            frameIndex = 0,
            // 播放第几帧
            tickCount = 0,
            // 每秒播放帧数
            ticksPerFrame = options.ticksPerFrame || 0,
            // 总帧数字
            numberOfFrames = options.numberOfFrames || 1;

        that.context = options.context;
        that.width = options.width;
        that.height = options.height;
        that.image = options.image;

        that.update = function () {
            tickCount += 1;
            if (tickCount > ticksPerFrame) {
                tickCount = 0;
                // If the current frame index is in range
                if (frameIndex < numberOfFrames - 1) {
                    // Go to the next frame
                    frameIndex += 1;
                } else {
                    frameIndex = 0;
                }
            }
        };

        that.clear = function () {
            // Clear the canvas
            that.context.clearRect(0, 0, that.width, that.height);
        };

        that.render = function () {
            // Clear the canvas
            that.context.clearRect(0, 0, that.width, that.height);
            // Draw the animation
            that.context.drawImage(
                that.image,
                frameIndex * that.width / numberOfFrames,
                0,
                that.width / numberOfFrames,
                that.height,
                0,
                0,
                that.width / numberOfFrames,
                that.height
            );
        };

        return that;
    }

    // Get canvas
    canvas = document.getElementsByTagName("canvas")[0];
    if(!canvas) return;
    canvas.width = 134;
    canvas.height = 150;

    // Create sprite sheet
    coinImage = new Image();

    // set sprite
    flash = sprite({
        context: canvas.getContext("2d"),
        width: 5494,
        height: 150,
        image: coinImage,
        numberOfFrames: 41,
        ticksPerFrame: 4
    });

    // Load sprite sheet
    coinImage.addEventListener("load", init);
    coinImage.src = "http://skybjf.github.io/img/article/insert/20151016/yvdi.png";
    coinImage.src = imgSrc;
    loop();
}
复制代码

效果示例

http://skybjf.github.io/demo/20151016/canvas.html
复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值