背景
加入猿创营(大帅老猿
)有一段时间了,群内创业、兼职、学习氛围很浓,感谢大帅及群友的很多学习案例分享。为了加强学习,同时也想跟大家学习如何多输出。借助本次'第一届猿创营摸金群全员实训'机会,经过1、2天的学习,把学习到的做一个小结,希望可以帮到还未入门的同学。
本次视觉动效最终效果图
所用框架(知识)
1. Pixi (资源加载及构建,渲染)
2. Gsap (动效)
本例包含元素
1. 车
2. 按钮
3. 路
4. 运动线条
所用素材
1. 主车架图
2. 操纵杆图
3. 刹车把手图
4. 按钮图
5. 圆圈图
构建开始
1.创建一个html文件,引入pixi及gsap的js文件,如下:
<script src="https://pixijs.download/release/pixi.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.4/gsap.min.js"></script>
2.创建一个dom容器,如下:
<div id="brakebanner"></div>
设置宽度及居中背景css:
<style>
#brakebanner {
width: 1000px;
margin: 0 auto;
background-color: #f8f8f8;
}
</style>
3.写js脚本, 全部js逻辑及注释
<script>
/**
* 1.>创建Pixi应用和stage(舞台: 特殊Pixi容器对象, 该舞台对象将根容器来保存您希望Pixi显示的东西。)
*
* 如果您需要修改Pixi的默认配置,请参阅Pixi.application文档。
*
* 要更改画布的大小,请使用renderer的resize方法,并提供任何新的width和height值。
* 但是,为了确保画布的大小调整到与分辨率匹配,请将autoResize设置为true。
*
* 本例使用固定高度 宽度. (可以参考官方文档实现自适应控制)
*
* 详细介绍: 请参阅[官方文档](https://pixijs.io): https://pixijs.io
*
* @type {PIXI.Application}
*/
let app = new PIXI.Application({
width: 1000,
height: 1000
})
/**
* 设置应用背景色(格式: 0x标识的16进制颜色值, 区别css使用#开头的颜色值)
* @type {number}
*/
app.renderer.backgroundColor = 0xf2f2f2
/**
* 将Pixi自动为您创建的画布添加到HTML文档中
*/
document.getElementById("brakebanner").appendChild(app.view)
/**
* 使用Pixi的Sprite类来创建精灵
*
* 创建方法有三种:
* 通过单个图像文件。(本文使用该种方法创建)
* 通过雪碧图。
* 通过纹理贴图。
*
* sprite(精灵)是一种的特殊图像对象。您可以控制它们的位置、大小和其他属性。
* 学习制作和控制sprite(精灵)非常重要。
*/
//按钮图片精灵
let spriteBtn = PIXI.Sprite.from('./images/btn.png');
//圆圈精灵
let spriteBtnCircle = PIXI.Sprite.from('./images/btn_circle.png');
//自行车精灵
let spriteBrakeBike = PIXI.Sprite.from('./images/brake_bike.png');
//控制杆精灵
let spriteBrakeHandlerbar = PIXI.Sprite.from('./images/brake_handlerbar.png');
//刹车把精灵
let spriteBrakeLever = PIXI.Sprite.from('./images/brake_lever.png');
//由于图片太大, 这里进行了缩放
spriteBtn.scale.x = spriteBtn.scale.y = 0.5;
spriteBtnCircle.scale.x = spriteBtnCircle.scale.y = 0.5;
spriteBrakeBike.scale.x = spriteBrakeBike.scale.y = 0.2;
spriteBrakeHandlerbar.scale.x = spriteBrakeHandlerbar.scale.y = 0.2;
spriteBrakeLever.scale.x = spriteBrakeLever.scale.y = 0.2;
//调整刹车把的位置, (这里设置了固定位置)
spriteBrakeLever.x = 170;
spriteBrakeLever.y = 190;
/**
* 自行车容器 - 将车, 控制杆, 刹车把放在该容器
* @type {PIXI.Container}
*/
let bikeContainer = new PIXI.Container();
bikeContainer.addChild(spriteBrakeBike);
bikeContainer.addChild(spriteBrakeLever);
bikeContainer.addChild(spriteBrakeHandlerbar);
//设置该容器的位置
bikeContainer.x = bikeContainer.y = 300;
/**
* 按钮容器 - 将按钮, 圆圈放在该容器
* @type {PIXI.Container}
*/
const btnContainer = new PIXI.Container();
btnContainer.addChild(spriteBtn);
btnContainer.addChild(spriteBtnCircle);
//设置该容器位置
btnContainer.x = -50 + app.screen.width / 2;
btnContainer.y = -120 + app.screen.width / 2;
//设置按钮位置
spriteBtn.x = 9 ;
spriteBtn.y = 9 ;
//设置圆圈位置
spriteBtnCircle.x = 0;
spriteBtnCircle.y = 0;
//创建一个红点
let circleRed = new PIXI.Graphics();
circleRed.beginFill(0xFF0000);
circleRed.drawCircle(0, 0, 4);
circleRed.endFill();
circleRed.x = 150;
circleRed.y = 0;
//创建一个绿点
let circleGreen = new PIXI.Graphics();
circleGreen.beginFill(0x008000);
circleGreen.drawCircle(0, 0, 4);
circleGreen.endFill();
circleGreen.x = 250;
circleGreen.y = 0;
//创建一个橘色点
let circleOrange = new PIXI.Graphics();
circleOrange.beginFill(0xFFA500);
circleOrange.drawCircle(0, 0, 4);
circleOrange.endFill();
circleOrange.x = 350;
circleOrange.y = 0;
/**
* 绘制一个矩形图形作为路
* 作为路容器 - 将创建的三个点(用来实现运动路线效果)放在该容器
* @type {PIXI.Container}
*/
let rectangleRoad = new PIXI.Graphics();
rectangleRoad.lineStyle(4, 0x008000, 1);
rectangleRoad.beginFill(0xcccccc);
rectangleRoad.drawRect(0, 0, 500, 2000);
rectangleRoad.endFill();
//将路移到中心
rectangleRoad.x = app.screen.width / 2;
rectangleRoad.y = app.screen.height / 2;
//设置路的旋转中心
rectangleRoad.pivot.x = rectangleRoad.width / 2;
rectangleRoad.pivot.y = rectangleRoad.height / 2;
//旋转路
rectangleRoad.rotation = (35 * Math.PI) / 180;
//加入三个点到路
rectangleRoad.addChild(circleRed);
rectangleRoad.addChild(circleGreen);
rectangleRoad.addChild(circleOrange);
//加入舞台
app.stage.addChild(rectangleRoad); //公路
app.stage.addChild(bikeContainer); //车容器
app.stage.addChild(btnContainer); //按钮容器
/**
* 锚点设置刹车把精灵的原点。
*
* 默认值是(0,0),这意味着精灵的原点是左上角。
* 将锚点设置为(0.5,0.5)意味着精灵的原点在中间。
* 将锚点设置为(1,1)意味着精灵的原点将是右下角。(本例设置右下角作为旋转的原点)
* @type {number}
*/
spriteBrakeLever.anchor.x = 1
spriteBrakeLever.anchor.y = 1
/**
* 为按钮精灵启用交互事件。
* 除非interactive设置为true,否则不会发出触摸、指针和鼠标事件。
* @type {boolean}
*/
spriteBtn.interactive = true;
spriteBtn.buttonMode = true;
/**
* 为按钮绑定, 按下鼠标, 放开鼠标事件
*/
spriteBtn.on('mousedown', onMusedown)
spriteBtn.on('mouseup', onMuseup)
/**
* 在按钮上按下鼠标时 - 事件处理逻辑
* @param e
*/
function onMusedown(e) {
//刹车把的动作动画
gsap.to(spriteBrakeLever, {
duration: 0.6,
rotation: (Math.PI / 180) * -30,
});
//停止运动轨迹函数
gsap.ticker.remove(gameLoop)
//停止后, 点恢复成初始圆点
circleRed.scale.y = 1
circleRed.scale.x = 1
circleGreen.scale.y = 1
circleGreen.scale.x = 1
circleOrange.scale.y = 1
circleOrange.scale.x = 1
}
/**
* 在按钮上松开鼠标时 - 事件处理逻辑
* @param e
*/
function onMuseup(e) {
//刹车把的动作动画
gsap.to(spriteBrakeLever, {
duration: 0.6,
rotation: 0,
});
//初始速度0
speed = 0;
//开始运动轨迹函数
gsap.ticker.add(gameLoop)
}
//运行速度初始值
let speed = 0.0;
/**
* 运动效果处理函数
*/
function gameLoop(){
speed += 0.5;
speed = Math.min(speed, 80);
//速度达到80时, 修改点的x,y 显示为线条样式的运动轨迹
if(speed == 80) {
circleRed.scale.y = 10
circleRed.scale.x = 0.1
circleGreen.scale.y = 10
circleGreen.scale.x = 0.1
circleOrange.scale.y = 10
circleOrange.scale.x = 0.1
}
console.log("es=", speed)
//增加y坐标值, 模拟运动轨迹
if(circleRed) circleRed.y += speed
if(circleGreen) circleGreen.y += speed
if(circleOrange) circleOrange.y += speed
//点运动到,y轴2000后, 重置y坐标值
if(circleRed.y > 2000 ) {
circleRed.y = 0
circleGreen.y = 0
circleOrange.y = 0
}
}
/**
* 初始运行, 运动效果
*/
gsap.ticker.add(gameLoop)
</script>
资源
1. PIXI官网:pixijs.com/
2. PIXI中文:pixijs.huashengweilai.com/
3. GSAP:greensock.com/docs/v3/GSA…
4. 案例地址:www.vanmoof.com/en-NL/s3?co…
5. 代码地址: github.com/freewl/YCY-TrainingCamp-S1
不足
1. 本文为零基础入门系列, 流水账式代码结构, 仅供学习参考与模仿
2. 动画处理不够细腻, 但是作为入门学习足够, 如果您感兴趣,可以添加更多逻辑及高级功能.
作业
1. 详细阅读Pixi及Gsap文档, sample及api文档. 深入了解每个对象及方法等的用法
2. 增加按钮动画效果
3. 增加车的动画效果(运动后停止的那刻,给车加个动画效果)
4. 封装代码, 将部分代码封装共用及提高代码结构与逻辑
号外
在公众号里搜 大帅老猿
,在他这里可以学到很多东西