前言
事情是这样的,上个月接了一个活儿。客户要我们模仿一个国外的网站 https://www.vanmoof.com/en-NL... (需要科学上网)
为他们做几个展示动效。
确实很酷!这个项目一共6个动效,客户给的工期是15天,我们实际花在真正写代码上的工期大概一个礼拜左右。报酬2个W
。
可能有同学觉得赚得也不多...的确不算多,但接活儿赚钱只是一方面,更重要的是在这个项目里我带着很多同学们一起实战获得了宝贵的项目实战经验。
并且这种动效开发,很多只会用vue
,react
写页面的前端同学很少能接触到。
想一起接外包私活儿的朋友加v吧:dashuailaoyuan
最终效果
先看最终效果
还原得还是很接近的吧,下面我就来一步步教大家如何写
准备好基础环境
https://github.com/ezshine/YC...
我也给大家准备好了一个空白项目,大家可以clone
这个仓库一步步来实现。
空白项目很简单,引入了两个库,一个叫PIXI
,是性能非常优秀的webGL2d
渲染引擎。另一个GSAP
,是非常优秀的前端动画引擎,这个库非常老牌,从我还在做FLASH
的时代就一直用它。
然后大家安装一下 VSCode
里的 live preview
插件,一定要注意是微软官方出品的,不要装了山寨版。
本教程视频版
https://www.bilibili.com/vide...
创建PIXI应用
class BrakeBanner{
constructor(selector){
//初始化PIXI应用,将舞台设置为1920x1080
this.app = new PIXI.Application({
width:window.innerWidth,
height:window.innerHeight,
backgroundColor: 0xffffff,
resizeTo:window
});
document.querySelector(selector).appendChild(this.app.view);
this.stage = new PIXI.Container();
this.app.stage.addChild(this.stage);
}
}
加载图片资源
//创建资源加载器
this.loader = new PIXI.Loader();
//向资源加载器添加资源 key,path
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.load();
this.loader.onComplete.add(()=>{
this.show();
});
this.loader.resources[key];
通过图片创建精灵元素
const btnImage = new PIXI.Sprite(this.loader.resources['btn.png'].texture);
btnContainer.addChild(btnImage);
const btnCircleImage = new PIXI.Sprite(this.loader.resources['btn_circle.png'].texture);
btnContainer.addChild(btnCircleImage);
转换中心点设置
btnImage.pivot.x = btnImage.pivot.y = btnImage.width/2;
btnCircleImage.pivot.x = btnCircleImage.pivot.y = btnCircleImage.width/2;
btnContainer.x = 200;
btnContainer.y = 200;
初尝动效GSAP
btnCircleImage.scale.x = btnCircleImage.scale.y = .8;
gsap.to(btnCircleImage,{duration:1,alpha:0,repeat:-1})
gsap.to(btnCircleImage.scale,{duration:1,x:1.1,y:1.1,repeat:-1})
把按钮相关的代码整合进 createActionButton 函数中
车架和刹车把手
const bikeContainer = new PIXI.Container();
this.stage.addChild(bikeContainer);
//整体进行一个缩放
bikeContainer.scale.x = bikeContainer.scale.y = .3;
const bikeImage = new PIXI.Sprite(this.loader.resources['brake_bike.png'].texture);
bikeContainer.addChild(bikeImage);
const bikeHandlerImage = new PIXI.Sprite(this.loader.resources['brake_handlerbar.png'].texture);
bikeContainer.addChild(bikeHandlerImage);
车把手
const bikeLeverImage = new PIXI.Sprite(this.loader.resources['brake_lever.png'].texture);
bikeContainer.addChild(bikeLeverImage);
bikeLeverImage.x = 255+454;
bikeLeverImage.y = 450+462;
bikeLeverImage.pivot.x = 454;
bikeLeverImage.pivot.y = 462;
bikeLeverImage.rotation = Math.PI/180*-35;
现在我们这个刹车的旋转角度已经OK了。
添加按钮交互
actionBtn.on("mousedown",()=>{
bikeLeverImage.rotation = Math.PI/180*-35;
})
actionBtn.on("mouseup",()=>{
bikeLeverImage.rotation = 0;
})
加入GSAP
actionBtn.on("mousedown",()=>{
gsap.to(bikeLeverImage,{duration:.6,rotation : Math.PI/180*-35});
})
actionBtn.on("mouseup",()=>{
gsap.to(bikeLeverImage,{duration:.6,rotation : 0});
})
是不是更有感觉了?OK,到这里大家对PIXI和GSAP已经算是入了门了,接下来我们实现这个速度线粒子效果。
将车体永远置于画布右下角
let resize = () => {
bikeContainer.x = window.innerWidth-bikeContainer.width;
bikeContainer.y = window.innerHeight-bikeContainer.height;
}
window.addEventListener('resize', resize);
resize();
速度粒子效果
怎么做?我们再仔细观察一下参考案例
- 首先得要有粒子,也就是小圆点
- 小圆点的颜色有好几种
- 向某一个角度一直移动
- 超出底部边界后回到顶部继续移动
- 按住鼠标停止
- 停止的时候还有一点回弹的效果
- 松开鼠标继续