一个3k的刹车动效长什么样子(PIXI+GSAP) | 猿创营

914 阅读2分钟

刹车效果展示

shache.gif

相关链接

思路

  1. 初始化我们的舞台-画布大小
  2. 将需要的图片加载进来
  3. 调整图片位置及页面窗口调整图片位置
  4. 添加按钮动效和鼠标点击和松开刹车把手动效
  5. 创建粒子-使粒子运动起来添加动效

初始化

PIXI.Application创建新的PIXI应用程序的便利类,这个类自动创建渲染器、ticker和根容器。

<html>
    <body>
        <div id="brakebanner"></div>
        <script src="https://pixijs.download/release/pixi.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.4/gsap.min.js"></script>
        <script>
            window.onload = init;
            function init() {
                let banner = new BrakeBanner("#brakebanner");
            }
            class BrakeBanner {
                constructor(selector){
                    // 初始化PIXI应用
                    this.app = new PIXI.Application({
                      width: window.innerWidth,
                      height: window.innerHeight,
                      backgroundColor: 0xffffff,
                      resizeTo: window, // 设置窗口可调整大小
                    });

                    //添加到页面
                    document.querySelector(selector).appendChild(this.app.view);
                }
            }
        </script>
    </body>
</html>

此时浏览器什么也不显示,因为画布颜色为白色,修改backgroundColor来更改画布颜色

加载所需的图片

PIXI中的层级根据加载的前后来决定

PIXI.Container 容器代表显示对象的集合。它是所有显示对象的基类,这些显示对象充当其他对象(例如Sprites)的容器。

PIXI.Sprite 创建精灵,Sprite对象是渲染到屏幕上的所有纹理对象的基础,可以直接从这里的图像创建精灵:

class BrakeBanner {
    constructor(selector){
        this.stage = this.app.stage;
        // 加载图片
        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_lever.png", "images/brake_lever.png");
        this.loader.add("brake_handlerbar.png", "images/brake_handlerbar.png");
        this.loader.add("brake_bike.png", "images/brake_bike.png");
         // 触发加载
        this.loader.load();
        // 加载完成后执行
        this.loader.onComplete.add(() => {
          this.show();
        });
    }
    show(){
        // 加载点击按钮
        let actionButton = this.createActionButton();
        actionButton.x = 420;
        actionButton.y = 320;
        
        // 车体
        const bikeContainer = new PIXI.Container();
        // 加载刹车把手
        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;

        // 加载车型
        bikeContainer.scale.x = bikeContainer.scale.y = 0.3;
        const bikeImage = new PIXI.Sprite(
          this.loader.resources["brake_bike.png"].texture
        );
        // 加载车把手
        const bikeHandlerbarImage = new PIXI.Sprite(
          this.loader.resources["brake_handlerbar.png"].texture
        );
        bikeContainer.addChild(bikeHandlerbarImage, bikeImage);
        this.stage.addChild(bikeContainer);
        this.stage.addChild(actionButton);
        
        const resize = () => {
          bikeContainer.x = window.innerWidth - bikeContainer.width;
          bikeContainer.y = window.innerHeight - bikeContainer.height;
        };
        resize();
        window.addEventListener("resize", resize);
    }
    createActionButton(){
        // 创建按钮容器
        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, btnCircle, 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;

        return actionButton;
    }
}

加载完我们的图片及修改完图片的位置,打开浏览器如下看到现在的效果,下面图片资源加载完后给我们的按钮和刹车把手添加动效

image.png

添加动效

show(){
    actionButton.interactive = true; // 设置按钮可交互
    actionButton.buttonMode = true; // 小手模式
    // 按钮点击事件
    actionButton.on("mousedown", () => {
      gsap.to(bikeLeverImage, {
        duration: 0.3,
        rotation: (Math.PI / 180) * -30,
      });
    });
    actionButton.on("mouseup", () => {
      gsap.to(bikeLeverImage, { duration: 0.3, rotation: 0 });
    });
}
createActionButton(){
    gsap.to(btnCircle.scale, { duration: 1, x: 1.2, y: 1.2, repeat: -1 });
    gsap.to(btnCircle, { duration: 1, alpha: 0, repeat: -1 });
}

dongxiao1.gif

添加粒子效果

粒子效果很简单,创建一个容器,随机绘画生成20个圆,向Y轴运动,旋转容器,再判断是否超出可视边界后改变Y的位置到可视范围内即可。

    // 创建粒子
    let particleContainer = new PIXI.Container();
    this.stage.addChild(particleContainer);

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

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

    particleContainer.rotation = (35 * Math.PI) / 180;
    let particles = [];
    let colors = [0xf1cf54, 0xb5cea8, 0xf1cf54, 0x818e9b];
    for (let i = 0; i < 20; i++) {
      let gr = new PIXI.Graphics();
      gr.beginFill(colors[Math.floor(Math.random() * colors.length)]);
      gr.drawCircle(0, 0, 4);
      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 += 0.5;
      speed = Math.min(speed, 20);
      for (let i = 0; i < particles.length; i++) {
        let pItem = particles[i];
        pItem.gr.y += speed;
        if (speed >= 20) {
          pItem.gr.scale.y = 20;
          pItem.gr.scale.x = 0.07;
        }
        if (pItem.gr.y > window.innerHeight) {
          pItem.gr.y = Math.random() * window.innerHeight;
        }
      }
    }
    function start() {
      speed = 0;
      gsap.ticker.add(loop);
    }
    function pause() {
      gsap.ticker.remove(loop);
      for (let i = 0; i < particles.length; i++) {
        let pItem = particles[i];
        pItem.gr.scale.y = 1;
        pItem.gr.scale.x = 1;
        gsap.to(pItem.gr, {
          duration: 0.6,
          x: pItem.sx,
          y: pItem.sy,
          ease: "elastic.out",
        });
      }
    }
    start();

shache.gif

最后

源码地址:github

视频教程地址:bilibili

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