Waft容器 1.6+
Waft前端框架 0.7+
Lottie 是一个用于 Web 和 iOS、Android 的移动库,可使用 Bodymovin 解析以 JSON 格式导出的 Adobe After Effects 动画,并将其本地呈现在移动设备上。以下为 Lottie 动画库适配Waft的方法。有关 Lottie 的详细信息请参见 Lottie 官方文档 和 Lottie 官方支持能力列表。
组件演示
axml
<div class="warpper">
<x-nav-bar showArrow="{{true}}" title="Lottie"></x-nav-bar>
<div class="container">
<div class="buttons">
<div class="button" onTap="autoPlay">点击切换autoPlay</div>
<div class="button" onTap="pause">点击切换pause</div>
<div class="button" onTap="resume">点击切换resume</div>
<div class="button" onTap="stop">点击切换stop</div>
<div class="button" onTap="play">点击切换play</div>
<div class="button" onTap="repeatCount">点击切换repeatCount</div>
</div>
<div class="tip">
<div>属性信息:</div>
<div class="tip-content">
<div class="flex">autoPlay(是否自动开始播放):<text class="text">{{autoPlay}}</text></div>
<div class="flex">path(Lottie 资源地址): <text class="text">{{path}}</text></div>
<div class="flex">repeatCount(循环次数): <text class="text">{{repeatCount}}</text></div>
<div class="flex">play(开始播放,从第一帧开始播放): <text class="text">{{play}}</text></div>
<div class="flex">pause(暂停播放,停留在当前帧): <text class="text">{{pause}}</text></div>
<div class="flex">resume(继续播放,从暂停时的帧继续播放): <text class="text">{{resume}}</text></div>
<div class="flex">stop(停止播放,强制跳到最后一帧结束): <text class="text">{{stop}}</text></div>
<div class="flex">onDataReady(数据下载、解析成功): <text class="text">{{onDataReady}}</text></div>
<div class="flex">onDataFailed(数据加载失败): <text class="text">{{onDataFailed}}</text></div>
<div class="flex">onAnimationStart(动画开始时触发): <text class="text">{{onAnimationStart}}</text></div>
<div class="flex">onAnimationEnd(动画结束时触发): <text class="text">{{onAnimationEnd}}</text></div>
<div class="flex">onAnimationRepeat(动画一次重播结束): <text class="text">{{onAnimationRepeat}}</text></div>
</div>
</div>
<lottie
a:if="{{lottie}}"
class="lottie"
id="myLottie"
play="{{play}}"
pause="{{pause}}"
resume="{{resume}}"
stop="{{stop}}"
onDataReady="onDataReady"
onDataFailed="onDataFailed"
onAnimationStart="onAnimationStart"
onAnimationEnd="onAnimationEnd"
onAnimationRepeat="onAnimationRepeat"
autoPlay="{{autoPlay}}"
path="{{path}}"
repeatCount="{{repeatCount}}"
>
</lottie>
</div>
</div>
css
.warpper {
background-color:#fff;
width:100%;
height:100%;
display:flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.container{
flex: 1;
color: #999;
line-height: 30rpx;
font-size: 16rpx;
}
.flex{
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
}
.buttons{
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
flex-wrap: wrap;
padding: 10rpx;
}
.button{
margin-bottom: 10rpx;
margin-right: 20rpx;
padding-left: 10rpx;
padding-right: 10rpx;
border-radius: 8rpx;
background-color: #ccc;
}
.tip{
background-color: #25b864;
color: #fff;
padding: 20rpx;
margin: 10rpx;
}
.tip-content{
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
flex-wrap: wrap;
}
.tip-content div{
width: 50%;
}
.text{
color: #f73131;
}
.lottie{
width: 80vw;
height: 150rpx;
margin-left: 10vw;
border: 1rpx solid red;
}
ts
import { JSON, JSONArray, JSONObject } from "waft-json";
import { console, getDataSource, Page, Props, WaftBridge, MessageEvent, setTimeout, document, LottieElement } from "waft";
let _this: Index;
export class Index extends Page {
constructor(props: Props){
super(props);
_this = this;
// 设置默认的state
this.setState(getDataSource());
this.addEventListener('play', () => {
console.log('=============onPlay==================')
const newState = new JSONObject;
newState.set('play', '点击了play按钮')
newState.set('stop', '')
newState.set('pause', '')
newState.set('resume', '')
_this.setState(newState)
const props = new JSONArray();
props.push(document.querySelector("#myLottie").props.componentId);
WaftBridge.call("render.component.lottie", "play", props.toString());
})
this.addEventListener('pause', () => {
console.log('=============pause==================')
const newState = new JSONObject;
newState.set('pause', "点击了pause按钮")
newState.set('play', "")
newState.set('stop', "")
newState.set('resume', "")
_this.setState(newState)
const props = new JSONArray();
props.push(document.querySelector("#myLottie").props.componentId);
WaftBridge.call("render.component.lottie", "pause", props.toString());
})
this.addEventListener('stop', () => {
console.log('=============stop==================')
const newState = new JSONObject;
newState.set('stop', "点击了stop按钮")
newState.set('pause', "")
newState.set('play', "")
newState.set('resume', "")
_this.setState(newState)
const props = new JSONArray();
props.push(document.querySelector("#myLottie").props.componentId);
WaftBridge.call("render.component.lottie", "stop", props.toString());
})
this.addEventListener('resume', () => {
console.log('=============resume==================')
const newState = new JSONObject;
newState.set('play', '')
newState.set('pause', '')
newState.set('stop', '')
newState.set('resume', '点击了resume按钮')
_this.setState(newState)
const props = new JSONArray();
props.push(document.querySelector("#myLottie").props.componentId);
WaftBridge.call("render.component.lottie", "resume", props.toString());
})
this.addEventListener('autoPlay', () => {
console.log('=============autoPlay==================')
const newState = new JSONObject;
newState.set('lottie', false)
newState.set('play', '')
newState.set('pause', '')
newState.set('stop', '')
newState.set('onDataReady', '')
newState.set('onDataFailed', '')
newState.set('onAnimationStart', '')
newState.set('onAnimationEnd', '')
newState.set('onAnimationRepeat', '')
_this.setState(newState)
setTimeout(() => {
const autoPlay = _this.state.getBool('autoPlay')
const _newState = new JSONObject;
_newState.set('autoPlay', !autoPlay)
_newState.set('lottie', true)
_this.setState(_newState)
}, 10)
})
this.addEventListener('repeatCount', () => {
console.log('=============repeatCount==================')
const repeatCount = _this.state.getInteger('repeatCount')
const newState = new JSONObject;
newState.set('lottie', false)
newState.set('play', '')
newState.set('pause', '')
newState.set('stop', '')
newState.set('repeatCount', '')
newState.set('onDataReady', '')
newState.set('onDataFailed', '')
newState.set('onAnimationStart', '')
newState.set('onAnimationEnd', '')
newState.set('onAnimationRepeat', '')
newState.set('repeatCount', repeatCount>3?-1:repeatCount+1)
_this.setState(newState)
setTimeout(() => {
const _newState = new JSONObject;
_newState.set('lottie', true)
_this.setState(_newState)
}, 10)
})
this.addEventListener('onDataReady', (event) => {
console.log('=============onDataReady==================')
const newState = new JSONObject;
newState.set('onDataReady', ' 被触发')
newState.set('onDataFailed', '')
newState.set('onAnimationStart', '')
newState.set('onAnimationEnd', '')
newState.set('onAnimationRepeat', '')
_this.setState(newState)
})
this.addEventListener('onDataFailed', (event) => {
console.log('=============onDataFailed==================')
const newState = new JSONObject;
newState.set('onDataReady', '')
newState.set('onDataFailed', ' 被触发')
newState.set('onAnimationStart', '')
newState.set('onAnimationEnd', '')
newState.set('onAnimationRepeat', '')
_this.setState(newState)
})
this.addEventListener('onAnimationStart', (event) => {
console.log('=============onAnimationStart==================')
const newState = new JSONObject;
newState.set('onDataReady', '')
newState.set('onDataFailed', '')
newState.set('onAnimationStart', ' 被触发')
newState.set('onAnimationEnd', '')
newState.set('onAnimationRepeat', '')
_this.setState(newState)
})
this.addEventListener('onAnimationEnd', (event) => {
console.log('=============onAnimationEnd==================')
const newState = new JSONObject;
newState.set('onDataReady', '')
newState.set('onDataFailed', '')
newState.set('onAnimationStart', '')
newState.set('onAnimationEnd', ' 被触发')
newState.set('onAnimationRepeat', '')
_this.setState(newState)
})
this.addEventListener('onAnimationRepeat', (event) => {
console.log('=============onAnimationRepeat==================')
const newState = new JSONObject;
newState.set('onDataReady', '')
newState.set('onDataFailed', '')
newState.set('onAnimationStart', '')
newState.set('onAnimationEnd', '')
newState.set('onAnimationRepeat', ' 被触发')
_this.setState(newState)
})
}
onShow(): void{
// 页面显示
console.log('page onShow');
}
onLoad(query: JSONObject): void{
// 页面加载后
console.log('page onLoad:' + JSON.stringify(query));
}
onMessage(event: MessageEvent): void{
// 信息推送更新
console.log('page onMessage:' + JSON.stringify(event.data));
}
}
属性
属性 | 必填 | 描述 |
---|---|---|
autoplay | false | 是否自动播放。 默认值:false |
path | true | Lottie 资源地址。包含近端(包内地址)和远端(网络)的 JSON 文件地址。 参考:https://ailabs-iot.aligenie.com/waft-assets/call_anim_1.json |
repeatCount | false | 循环次数。 - 如果是负数表示无限次。 - 如果是 0 表示不循环,播放一次。 - 如果是 1 表示循环一次,播放两次。 |
默认值:0 |
API
调用方式
API | 参数 | 描述 |
---|---|---|
play | / | 开始播放,从第一帧开始播放 |
pause | / | 暂停播放,停留在当前帧 |
resume | / | 继续播放,从暂停时的帧继续播放 |
stop | / | 停止播放,强制跳到最后一帧结束 |
事件
onDataReady | 数据下载、解析成功 |
---|---|
onDataFailed | 数据加载失败 |
onAnimationStart | 动画开始时触发 |
onAnimationEnd | 动画结束时触发 |
onAnimationRepeat | 动画一次重播结束 |
限制
- 收到 onDataReady 事件以后才能调用 Lottie 组件的 API,不然无效
- Lottie 的资源不能包含本地图片路径,如果需要包含图片,需要用 base64 或者 svg 编码的
lottie
资源格式{"id":"image_0","w":66,"h":89,"u":"","p":"data:image/png;base64..."}
格式参考:
https://ailabs-iot.aligenie.com/waft-assets/call_anim_1.json