tm-lottie.vue 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. <template>
  2. <view :key="cKey" class="tm-lottie flex-center">
  3. <!-- #ifndef H5 -->
  4. <canvas :style="{ width: w_w + 'px', height: h_h + 'px' }" id="cid" canvas-id="cid" class="cid"></canvas>
  5. <!-- #endif -->
  6. <!-- #ifdef H5 -->
  7. <canvas :style="{ width: w_w + 'px', height: h_h + 'px' }" :id="cuid" :canvas-id="cuid"></canvas>
  8. <!-- #endif -->
  9. </view>
  10. </template>
  11. <script>
  12. import lottie from 'tm-vuetify/tool/function/lottie.js';
  13. export default {
  14. name: 'tm-lottie',
  15. props: {
  16. width: {
  17. type: Number | String,
  18. default: 420
  19. },
  20. height: {
  21. type: Number | String,
  22. default: 420
  23. },
  24. url: {
  25. type: String||Object,
  26. default: ()=>{
  27. return "";
  28. }
  29. },
  30. loop: {
  31. type: Boolean,
  32. default: true
  33. },
  34. autoplay: {
  35. type: Boolean,
  36. default: true
  37. }
  38. },
  39. computed: {
  40. w_w: function() {
  41. return uni.upx2px(this.width);
  42. },
  43. h_h: function() {
  44. return uni.upx2px(this.height);
  45. }
  46. },
  47. data() {
  48. return {
  49. cuid: 'cid',
  50. cKey: ''
  51. };
  52. },
  53. created() {
  54. // #ifdef H5
  55. this.cuid = this.$tm.guid();
  56. // #endif
  57. this.cKey = this.$tm.guid();
  58. },
  59. destroyed() {
  60. // 释放内存。
  61. lottie.destroy()
  62. },
  63. async mounted() {
  64. if (this.url) {
  65. this.$nextTick(async function() {
  66. await this.LoadLottiePlay_Mp();
  67. });
  68. }
  69. },
  70. methods: {
  71. async LoadLottiePlay_Mp(url) {
  72. const canvasContext = uni.createCanvasContext(this.cuid, this);
  73. // #ifdef MP-WEIXIN || MP-ALIPAY
  74. // let canvas = await this.getNodeCanvasNodeRef();
  75. // console.log(canvas);
  76. // #endif
  77. // 请求到的lottie json数据
  78. let animationData=null
  79. // 请求lottie的路径。注意开启downloadFile域名并且返回格式是json
  80. const animationPath = url || this.url;// url || this.url
  81. if(typeof animationPath ==='string'&&animationPath!=''){
  82. let p = await this.rloadJson(animationPath).catch(e=>{
  83. uni.$tm.toast(JSON.stringify(e));
  84. })
  85. animationData = JSON.parse(p.data.data)
  86. }else{
  87. animationData = url;
  88. }
  89. if(!animationData) return;
  90. // 指定canvas大小
  91. canvasContext.canvas = {
  92. width: this.w_w,
  93. height: this.h_h
  94. };
  95. try {
  96. // 如果同时指定 animationData 和 path, 优先取 animationData
  97. lottie.loadAnimation({
  98. renderer: 'canvas', // 只支持canvas
  99. loop: this.loop,
  100. autoplay: this.autoplay,
  101. animationData: animationData,
  102. path: '',
  103. rendererSettings: {
  104. context: canvasContext,
  105. clearCanvas: true
  106. }
  107. });
  108. } catch (e) {
  109. console.log(e);
  110. }
  111. },
  112. //mp alipay
  113. getNodeCanvasNodeRef(){
  114. return new Promise((resolve,reject)=>{
  115. const query = uni.createSelectorQuery().in(this)
  116. query
  117. .select('.cid')
  118. .fields({ node: true, size: true })
  119. .exec(res => {
  120. console.log(res);
  121. const canvasNode = res[0].node
  122. const canvasDpr = uni.getSystemInfoSync().pixelRatio
  123. const canvasWidth = res[0].width
  124. const canvasHeight = res[0].height
  125. const ctx = canvasNode.getContext('2d')
  126. resolve(ctx,{dpr:canvasDpr,width:canvasWidth,height:canvasHeight,node:canvasNode});
  127. })
  128. })
  129. },
  130. async LoadLottiePlay_H5(url) {
  131. const canvasContext = uni.createCanvasContext(this.cuid, this);
  132. // 请求到的lottie json数据
  133. let animationData=null
  134. // 请求lottie的路径。注意开启downloadFile域名并且返回格式是json
  135. const animationPath = url || this.url;// url || this.url
  136. // 指定canvas大小
  137. canvasContext.canvas = {
  138. width: this.w_w,
  139. height: this.h_h
  140. };
  141. try {
  142. // 如果同时指定 animationData 和 path, 优先取 animationData
  143. lottie.loadAnimation({
  144. renderer: 'canvas', // 只支持canvas
  145. loop: this.loop,
  146. autoplay: this.autoplay,
  147. animationData: '',
  148. path: animationPath,
  149. rendererSettings: {
  150. context: canvasContext,
  151. clearCanvas: true
  152. }
  153. });
  154. } catch (e) {
  155. console.log(e);
  156. }
  157. },
  158. play() {
  159. lottie.play();
  160. },
  161. stop() {
  162. lottie.stop();
  163. },
  164. pause() {
  165. lottie.pause();
  166. },
  167. rloadJson(url){
  168. return new Promise((res,rej)=>{
  169. uni.request({
  170. responseType:'json',
  171. url:url,
  172. success: (v) => {
  173. res(v)
  174. },
  175. fail: (e) => {
  176. console.log(e);
  177. rej(e)
  178. }
  179. })
  180. })
  181. },
  182. // type:1正向播放,-1反向
  183. setDirection(type = 1) {
  184. lottie.setDirection(type);
  185. },
  186. async registerAnimation(url) {
  187. if (!url) return;
  188. lottie.destroy();
  189. this.cKey = this.$tm.guid();
  190. await this.LoadLottiePlay_Mp(url);
  191. lottie.resize();
  192. }
  193. }
  194. };
  195. </script>
  196. <style lang="scss"></style>