comb-loader.vue 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. <template>
  2. <view class="text-container">
  3. <!-- #ifdef APP-NVUE -->
  4. <text ref="text" class="loading-text" :class="animationClass" v-for="(item, index) in texts" :key="index" :style="{'font-size': fontSize + 'rpx'}">{{item}}</text>
  5. <!-- #endif -->
  6. <!-- #ifdef APP-VUE || H5 -->
  7. <text ref="text" class="loading-text" :class="animationClass" v-for="(item, index) in texts" :key="index" :style="{'animation-delay': 102.631578 * (index + 1) + 'ms', 'font-size': fontSize + 'rpx'}" v-html="item"></text>
  8. <!-- #endif -->
  9. <!-- #ifdef MP-WEIXIN -->
  10. <block v-for="(item, index) in texts" :key="index">
  11. <text v-if="item == '&nbsp;'" :style="{width: spaceSize + 'rpx'}"></text>
  12. <text ref="text" class="loading-text" :class="animationClass" :style="{'animation-delay': 102.631578 * (index + 1) + 'ms', 'font-size': fontSize + 'rpx'}" v-else>{{item}}</text>
  13. </block>
  14. <!-- #endif -->
  15. </view>
  16. </template>
  17. <script>
  18. // ls-loading组件内置动画效果组件: 组合类型动画组件
  19. // #ifdef APP-NVUE
  20. const animation = weex.requireModule('animation');
  21. // #endif
  22. let sit;
  23. export default {
  24. name: 'comb-loader',
  25. props: {
  26. // 加载中的文字
  27. text: {
  28. type: String,
  29. default: '正在加载'
  30. },
  31. // 加载中文字大小
  32. fontSize: {
  33. type: [String, Number],
  34. default: 58
  35. },
  36. // 动画类型 twinkle文字闪烁 focus文字聚焦
  37. animationType: {
  38. type: String,
  39. default: "twinkle"
  40. }
  41. },
  42. computed: {
  43. texts() {
  44. // #ifdef APP-NVUE
  45. return this.text.split('');
  46. // #endif
  47. // #ifndef APP-NVUE
  48. return this.text.split('').map(item => {
  49. return item.replace(/\s/g, '&nbsp;');
  50. });
  51. // #endif
  52. },
  53. spaceSize() {
  54. return this.fontSize / 2;
  55. },
  56. animationClass() {
  57. if (this.animationType == 'twinkle') {
  58. return 'text-animation-twinkle'
  59. }
  60. if (this.animationType == 'focus') {
  61. return 'text-animation-focus'
  62. }
  63. }
  64. },
  65. mounted() {
  66. setTimeout(() => {
  67. // #ifdef APP-NVUE
  68. switch (this.animationType) {
  69. case 'twinkle':
  70. this.createAnimation1();
  71. break;
  72. case 'focus':
  73. this.createAnimation2();
  74. break;
  75. default:
  76. this.createAnimation1();
  77. }
  78. // #endif
  79. }, 40);
  80. },
  81. destroyed() {
  82. clearInterval(sit);
  83. },
  84. methods: {
  85. // 动画1 twinkle 文字依次闪烁
  86. createAnimation1() {
  87. const refs = this.$refs.text;
  88. const gap = 1200 / this.texts.length;
  89. const duration = 66 * this.texts.length;
  90. let flag = true;
  91. let style;
  92. // 定时器执行前,先执行一次,让整个过程更流畅
  93. setTimeout(() => {
  94. for (let i = 0, length = refs.length; i < length; i++) {
  95. this.executeAnimation(refs[i], gap * (i + 1), {opacity: 1});
  96. }
  97. }, 100);
  98. clearInterval(sit);
  99. sit = setInterval(() => {
  100. style = flag ? {opacity: 1} : {opacity: 0.3};
  101. for (let i = 0, length = refs.length; i < length; i++) {
  102. this.executeAnimation(refs[i], gap * (i + 1), style);
  103. }
  104. flag = !flag;
  105. }, duration);
  106. },
  107. // 动画2 focus 文字依次放大
  108. createAnimation2() {
  109. const refs = this.$refs.text;
  110. const gap = 2300 / refs.length;
  111. const duration = 80 * refs.length;
  112. let flag = true;
  113. let style;
  114. // 定时器执行前,先执行一次,让整个过程更流畅
  115. setTimeout(() => {
  116. for (let i = 0, length = refs.length; i < length; i++) {
  117. this.executeAnimation(refs[i], gap * (i + 1), {transform: 'scale(1.3)'});
  118. }
  119. }, 100);
  120. clearInterval(sit);
  121. sit = setInterval(() => {
  122. style = flag ? {transform: 'scale(1.3)'} : {transform: 'scale(1)'};
  123. for (let i = 0, length = refs.length; i < length; i++) {
  124. this.executeAnimation(refs[i], gap * (i + 1), style);
  125. }
  126. flag = !flag;
  127. }, duration);
  128. },
  129. // 执行动画
  130. executeAnimation(ref, delay, styles) {
  131. animation.transition(ref, {
  132. styles,
  133. duration: 600, //ms
  134. timingFunction: 'ease-in-out',
  135. needLayout: false,
  136. delay: delay //ms
  137. });
  138. }
  139. }
  140. }
  141. </script>
  142. <style>
  143. .loading-text {
  144. font-weight: 700;
  145. /* #ifdef APP-NVUE */
  146. /* color: #c2c1c2; */
  147. opacity: 0.3;
  148. /* #endif */
  149. /* #ifndef APP-NVUE */
  150. opacity: 1;
  151. color: #e8e7e8;
  152. animation-iteration-count: infinite;
  153. /* #endif */
  154. }
  155. .text-animation-twinkle {
  156. /* #ifndef APP-NVUE */
  157. animation-timing-function: ease-in-out;
  158. animation-duration: 2.6s;
  159. animation-name: twinkle;
  160. /* #endif */
  161. }
  162. .text-animation-focus {
  163. margin-left: 2rpx;
  164. margin-right: 2rpx;
  165. /* #ifndef APP-NVUE */
  166. animation-timing-function: linear;
  167. animation-duration: 1.6s;
  168. animation-name: focus;
  169. /* #endif */
  170. }
  171. /* #ifndef APP-NVUE */
  172. @keyframes twinkle {
  173. 0% {
  174. /* color: #c3c3c3; */
  175. color: #F0AD4E;
  176. }
  177. 100%{
  178. color: #FFFFFF;
  179. }
  180. 20% {
  181. /* color: #e8e7e8; */
  182. color: #007AFF;
  183. }
  184. }
  185. @keyframes focus {
  186. 0%,100% {
  187. transform: scale(1);
  188. }
  189. 20% {
  190. transform: scale(1.3);
  191. }
  192. }
  193. /* #endif */
  194. </style>