Getting started with front-end dynamic effects, using PIXI and GSAP to imitate the braking visual effects of vanmoof e-commerce pages |

Brake visual dynamic effect display:

shache.gif

1. The designed technology:

PIXI: is a very fast 2D sprite rendering engine. What does it mean? It means it helps you display, animate and manage interactive graphics so you can easily make games and applications using JavaScript and other HTML5 technologies. It has a reasonable, clean API and includes many useful features such as support for texture atlases and providing a streamlined system for animated sprites (interactive images). It also gives you a complete scene graph so you can create hierarchies of nested sprites (sprites within sprites) and allows you to attach mouse and touch events directly to sprites. And, most importantly, Pixi gives you the freedom to use it, adapt it to your personal coding style, and integrate seamlessly with other frameworks.

GSAP: (GreenSock Animation Platform) is a professional animation library developed from the flash era to today.

2. Implementation steps:

(1), create a PIXI application:

<body>
    <div id="brakebanner"></div>
</body>
复制代码
 window.onload = init;
 function init() {
   let banner = new BrakeBanner("#brakebanner");
 }
 class BrakeBanner {
	constructor(selector) {
		// 使用PIXI,初始化PIXI的应用,创建画布并显示在页面上
		this.app = new PIXI.Application({
			width: window.innerWidth,
			height: window.innerHeight,
			// backgroundColor: 0xffffff,
			backgroundColor:0xf1cf54,
			resizeTo: window
		})
		//添加PIXI应用到页面中
		document.querySelector(selector).appendChild(this.app.view)
	}
}
复制代码

This is the most basic code you need to write to get started with Pixi. It will generate a yellow canvas element on your HTML page. Here's what it looks like when running this code in a browser.

yellow.png

That's right, it's a yellow square!

(2), create a loader to load all images into the canvas:

 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("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("btn_circle.png", "images/btn_circle.png")
            // 触发加载事件
            this.loader.load()
     }
}

复制代码

(3), load the button that controls the brake, the following is the situation when running this code in the browser:

 class BrakeBanner {
	constructor(selector) {
            ............//此处省略上面缩写代码
           // 添加侦听器,侦听加载资源完成的情况
            this.loader.onComplete.add(() => {
                    this.show()
            })            
     }
        //加载资源
        show() {
                let actionButton = this.createActionButton()
                actionButton.x = 400;
                actionButton.y = 400;
                this.stage.addChild(actionButton);

        }
        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);
        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;
        // 给圆圈设置动效,利用gsap,repeat: -1 无限循环
        gsap.to(btnCircle.scale, { duration: 1, x: 1.3, y: 1.3, repeat: -1 });
        // alpha设置透明度
        gsap.to(btnCircle, { duration: 1, alpha: 0, repeat: -1 });
        return actionButton;
        }
}
复制代码

buttondongxiao.gif

(4), load the frame and handlebars:

show() {
        ............//此处省略上面缩写代码
        // 加载车架
        const bikeContainer = new PIXI.Container();
        this.stage.addChild(bikeContainer);
        let bikeImage = new PIXI.Sprite(this.loader.resources["brake_bike.png"].texture);
        // 缩放车架的大小
        bikeContainer.scale.x = bikeContainer.scale.y = .3
        bikeContainer.addChild(bikeImage);
        // 刹车的把手
        let bikeLeverImage = new PIXI.Sprite(this.loader.resources["brake_lever.png"].texture);
        bikeContainer.addChild(bikeLeverImage);
        bikeLeverImage.pivot.x = bikeLeverImage.pivot.y = 455
        bikeLeverImage.x = 722;
        bikeLeverImage.y = 900;
        // 车把手
        let bikeHandlerbarImage = new PIXI.Sprite(this.loader.resources["brake_handlerbar.png"].texture);
        bikeContainer.addChild(bikeHandlerbarImage);
        this.stage.addChild(actionButton);

	}
复制代码

Here's what it looks like when running this code in the browser:

chejia.png

(5) Trigger events of the brake handle:

show(){
         ............//此处省略上面缩写代码
        // 设置按住的触发事件
        actionButton.interactive = true;
        // 鼠标移动到按住按钮上显示小手
        actionButton.buttonMode = true;
        actionButton.on("mousedown", () => {
        // 旋转刹车把手
        gsap.to(bikeLeverImage, { duration: 0.6, rotation: Math.PI / 180 * -30 })
         })
        actionButton.on("mouseup", () => {
        // 旋转刹车把手
        gsap.to(bikeLeverImage, { duration: 0.6, rotation: 0 })
        })
    }
复制代码

Here's what it looks like when running this code in the browser:

anzhushache_.gif

(6), add the dynamic effect of the particles and combine it with the brake to display:

show(){
    ............//此处省略上面缩写代码
    // 设置自行车的位置一直在页面右下角
    let resize = () => {
        bikeContainer.x = window.innerWidth - bikeContainer.width
        bikeContainer.y = window.innerHeight - bikeContainer.height
    }
    window.addEventListener("resize", resize)
    resize()

    // 创建粒子容器
    let partcleContainer = new PIXI.Container();
    this.stage.addChild(partcleContainer);
    partcleContainer.pivot.x = window.innerWidth / 2;
    partcleContainer.pivot.y = window.innerHeight / 2;
    ;
    partcleContainer.x = window.innerWidth / 2;
    partcleContainer.y = window.innerHeight / 2;

    partcleContainer.rotation = 35 * Math.PI / 180;
    let partcles = [];
    let colors = [0xf1cf54, 0xb5cea8, 0xf1cf54, 0x818181, 0x000000]
    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, 6);
            gr.endFill();
            // 初始化粒子的坐标
            let pItem = {
                    sx: Math.random() * window.innerWidth,
                    sy: Math.random() * window.innerHeight,
                    gr
            }
            gr.x = pItem.sx;
            gr.y = pItem.sy;
            partcleContainer.addChild(gr);
            partcles.push(pItem);
    }

    let speed = 0;
    function loop() {
        speed += 0.1;
        speed = Math.min(speed, 20)
        for (let i = 0; i < partcles.length; i++) {
                let pItem = partcles[i];
                pItem.gr.y += speed;
                if (speed >= 20) {
                        pItem.gr.scale.x = 0.03;
                        pItem.gr.scale.y = 40;
                }
                if (pItem.gr.y > window.innerHeight) pItem.gr.y = 0;
        }
    }
    function start() {
            speed = 0
            gsap.ticker.add(loop)
    }
    function pause() {
            gsap.ticker.remove(loop)
            for (let i = 0; i < partcles.length; i++) {
                    let pItem = partcles[i];
                    pItem.gr.scale.x = 1;
                    pItem.gr.scale.y = 1;
                    gsap.to(pItem.gr, { duration: .6, x: pItem.sx, y: pItem.sy, easy: "elastic.out" })
            }
	}
  start();
}
复制代码

Here's what it looks like when running this code in the browser:

all_.gif

3. The above are all the steps and codes to realize the braking effect. If you like it, let's act quickly.

Project source code: github.com/jianghongsh…

4. Finally

Search in the official account  大帅老猿, you can learn a lot from him!

Guess you like

Origin juejin.im/post/7119398346942644261