初次使用PIXI+GSAP来做动画效果还不错,之前很少做比较复杂的动画类的东西,这次学习了
- 这是PIXI的官网 pixijs.com/
- 这是GSAP的官网 greensock.com/docs/v3/GSA…
官网因为是英文的 可能不太友好,中文的官网没有,但是有些辅助的资料,大家可以看一下,但是最终还是要自己多去写demo练一练才能熟练起来
这是实现之后的效果
我们边学边熟悉一下PIXI的api和GSAP的api
首先我们需要用PIXI创建一块画布
this.app = new PIXI.Application({
width: window.innerWidth, // 这是画布的宽
height: window.innerHeight, // 画布的高
backgroundColor: 0xffffff // 画布的底色
})
我先介绍一下我们这次会用到的api
this.stage = this.app.stage // 是相当于页面 我们需要把我们画的图片、图形全部挂到上面才能显示出来
this.loader = new PIXI.Loader() // 是一个加载器,是加载解析图片的一些信息,方便我们去使用
this.loader.add("btn.png", 'images/btn.png') // 这是把需要加载图片添加到里面进行解析 第一个参数是key,第两个参数是图片地址,
this.loader.load() // 对添加的图片进行解析
this.loader.onComplete.add(()=>{
show()
}) // 图片解析完进行的回调函数
new PIXI.Container() // 新建一个容器 可以把你认为是一组的写在里面
this.loader.resources['btn.png'].texture // 图片加载解析完成,当我们需要对应的key的信息的时候就需要使用这种方式,texture属性里是图片的信息
let btn= new PIXI.Sprite(this.loader.resources['btn.png'].texture) // 新建一个精灵 只有通过这个画出来的图片才能添加到stage上,并且显示出来 第一次参数是图片的信息,有个图片信息精灵就可以画出来了
this.stage.addChild(btn) // 这个方法是把容器或者 新创建的精灵添加到 stage 显示
btn.pivot.x和y 是设置这个图片的圆心点坐标的
btn.x和y 是设置距离的
btn.interactive = true 让相对应的图可以添加监听事件
show方法
show() {
let { bikeLeverImage } = this.createbike()
let actionButton = this.createActionBtn()
let { start,pause } = this.createl()
actionButton.on('mousedown', () => {
gsap.to(bikeLeverImage, { duration: 0.6, rotation: Math.PI / 180 * -30 })
pause()
})
actionButton.on('mouseup', () => {
// bikeLeverImage.rotation = Math.PI / 180 * 0
gsap.to(bikeLeverImage, { duration: 0.6, rotation: Math.PI / 180 * 0 })
start()
})
}
对上面实现的效果进行分解 按键应该是一起的
这是实现按键的方法
难点主要是需要实现按键的波纹动画效果
createActionBtn() {
// 这个这两个图片是一起的 所以应该放到一个容器里 进行统一管理
let actionButton = new PIXI.Container()
this.stage.addChild(actionButton)
let btnImage = new PIXI.Sprite(this.loader.resources['btn.png'].texture)
actionButton.addChild(btnImage)
let circle = new PIXI.Sprite(this.loader.resources['btn_circle'].texture)
actionButton.addChild(circle)
let circle2 = new PIXI.Sprite(this.loader.resources['btn_circle'].texture)
actionButton.addChild(circle2)
btnImage.pivot.x = btnImage.pivot.y = btnImage.width / 2
circle.pivot.x = circle.pivot.y = circle.width / 2
circle2.pivot.x = circle2.pivot.y = circle2.width / 2
actionButton.x = actionButton.y = 300
circle.scale.x = circle.scale.y = 0.8
// gsas是动画效果的插件 repeat: -1 是循环
// 这个动画是实现按键的波纹效果的
gsap.to(circle.scale, { duration: 1, x: 1.3, y: 1.3, repeat: -1 }) //
gsap.to(circle, { duration: 1, alpha: 0, repeat: -1 })
// 可以添加监听事件
actionButton.interactive = true
actionButton.buttonMode = true
return actionButton
}
建立一个自行车方法
createbike() {
// 新建一个车架容器
let bikeContainer = new PIXI.Container()
bikeContainer.scale.x = bikeContainer.scale.y = 0.3
this.stage.addChild(bikeContainer)
let bikeImage = new PIXI.Sprite(this.loader.resources['brake_bike'].texture)
bikeContainer.addChild(bikeImage)
// 把手
let bikeLeverImage = new PIXI.Sprite(this.loader.resources['brake_lever'].texture)
bikeContainer.addChild(bikeLeverImage)
bikeLeverImage.pivot.x = 455
bikeLeverImage.pivot.y = 455
bikeLeverImage.x = 722
bikeLeverImage.y = 900
let brakeHandlerbar = new PIXI.Sprite(this.loader.resources['brake_handlerbar'].texture)
bikeContainer.addChild(brakeHandlerbar)
return { bikeImage, bikeLeverImage, brakeHandlerbar }
}
第二步需要建立车架及车把 难点主要是 刹车效果
// 按键的事件卸载了show方法里
createbike() {
// 新建一个车架容器
let bikeContainer = new PIXI.Container()
bikeContainer.scale.x = bikeContainer.scale.y = 0.3
this.stage.addChild(bikeContainer)
let bikeImage = new PIXI.Sprite(this.loader.resources['brake_bike'].texture)
bikeContainer.addChild(bikeImage)
let bikeLeverImage = new PIXI.Sprite(this.loader.resources['brake_lever'].texture)
bikeContainer.addChild(bikeLeverImage)
bikeLeverImage.pivot.x = 455
bikeLeverImage.pivot.y = 455
bikeLeverImage.x = 722
bikeLeverImage.y = 900
let brakeHandlerbar = new PIXI.Sprite(this.loader.resources['brake_handlerbar'].texture)
bikeContainer.addChild(brakeHandlerbar)
return { bikeImage, bikeLeverImage, brakeHandlerbar }
}
第三步 我们需要建立粒子 并且粒子需要向30度移动
createl() {
这是我们画粒子的思路
// 向某一个角度持续移动
// gsap.ticker.add(loop) // gsap添加了一个监听事件
// 超出边界后回到顶部继续移动
// 按住鼠标停止移动
// 停止有回弹效果
// 松开鼠标继续
// 创建粒子
let particleContainer = new PIXI.Container();
this.stage.addChild(particleContainer)
// 修改圆心坐标
particleContainer.pivot.x = window.innerWidth / 2
particleContainer.pivot.y = window.innerHeight / 2
// 旋转粒子容器
particleContainer.rotation = 30 * Math.PI / 180
let particles = []
// 粒子有多个颜色
let colors = [0xf1cf54, 0xb5cea8, 0xf1cf54, 0x818f54, 0xb5cea8]
for (let i = 0; i < 10; i++) {
let gr = new PIXI.Graphics(); // 相当于canvas的getContext("2d") 就是一个画笔
gr.beginFill(colors[Math.floor(Math.random() * colors.length)])
gr.drawCircle(0, 0, 6)
gr.endFill()
let aitem = {
sx: Math.random() * window.innerWidth,
sy: Math.random() * window.innerHeight,
gr: gr,
}
gr.x = aitem.sx
gr.y = aitem.sy
particleContainer.addChild(gr)
particles.push(aitem)
}
let speed = 0
// 用gsap创建一个循环
function loop() {
speed += .5
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 = 40
pItem.gr.scale.x = 0.04
}
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++) {
let pItem = particles[i]
pItem.gr.scale.y = 1
pItem.gr.scale.x = 1
gsap.to(pItem.gr,{ duration:1,x: pItem.sx,y: pItem.sy,ease: "elastic" })
}
}
start()
return {
start,pause
}
}
上面动态图就是实现的效果
在公众号里搜 大帅老猿,在他这里可以学到很多东西