美文网首页
vue 使用雪碧图、canvas做帧动画

vue 使用雪碧图、canvas做帧动画

作者: 小猪x | 来源:发表于2022-05-09 16:21 被阅读0次
<style lang="less">
    @import './rebbit.less';
</style>

<template>
    <div class="rabiit_ll" v-if="isShowRabbit">
        <canvas ref="rabbitId" :style="`width:${scale * 108}px;height:${scale * 120}px;`"/>
        <div class="hand_view" :style="`width:${scale * 108}px;height:${scale * 108}px;left:${scale * -5}px;top:${scale * 12}px;background-image: url(${handImg});`"/>
    </div>
</template>

<script>

let total = 21;
let picHost = 'https://h2.appsimg.com/a.appsimg.com/upload/wxadmin/2021/12/09/153/9d7796ca49dd4165a6453b6cf4996fdb.png';

export default {
    name: 'RebbitView',
    props: {
        // 缩放比例
        scale: {
            type: Number,
            default: 1
        },
        // 等级
        userLevel: {
            type: Number,
            default: 1
        }
    },
    data () {
        return {
            isShowRabbit: true,
            handImg: 'https://weixin.vipstatic.com/uploadfiles/wx-small/images/rubbit_hand_1.png'
        };
    },

    watch: {
        userLevel (value) {
            let userLevel = value || 1;
            this.handImg = `https://weixin.vipstatic.com/uploadfiles/wx-small/images/rubbit_hand_${userLevel}.png`;
        }
    },

    mounted () {
        this.startRubbit();
    },

    destroyed () {
        this.stopRubbit();
    },

    methods: {
        startRubbit () {
            if (this.hasRubbit) {
                return;
            }
            this.hasRubbit = true;

            let canvas = this.$refs.rabbitId;
            canvas.width = 270;
            canvas.height = 300;
            let context = canvas.getContext('2d');

            this.getImage().then((img) => {
                let startTime;
                let curCount = 0;
                this.step = () => {
                    if (!this.hasRubbit) {
                        return;
                    }
                    if (!startTime) {
                        startTime = new Date().getTime();
                    }
                    let timestamp = new Date().getTime();
                    let elapsed = timestamp - startTime;

                    if (elapsed > 40) {
                        startTime = timestamp;
                        let imgW = 270;
                        let imgH = 300;
                        let sx = (curCount % 3) * imgW;
                        let sy = Math.floor(curCount / 3) * imgH;
                        context.clearRect(0, 0, imgW, imgH);
                        context.drawImage(img, sx, sy, imgW, imgH, 0, 0, imgW, imgH); // 绘制
                        curCount = (curCount + 1) % total;
                    }
                    this.requestFrameId = requestAnimationFrame(this.step);
                };
                this.requestFrameId = requestAnimationFrame(this.step);
            }).catch(err => {
                console.error('加载兔子图片有异常', err);
                this.isShowRabbit = false;
                this.stopRubbit();
            });
        },

        /**
         * 获取图片对象
         */
        getImage () {
            return new Promise((resolve, reject) => {
                let img = new Image();
                img.src = picHost;
                img.onerror = (err) => {
                    reject(err);
                };
                img.onload = () => {
                    resolve(img);
                };
            });
        },

        /**
         * 停止动画
         */
        stopRubbit () {
            this.hasRubbit = false;
            if (this.requestFrameId) {
                cancelAnimationFrame(this.requestFrameId);
            }
        }
    }
};
</script>

.rabiit_ll {
    position: relative;
    .hand_view {
        position: absolute;
        background-size: 100% 100%;
        background-repeat: no-repeat;
        animation: shake 1s infinite linear;
        transform-origin: 50% 50%;
    }
}


@keyframes shake {
    0% {
        transform: rotate(0deg);
    }
    25% {
        transform: rotate(5deg);
    }
    50% {
        transform: rotate(0deg);
    }
    75% {
        transform: rotate(-5deg);
    }
    100% {
        transform: rotate(0deg);
    }
}
image.png

相关文章

  • vue 使用雪碧图、canvas做帧动画

  • 动画

    Android中的动画主要分为补间动画、帧动画和属性动画。 1.补间动画与帧动画都是canvas对matrix的操...

  • CSS 雪碧图

    Question: 1、什么是雪碧图?2、为什么使用雪碧图?3、什么情况下适合使用雪碧图?4、雪碧图怎么使用?5、...

  • css-Sprite (雪碧图)

    雪碧图的使用场景: 不推荐使用雪碧图的地方: css Sprite(雪碧图)的实现原理: 雪碧图的实现方式: 作者...

  • 利用SurfaceView实现帧动画效果,更流畅,更节约内存

    利用SurfaceView实现帧动画效果 在开发Android做动画效果的时候,有时候UI给开发一组动画实现的帧图...

  • CSS3逐帧动画写法

    找了好久动画写法,全是雪碧图,都没有看到过CSS真正的逐帧写法。今天有福了,看看波波写法吧。 波波写法,哈哈,从同...

  • Android动画

    文章脑图 1、Android动画种类 逐帧动画、补间动画、属性动画 逐帧动画 逐帧动画的原理就是让一系列的静态图片...

  • 前端—雪碧图

    使用雪碧图的优点有以下几点: 雪碧图的制作与使用方法:

  • 对WindowManager中的View设置动画

    1.直接对View设置传统动画 传统动画包括帧动画和补间动画。帧动画主要是一帧一帧的播放。可以在xml中使用 标签...

  • canvas-nest用法

    源码 vue中使用 vue插件(vue-canvas-nest) install Usage example

网友评论

      本文标题:vue 使用雪碧图、canvas做帧动画

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