前端页面如何使用pixi.js与gsap.js实现单车刹车的动画效果 | 猿创营

2,406 阅读3分钟

动画.gif

先上效果图

页面预览链接:static-0e8ae3fb-bd28-44af-9744-94032350d446.bspapp.com/

相关链接整理

需要实现的功能点

1.页面通过按钮控制单车的刹车、运动。

2.按钮需要有涟漪动画效果。

3.页面通过小粒子往左下角滑动来确定刹车的状态。

4.粒子有多个颜色,它们向某一个角度持续移动。

5.当粒子超出边界后回到顶部继续移动。

6.停止的时候粒子有一定回弹的效果,松开鼠标继续运动。

准备开发环境

  • 1.编辑器建议使用vscode,并且安装微软的Live Preview插件,该插件可以在编辑器里面实时的预览代码的执行结果。
  • 2.准备好pixi.js、gsap.js的依赖文件。

在页面中加载素材图片

                this.loader = new PIXI.Loader();

		this.loader.add("btn.png","images/btn.png");
		this.loader.add("brakeBike.png","images/brake_bike.png");
		this.loader.add("brakeHandlerbar.png","images/brake_handlerbar.png");
		this.loader.add("brakeLever.png","images/brake_lever.png");
		this.loader.add("btnCircle.png","images/btn_circle.png");

		this.loader.load();
                

图片资源定义好后要把它们放到PIXI的容器里面去

        this.app = new PIXI.Application({
			width: window.innerWidth,
			height: window.innerHeight,
			backgroundColor: 0xffffff,
			resizeTo: window
		})

		document.querySelector(selector).appendChild(this.app.view)

		this.stage = this.app.stage;

		this.loader = new PIXI.Loader();

		this.loader.add("btn.png","images/btn.png");
		this.loader.add("brakeBike.png","images/brake_bike.png");
		this.loader.add("brakeHandlerbar.png","images/brake_handlerbar.png");
		this.loader.add("brakeLever.png","images/brake_lever.png");
		this.loader.add("btnCircle.png","images/btn_circle.png");

		this.loader.load();

		this.loader.onComplete.add(()=>{
			this.show()
		})
                show(){
                    //addChild最后添加的层级最高
                    let actionButton = this.createActionButton();
                    actionButton.x = 300;
                    actionButton.y = 180;

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

                    bikeContainer.scale.x = bikeContainer.scale.y = 0.3

                    let brakeLever = new PIXI.Sprite(this.loader.resources['brakeLever.png'].texture);
                    bikeContainer.addChild(brakeLever);

                    let bikeImage = new PIXI.Sprite(this.loader.resources['brakeBike.png'].texture);
                    bikeContainer.addChild(bikeImage);

                    let brakeHandlerbar = new PIXI.Sprite(this.loader.resources['brakeHandlerbar.png'].texture);
                    bikeContainer.addChild(brakeHandlerbar);

                    brakeLever.pivot.x = brakeLever.pivot.y = 455;
                    brakeLever.x = 722;
                    brakeLever.y = 900;


                    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['btnCircle.png'].texture)
		let btnCircle1 = new PIXI.Sprite(this.loader.resources['btnCircle.png'].texture)
			
		actionButton.addChild(btnImage);

		actionButton.addChild(btnCircle);
		actionButton.addChild(btnCircle1);

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

		return actionButton;
	}    
  • new PIXI.Application()//创建新的PIXI应用程序。
  • new PIXI.Loader()//Loader可以用来加载资源。
  • new PIXI.Sprite()//加载精灵图片 配置这个方法返回的值使用 《this.loader.resources[Loader创建的图片变量].texture》。
  • 容器或者图片资源可以通过 pivot属性改变动画的中心轴, x,y属性改变位置。
  • gsap.to(pixi对象,动画)可以让pixi对象增加动画效果。

按钮涟漪效果

                let btnCircle = new PIXI.Sprite(this.loader.resources['btnCircle.png'].texture)
		let btnCircle1 = new PIXI.Sprite(this.loader.resources['btnCircle.png'].texture)
			
		actionButton.addChild(btnImage);

		actionButton.addChild(btnCircle);
		actionButton.addChild(btnCircle1);

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

gsap.to(btnCircle.scale,{duration:1,x:1.3,y:1.3,repeat:-1});通过gsap动画让按钮外圆由scale 0.8 重复放大到 1.3,持续时间为1s即可实现涟漪效果。

给按钮增加刹车、运动事件

                actionButton.on("mousedown",()=>{
			gsap.to(brakeLever,{duration: .6,rotation: Math.PI/180*-30});//逆时针旋转一定的角度
			pause();
		})
		actionButton.on("mouseup",()=>{
			gsap.to(brakeLever,{duration: .6,rotation: 0});//回到原点
			start();
		})

pixi.js通过对象的on方法监听事件。

粒子效果

//创建粒子
		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 = [];
		let colors = [0xff1234,0xb5cea8,0xf1cf54,0xf1cf54,0xff0000];

		for(let i = 0;i<10;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
			}

			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++) {
				const pItem = particles[i];
				
				pItem.gr.y += speed;

				if(speed>=20){
					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;
			gsap.ticker.add(loop);
		}
		function pause(){
			gsap.ticker.remove(loop);

			for (let i = 0; i < particles.length; i++) {
				const pItem = particles[i];
				
				pItem.gr.scale.y = 1;
				pItem.gr.scale.x = 1;
				
				gsap.to(pItem.gr,{duration:.6,x:pItem.sx,y:pItem.sy,ease: 'elastic.out'})
			}
		}
		start();

至于粒子效果可以通过new PIXI.Graphics()在页面上随机颜色创建几个小球,小球从上到下运动(沿着Y轴),速度越来越快,随着速度变快,变成了一条线,不断的重复这个运动即可。 想让小球沿某个角度斜着飞,只需要将小球的所在容器旋转角度即可。 当点击刹车的时候,使用gsap.to(pItem.gr,{duration:.6,x:pItem.sx,y:pItem.sy,ease: 'elastic.out'}),关键属性'elastic.out'即可实现粒子停止时的回弹效果。

总结

这次通过学习大帅老师的单车刹车项目后,我对pixi.js、gsap.js有了初步的认识。之前根本没听过这2个技术框架,要是用传统的css来实现这样的效果根本无从下手,所以作为前端程序员还是要多了解一些国外比较优秀的技术。

最后推荐下大帅老师,确实很厉害,干货多多; 在公众号里搜 大帅老猿,他做技术外包很靠谱。