Waft容器 1.6+ Waft前端框架 0.7+

Lottie 是一个用于 Web 和 iOS、Android 的移动库,可使用 Bodymovin 解析以 JSON 格式导出的 Adobe After Effects 动画,并将其本地呈现在移动设备上。以下为 Lottie 动画库适配Waft的方法。有关 Lottie 的详细信息请参见 Lottie 官方文档Lottie 官方支持能力列表

组件演示

screenshot.png

axml

  1. <div class="warpper">
  2. <x-nav-bar showArrow="{{true}}" title="Lottie"></x-nav-bar>
  3. <div class="container">
  4. <div class="buttons">
  5. <div class="button" onTap="autoPlay">点击切换autoPlay</div>
  6. <div class="button" onTap="pause">点击切换pause</div>
  7. <div class="button" onTap="resume">点击切换resume</div>
  8. <div class="button" onTap="stop">点击切换stop</div>
  9. <div class="button" onTap="play">点击切换play</div>
  10. <div class="button" onTap="repeatCount">点击切换repeatCount</div>
  11. </div>
  12. <div class="tip">
  13. <div>属性信息:</div>
  14. <div class="tip-content">
  15. <div class="flex">autoPlay(是否自动开始播放):<text class="text">{{autoPlay}}</text></div>
  16. <div class="flex">path(Lottie 资源地址): <text class="text">{{path}}</text></div>
  17. <div class="flex">repeatCount(循环次数): <text class="text">{{repeatCount}}</text></div>
  18. <div class="flex">play(开始播放,从第一帧开始播放): <text class="text">{{play}}</text></div>
  19. <div class="flex">pause(暂停播放,停留在当前帧): <text class="text">{{pause}}</text></div>
  20. <div class="flex">resume(继续播放,从暂停时的帧继续播放): <text class="text">{{resume}}</text></div>
  21. <div class="flex">stop(停止播放,强制跳到最后一帧结束): <text class="text">{{stop}}</text></div>
  22. <div class="flex">onDataReady(数据下载、解析成功): <text class="text">{{onDataReady}}</text></div>
  23. <div class="flex">onDataFailed(数据加载失败): <text class="text">{{onDataFailed}}</text></div>
  24. <div class="flex">onAnimationStart(动画开始时触发): <text class="text">{{onAnimationStart}}</text></div>
  25. <div class="flex">onAnimationEnd(动画结束时触发): <text class="text">{{onAnimationEnd}}</text></div>
  26. <div class="flex">onAnimationRepeat(动画一次重播结束): <text class="text">{{onAnimationRepeat}}</text></div>
  27. </div>
  28. </div>
  29. <lottie
  30. a:if="{{lottie}}"
  31. class="lottie"
  32. id="myLottie"
  33. play="{{play}}"
  34. pause="{{pause}}"
  35. resume="{{resume}}"
  36. stop="{{stop}}"
  37. onDataReady="onDataReady"
  38. onDataFailed="onDataFailed"
  39. onAnimationStart="onAnimationStart"
  40. onAnimationEnd="onAnimationEnd"
  41. onAnimationRepeat="onAnimationRepeat"
  42. autoPlay="{{autoPlay}}"
  43. path="{{path}}"
  44. repeatCount="{{repeatCount}}"
  45. >
  46. </lottie>
  47. </div>
  48. </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