完成效果图
动效分三部分(开头好潦草啊,后面补吧)
- 水波纹效果
- 刹车
- 粒子运动
什么是PIXIJS
PixiJS是一个轻量级的2D渲染引擎,它能自动侦测使用WebGL还是Canvas来创建图形。开发者无需专门学习 WebGL 就能感受到强大的硬件加速的力量。
pixi应用对象的成员
成员 | 类型 | 描述 |
---|---|---|
app.loader | PIXI.Loader | 加载器实例用于资源加载,用于加载静态资源。 |
app.resizeTo | Window|HTMLElement | 元素或窗口尺寸更改 |
app.screen | PIXI.Rentangle | 渲染器的屏幕矩形对象 |
app.stage | PIXI.Container | 根显示容器,舞台,pixi创建的根容器。游戏中的精灵或容器都要添加到舞台上才能显示。 |
app.ticker | PIXI.Ticker | 计时器,可理解为每次渲染一帧前执行。 |
app.view | HTMLCanvasElement | 渲染器的canvas元素,pixi创建的DOM元素即用于渲染游戏的canvas。 |
BrakeBanner类的构建
创建画布,将画布加入dom中
//创建一个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("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()
})
按钮水波纹
加载素材(按钮,水波纹)
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);
- 通过pivot设置远点,这里将原点设置在图片的中心位置
- scale 将图片等比缩放
- alpha 设置视图的透明度
gsap.to(targets, vars)
产生从初始位置(或状态)到目标位置(或状态)的动画
targets: 产生动画的对象
vars: 目标状态参数
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;
actionButton.x = actionButton.y = 400;
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 });
完成按钮的创建
this.stage.addChild(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 bikeLeverlImage = new PIXI.Sprite(this.loader.resources["brake_lever.png"].texture)
bikeContainer.addChild(bikeLeverlImage);
bikeLeverlImage.pivot.x = 455
bikeLeverlImage.pivot.y = 455
bikeLeverlImage.x = 722
bikeLeverlImage.y = 900
//刹车
const bikeHandlerBarImage = new PIXI.Sprite(this.loader.resources["brake_handlerbar.png"].texture)
bikeContainer.addChild(bikeHandlerBarImage);
interactive
有交互的元素一定要设interactive属性为true,否则[监听]的事件都将无反应。buttonMode
属性,默认为false,设置为true时,鼠标悬浮会变成手型。或者可以直接设置cursor
来修改光标样式
actionButton.interactive = true;
//小手
actionButton.buttonMode = true;
//刹车
actionButton.on("mousedown", () => {
// bikeLeverlImage.rotation = Math.PI / 180 * - 30
gsap.to(bikeLeverlImage, { duration: 0.6, rotation: Math.PI / 180 * - 30 })
pause()
})
actionButton.on("mouseup", () => {
// bikeLeverlImage.rotation = 0;
gsap.to(bikeLeverlImage, { duration: .6, rotation: 0 })
start()
})
对应的开始,暂停
app.ticker
PIXI.Ticker 计时器,可理解为每次渲染一帧前执行。
function start() {
speed = 0
}
function pause() {
gsap.ticker.remove(loop)
}
粒子运动效果
粒子运动特点:
- 粒子的粒子有多个颜色
- 粒子向某个角度持续移动
- 超出边界后回到顶部持续移动
- 按住鼠标停止
- 停止的时候还有回弹效果
- 松开鼠标继续
创建一块画布,粒子的运动轨迹是某个角度的持续运动,可以设置画布旋转一定的角度,从而实现粒子的固定角度运动
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 = [0xf1c54, 0xb5cea8, 0xf1cf54, 0x818181, 0x000000]
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() * innerWidth,
sy: Math.random() * innerHeight,
gr: gr
}
gr.x = pItem.sx;
gr.y = pItem.sy;
particleContainer.addChild(gr)
particles.push(pItem);
}
- 粒子的运动轨迹
- 下面就是粒子如何运动
- 初始速度为0
- 粒子开始运动时不是无限加速,加速到一定上限后,不再加速
- 运动超出显示区域后,粒子回归初始位置0
tip
pItem.gr.scale.y = 40
pItem.gr.scale.x = 0.03 通过设置高速模式下粒子的运动样式,展示动态情况下的效果
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.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: 'elastice.out' })
}
}
结尾:
附上源码地址YCY-TrainingCamp-S1
在公众号里搜 大帅老猿
,他做技术外包很靠谱