tm-lottie.vue 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  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. console.log(animationData)
  89. }
  90. if(!animationData) return;
  91. // 指定canvas大小
  92. canvasContext.canvas = {
  93. width: this.w_w,
  94. height: this.h_h
  95. };
  96. try {
  97. // 如果同时指定 animationData 和 path, 优先取 animationData
  98. lottie.loadAnimation({
  99. renderer: 'canvas', // 只支持canvas
  100. loop: this.loop,
  101. autoplay: this.autoplay,
  102. animationData: animationData,
  103. path: '',
  104. rendererSettings: {
  105. context: canvasContext,
  106. clearCanvas: true
  107. }
  108. });
  109. } catch (e) {
  110. console.log(e);
  111. }
  112. },
  113. //mp alipay
  114. getNodeCanvasNodeRef(){
  115. return new Promise((resolve,reject)=>{
  116. const query = uni.createSelectorQuery().in(this)
  117. query
  118. .select('.cid')
  119. .fields({ node: true, size: true })
  120. .exec(res => {
  121. console.log(res);
  122. const canvasNode = res[0].node
  123. const canvasDpr = uni.getSystemInfoSync().pixelRatio
  124. const canvasWidth = res[0].width
  125. const canvasHeight = res[0].height
  126. const ctx = canvasNode.getContext('2d')
  127. resolve(ctx,{dpr:canvasDpr,width:canvasWidth,height:canvasHeight,node:canvasNode});
  128. })
  129. })
  130. },
  131. async LoadLottiePlay_H5(url) {
  132. const canvasContext = uni.createCanvasContext(this.cuid, this);
  133. // 请求到的lottie json数据
  134. let animationData=null
  135. // 请求lottie的路径。注意开启downloadFile域名并且返回格式是json
  136. const animationPath = url || this.url;// url || this.url
  137. // 指定canvas大小
  138. canvasContext.canvas = {
  139. width: this.w_w,
  140. height: this.h_h
  141. };
  142. try {
  143. // 如果同时指定 animationData 和 path, 优先取 animationData
  144. lottie.loadAnimation({
  145. renderer: 'canvas', // 只支持canvas
  146. loop: this.loop,
  147. autoplay: this.autoplay,
  148. animationData: '',
  149. path: animationPath,
  150. rendererSettings: {
  151. context: canvasContext,
  152. clearCanvas: true
  153. }
  154. });
  155. } catch (e) {
  156. console.log(e);
  157. }
  158. },
  159. play() {
  160. lottie.play();
  161. },
  162. stop() {
  163. lottie.stop();
  164. },
  165. pause() {
  166. lottie.pause();
  167. },
  168. rloadJson(url){
  169. return new Promise((res,rej)=>{
  170. uni.request({
  171. responseType:'json',
  172. url:url,
  173. success: (v) => {
  174. res(v)
  175. },
  176. fail: (e) => {
  177. console.log(e);
  178. rej(e)
  179. }
  180. })
  181. })
  182. },
  183. // type:1正向播放,-1反向
  184. setDirection(type = 1) {
  185. lottie.setDirection(type);
  186. },
  187. async registerAnimation(url) {
  188. if (!url) return;
  189. lottie.destroy();
  190. this.cKey = this.$tm.guid();
  191. await this.LoadLottiePlay_Mp(url);
  192. lottie.resize();
  193. }
  194. }
  195. };
  196. </script>
  197. <style lang="scss"></style>