PIXI+GSAP 防刹车动效 | 猿创营

前言

之前没有接触过动画开发,今天参加猿创营实训活动学习下拓展下知识面
原版vanmoof商城地址

使用到的技术

Pixi

  • 一个非常快的2D sprite渲染引擎
  • 可以帮助你显示、动画和管理交互式图形,这样你就可以轻松地使用JavaScript和其他HTML5技术制作游戏和应用程序

GSAP

  • 一个从flash时代一直发展到今天的专业动画库

开发过程

创建一个PIXI.Application实例

constructor(selector) {
    this.app = new PIXI.Application({
            widtd: window.innerWidth,
            height: window.innerHeight,
            backgroundColor: 0xffffff,
            resizeTo: window
    }      
    document.querySelector(selector).appendChild(this.app.view)
...
}

加载项目需要用到的图片资源

this.loader = new PIXI.Loader();
this.loader.add("btn.png", "images/btn.png");
this.loader.add("btn_circle.png", "images/btn_circle.png");
this.loader.add("brake_bike.png", "images/brake_bike.png");
this.loader.add("brake_handlerbar.png", "images/brake_handlerbar.png");
this.loader.add("brake_lever.png", "images/brake_lever.png");
this.loader.add("malu_line.png", "images/malu_line.png");
this.loader.load();

绘制按钮给按钮加上动画

let actionButton = new PIXI.Container();

let btnImage = new PIXI.Sprite(this.loader.resources['btn.png'].texture);
let btnCircle = new PIXI.Sprite(this.loader.resources['btn_circle.png'].texture)
let btnCircle2 = new PIXI.Sprite(this.loader.resources['btn_circle.png'].texture)

actionButton.addChild(btnImage);
actionButton.addChild(btnCircle);
actionButton.addChild(btnCircle2);

btnImage.pivot.x = btnImage.pivot.y = btnImage.width / 2
btnCircle.pivot.x = btnCircle.pivot.y = btnCircle.width / 2
btnCircle2.pivot.x = btnCircle2.pivot.y = btnCircle2.width / 2
btnCircle.scale.x = btnCircle.scale.y = 0.8
actionButton.scale.x = actionButton.scale.y = 0.8
gsap.to(btnCircle.scale, { duration: 1, x: 1.3, y: 1.3, repeat: -1 })
gsap.to(btnCircle.scale, { duration: 1, alpha: 0, repeat: -1 })
return actionButton;

绘制自行车

const bikeContainer = new PIXI.Container();
this.stage.addChild(bikeContainer)

bikeContainer.scale.x = bikeContainer.scale.y = 0.3;
const bikeImage = new PIXI.Sprite(this.loader.resources['brake_bike.png'].texture);
bikeContainer.addChild(bikeImage)

const bikeLeverImage = new PIXI.Sprite(this.loader.resources['brake_lever.png'].texture);
bikeContainer.addChild(bikeLeverImage)

bikeLeverImage.pivot.x = 455;
bikeLeverImage.pivot.y = 455;

bikeLeverImage.x = 722;
bikeLeverImage.y = 900;
const bikeHandbarImage = new PIXI.Sprite(this.loader.resources['brake_handlerbar.png'].texture);
bikeContainer.addChild(bikeHandbarImage)

绘制粒子效果

let particleContainer = new PIXI.Container();
this.stage.addChild(particleContainer);

particleContainer.rotation = 35 * Math.PI / 180;
particleContainer.pivot.x = window.innerWidth / 2;
particleContainer.pivot.y = window.innerHeight / 2;

particleContainer.x = window.innerWidth / 2;
particleContainer.y = window.innerHeight / 2;


let particles = [];
const colors = [0xf1cf54, 0xb5cea8, 0xf1cf54, 0x818181, 0x000000];
for (let i = 0; i < 10; i++) {
        let gr = new PIXI.Graphics();
        let randomColor = Math.floor(Math.random() * colors.length)
        gr.beginFill(colors[randomColor]);
        gr.drawCircle(0, 0, 6);
        gr.endFill();

        let pItem = {
                sx: Math.random() * window.innerWidth,
                sy: Math.random() * window.innerHeight,
                gr: gr
        }

        gr.x = pItem.sx;
        gr.y = pItem.sy;

        particleContainer.addChild(gr);
        particles.push(pItem)
}
let speed = 0;
function loop() {
        speed += .5;
        speed = Math.min(speed, 20);
        for (let i = 0; i < particles.length; i++) {
                let pItem = particles[i];
                // pItem.gr.y += 10;
                pItem.gr.y += speed;
                if (speed >= 20) { // since slow to fast
                        pItem.gr.scale.y = 40;
                        pItem.gr.scale.x = 0.03;
                }
                if (pItem.gr.y > window.innerHeight) {
                        pItem.gr.y = 0;
                }
        }
}
function start() {
        speed = 0;
        // gasp.ticker.add(loop)
        gsap.ticker.add(loop);
}
function pause() {
        gsap.ticker.remove(loop);

        for (let i = 0; i < particles.length; i++) {
                let pItem = particles[i];
                // pItem.gr.y += 10;
                pItem.gr.y += speed;

                pItem.gr.scale.y = 1;
                pItem.gr.scale.x = 1;

                gsap.to(pItem.gr, { duration: .6, x: pItem.sx, y: pItem.sy, ease: 'eelastic.out' })

        }

}

给按钮绑定事件触发车把手的变化和粒子变化

actionButton.on("mousedown", () => {
        gsap.to(bikeLeverImage, { duration: .6, rotation: Math.PI / 180 * -30 })
        pause();
});
actionButton.on("mouseup", () => {
        gsap.to(bikeLeverImage, { duration: .6, rotation: 0 })
        start();
});

源码地址

小结

公众号里搜 大帅老猿,在他这里可以学到很多东西

猜你喜欢

转载自juejin.im/post/7126119160643321893