zoukankan      html  css  js  c++  java
  • canvas序列帧动画 & pixi.js

    方法一:基于canvas实现多个人物序列帧切换 (原生写法)

    class cavasAnimate {
        constructor(id, activeRw) {
            this.id = id;
            this.sourcesRw = {};
            this.canvas = null;
            this.ctx = null;
            this.timer = null;
            this.loadedImages = 0;
            this.numImages = 0;
            this.images = [];
            this.activeRw = activeRw;
            this.init(id)
            this.sourceImg = {}
            this.existKey = []
        }
    
        init(id) {
            //创建画布
            this.canvas = document.getElementById(id);
            this.canvas.width = this.activeRw.width;
            this.canvas.height = this.activeRw.height;
            this.ctx = this.canvas.getContext("2d");
            this.changeRw(this.activeRw, id);
        }
    
        changeRw(activeRw) {
            console.log(this.sourceImg);
    
            // this.timer = null;
            clearInterval(this.timer);
            this.sourcesRw = [];
            this.canvas.width = activeRw.width;
            this.canvas.height = activeRw.height;
            this.ctx.clearRect(0, 0, this.activeRw.width, this.activeRw.height);
            setTimeout(() => {
                console.log(5, Array.isArray(this.sourceImg), this.sourceImg, this.sourceImg.length)
            }, 10000)
            //执行图片预加载,加载完成后播放图片
            this.loadImg(this.sourcesRw, activeRw, (images) => {
    
                // console.log(1,this.sourcesRw)
                this.activeRw = activeRw;
                clearInterval(this.timer)
                this.playImg(images)
            });
        }
    
        loadImg(sourcesRw, activeRw, callback) {
            this.loadedImages = 0;
            this.numImages = 0;
            this.images = [];
            this.numImages = this.sourcesRw.length;
            console.log('load')
            if (this.sourceImg) {
                this.existKey = []
                for (let i in this.sourceImg) {
                    console.log(i);
                    this.existKey.push(i)
                }
                console.log('this.existKey', this.existKey)
            }
    
    
            if (this.existKey && this.existKey.indexOf(activeRw.key) > -1) {
                callback(this.sourceImg[activeRw.key]);
                return;
            }
    
            for (let i = 0; i <= activeRw.num; i++) {
                this.sourcesRw[i] = require('@/assets/images/' + activeRw.key + '/' + activeRw.key + i + '.png');
            }
    
            for (let i = 0, len = sourcesRw.length; i < len; i++) {
                this.images[i] = new Image();
                //当一张图片加载完成时执行
                this.images[i].onload = () => {
                    //当所有图片加载完成时,执行回调函数callback
                    this.loadedImages++;
                    if (this.loadedImages >= this.numImages) {
                        callback(this.images);
                        this.sourceImg[activeRw.key] = this.images
    
    
                    }
                };
                //把sourcesRw中的图片信息导入images数组
                this.images[i].src = this.sourcesRw[i];
            }
        }
    
        playImg(images) {
            let imageNum = images.length;
            let imageNow = 0;
            this.timer = setInterval(() => {
                this.ctx.clearRect(0, 0, this.activeRw.width, this.activeRw.height);
                // this.ctx.globalAlpha=0.9
                this.ctx.drawImage(images[imageNow], 0, 0, this.activeRw.width, this.activeRw.height);
                if (document.getElementById(this.id).parentElement.style.background !== "none") {
                    document.getElementById(this.id).parentElement.style.background = "none";
                }
    
                imageNow++;
                if (imageNow >= imageNum) {
                    imageNow = 0;
                }
            }, 70)
        }
    
        resize() {
    
        }
    }
    
    const animateObj = (id, rwList) => {
        return new cavasAnimate(id, rwList);
    };
    
    export default animateObj;
    data() {
                return {
                    canvasAniObj: null,
                    activeIndex: 0,
                    timer: null,
                    rwArr: [
                        {
                            key: 'hu',
                             1400,
                            height: 1308,
                            num: 107
                        }, {
                            key: 'al',
                             950,
                            height: 1628,
                            num: 66
                        },
                        {
                            key: 'll',
                             1400,
                            height: 1564,
                            num: 67
                        }
    
                    ],
                    loaded: false
                };
            },
            watch: {},
            methods: {
                chooseRw(index) {
                    console.log(index)
                    this.activeIndex = index;
                    this.canvasAniObj.changeRw(this.rwArr[index])
                    let imgUrl = require('@/assets/images/' + this.rwArr[index].key + '/' + this.rwArr[index].key + '0.png');
                    document.getElementById('animation_canvas').parentElement.style.backgroundImage = 'url(' + imgUrl + ')';
                }
            },
            mounted() {
                this.canvasAniObj = cavasAnimation("animation_canvas", this.rwArr[0]
            }

    方法一:基于 pixi.js 实现多个人物序列帧切换

    import * as PIXI from "pixi.js-legacy";
    
    class animate {
        constructor(id, idGroup, picInfo) {
            if (window.pixiStore === undefined) {
                window.pixiStore = {
                    urlList: {},
                    callbackID: {
                        part1: 0,
                        part5: 0
                    }
                };
            }
            this.idGroup = idGroup;
            this.picInfo = picInfo;
            this.id = id;
            this.app = new PIXI.Application({
                transparent: true,
                forceCanvas: true
            });
    
            this.anim = null;
            document.getElementById(this.id).innerHTML = "";
            document.getElementById(this.id).appendChild(this.app.view);
        }
    
        animation(type, retryTimes, callbackID) {
            this.app.stage.removeChild(this.anim);
    
            let imgs = [];
            let frames = [];
    
            for (let $i = 0; $i <= this.picInfo[type].imgnum; $i++) {
                let imgUrl = require("@/assets/rw/" +
                    this.picInfo[type].folderu +
                    type +
                    $i +
                    ".png");
    
                if (
                    window.pixiStore.urlList[imgUrl] === undefined ||
                    window.pixiStore.urlList[imgUrl] === false
                ) {
                    window.pixiStore.urlList[imgUrl] = true;
                    imgs.push(imgUrl);
                }
            }
    
            this.app.loader.reset();
            this.app.loader.add(imgs).load(() => {
                if (
                    window.pixiStore.callbackID[this.idGroup[this.id]] !==
                    callbackID
                ) {
                    return;
                }
    
                let dirty = false;
    
                for (let $i = 0; $i <= this.picInfo[type].imgnum; $i++) {
                    let imgUrl = require("@/assets/rw/" +
                            this.picInfo[type].folderu +
                            type +
                            $i +
                            ".png"),
                        textrue = PIXI.Texture.from(imgUrl);
                    if (textrue.orig.width === 1) {
                        window.pixiStore.urlList[imgUrl] = false;
                        PIXI.Texture.removeFromCache(imgUrl);
                        if (dirty === false) {
                            dirty = true;
                        }
                    }
    
                    frames.push(textrue);
                }
    
                if (dirty && retryTimes < 1) {
                    retryTimes++;
                    this.animation(type, retryTimes, callbackID);
                    return;
                } else if (dirty && retryTimes >= 1) {
                    return;
                }
    
                this.app.stage.removeChild(this.anim);
                this.resize(type);
    
                document.getElementById(this.id).style.background = "none";
    
                this.anim = new PIXI.AnimatedSprite(frames);
                this.anim.animationSpeed = 20 / 60;
                this.app.stage.addChild(this.anim);
                this.anim.play();
            });
        }
    
        render(type) {
            document.getElementById(this.id).style.background = "";
            let retryTimes = 0;
            window.pixiStore.callbackID[this.idGroup[this.id]]++;
            this.animation(
                type,
                retryTimes,
                window.pixiStore.callbackID[this.idGroup[this.id]]
            );
        }
    
        resize(type) {
            let width = document.getElementById(this.id).offsetWidth;
            let height = document.getElementById(this.id).offsetHeight;
    
            this.app.renderer.resize(width, height);
            this.app.stage.scale.x =
                this.app.renderer.width / this.picInfo[type].width;
            this.app.stage.scale.y =
                this.app.renderer.height / this.picInfo[type].height;
        }
    }
    
    const animateObj = (id, idGroup, picInfo) => {
        return new animate(id, idGroup, picInfo);
    };
    
    export default animateObj;
    
    
    mofeiList: [
    {
    key: "mofei_1",
    key2: "hu",
    name: "阿狐",
    txt:
    "澈底的及時享樂主義者,中意一切「風流」的東西:月、酒、花與刀。<br/> 最喜歡的是在盛放中飄散的櫻花。"
    },
    {
    key: "mofei_2",
    key2: "al",
    name: "埃里克",
    txt:
    "高能,冰冷、嚴厲、無情的終極兵器機械少女。不過, 倘若這些只是自我掩飾的面具……?"
    },
    {
    key: "mofei_3",
    name: "芬德爾",
    key2: "fd",
    txt:
    "濕噠噠黏糊糊的奇異生物。將自己的身體設定成了人類的少女形態,對此非常自得。"
    },
    },
    idGroup: {
    "part1-ani": "part1",
    part5rw: "part5",
    part52rw: "part5"
    },

    picInfo: {
    hu: {
    1400,
    height: 1308,
    folderu: "hu/",
    imgnum: 107
    },
    al: {
    950,
    height: 1628,
    folderu: "al/",
    imgnum: 65
    },

    fd: {
    850,
    height: 1460,
    folderu: "fd/",
    imgnum: 83
    }
    },

    methods: { chooseTab(tab) { this.activeTab = tab; this.showAni = false; setTimeout(() => { this.showAni = true; }, 50); if (tab == "buxia") { this.rwList = this.buxiaList; } else { this.rwList = this.mofeiList; } this.$nextTick(() => { this.animateObj.render(this.animateType.key2); }); }, chooseRw(idx) { this.currentRwIndex = idx; this.showAni = false; setTimeout(() => { this.showAni = true; }, 50); this.$nextTick(() => { this.animateObj.render(this.animateType.key2); }); } }, created() { this.rwList = this.mofeiList; }, mounted() { console.log(this.animateType); this.$nextTick(() => { this.animateObj = animate("part5rw", this.idGroup, this.picInfo); this.animateObj.render(this.animateType.key2); }); }
  • 相关阅读:
    【实战】如何实现滚轮时间的显示
    NSDate的常用用法
    UIDatePicker的简单用法
    NSDateFormatter相关整理
    UIPickerView
    回家任务
    addTarget:self 的意思是说,这个方法在本类中
    2020/2/25
    树上启发式合并
    题解
  • 原文地址:https://www.cnblogs.com/catherLee/p/13278292.html
Copyright © 2011-2022 走看看