prize-flying.vue 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. <template>
  2. <view class="prize-flying">
  3. <template v-for="(flyLeft, index) in flyLeftList">
  4. <!-- <view :key="'fly-left-' + index" :class="['fly-prize', 'fly-left']" :style="flyStyle(flyLeft)"></view> -->
  5. <view
  6. :key="'fly-left-' + index"
  7. :class="['fly-prize', 'fly-left']"
  8. :style="{ background: flyLeft.image, '-webkit-animation-duration': flySpeed + 's', 'animation-duration': flySpeed + 's' }"
  9. ></view>
  10. </template>
  11. <template v-for="(flyCenter, index) in flyCenterList">
  12. <!-- <view :key="'fly-center-' + index" :class="['fly-prize', 'fly-center']" :style="flyStyle(flyCenter)"></view> -->
  13. <view
  14. :key="'fly-center-' + index"
  15. :class="['fly-prize', 'fly-center']"
  16. :style="{ background: flyCenter.image, '-webkit-animation-duration': flySpeed + 's', 'animation-duration': flySpeed + 's' }"
  17. ></view>
  18. </template>
  19. <template v-for="(flyRight, index) in flyRightList">
  20. <!-- <view :key="'fly-right-' + index" :class="['fly-prize', 'fly-right']" :style="flyStyle(flyRight)"></view> -->
  21. <view
  22. :key="'fly-right-' + index"
  23. :class="['fly-prize', 'fly-right']"
  24. :style="{ background: flyRight.image, '-webkit-animation-duration': flySpeed + 's', 'animation-duration': flySpeed + 's' }"
  25. ></view>
  26. </template>
  27. </view>
  28. </template>
  29. <script>
  30. export default {
  31. name: 'prize-flying',
  32. props: {
  33. boxId: Number
  34. },
  35. data() {
  36. return {
  37. prizeList: [],
  38. flyLeftList: [],
  39. flyCenterList: [],
  40. flyRightList: [],
  41. indexRecord: 0, //记录奖品下标
  42. intervalTime: 2, //飞出频率 秒
  43. interval: null,
  44. flySpeed: 25 //飞行速度 秒 越小越快
  45. };
  46. },
  47. created() {
  48. this.loadPrizeList();
  49. },
  50. destroyed() {
  51. //销毁
  52. clearInterval(this.interval);
  53. },
  54. computed: {
  55. prizeLength() {
  56. return this.prizeList.length;
  57. }
  58. },
  59. methods: {
  60. //加载奖品列表
  61. loadPrizeList() {
  62. if (!this.boxId) return;
  63. this.$api.boximages({ box_id: this.boxId }).then(({ data }) => {
  64. this.prizeList = data.goodsimagelist;
  65. this.flyInterval();
  66. });
  67. },
  68. //循环
  69. flyInterval() {
  70. this.pushFlyList();
  71. this.interval = setInterval(() => {
  72. this.pushFlyList();
  73. }, this.intervalTime * 1000);
  74. },
  75. pushFlyList() {
  76. let count = 0;
  77. while (count < 3) {
  78. if (this.indexRecord == this.prizeLength - 1) {
  79. this.indexRecord = 0;
  80. } else {
  81. this.indexRecord++;
  82. }
  83. let prize = this.prizeList[this.indexRecord];
  84. switch (count) {
  85. case 0:
  86. this.flyLeftList.push(prize);
  87. break;
  88. case 1:
  89. this.flyCenterList.push(prize);
  90. break;
  91. case 2:
  92. this.flyRightList.push(prize);
  93. break;
  94. }
  95. count++;
  96. }
  97. },
  98. flyStyle(prize) {
  99. return {
  100. background: `url(${prize.image})`,
  101. '-webkit-animation-duration': `${this.flySpeed}s`,
  102. 'animation-duration': `${this.flySpeed}s`
  103. };
  104. }
  105. }
  106. };
  107. </script>
  108. <style lang="scss">
  109. .prize-flying {
  110. z-index: 99;
  111. width: 200rpx;
  112. position: absolute;
  113. bottom: 50%;
  114. left: 50%;
  115. transform: translateX(-50%);
  116. .fly-prize {
  117. text-align: center;
  118. position: absolute;
  119. top: 100%;
  120. opacity: 0;
  121. width: 78rpx;
  122. height: 78rpx;
  123. background-repeat: no-repeat !important;
  124. background-size: 100% 100% !important;
  125. border-radius: 50%;
  126. background: #fff;
  127. border: 1px solid #3277ff;
  128. padding: 14rpx;
  129. }
  130. .fly-left {
  131. left: 0px;
  132. z-index: 5;
  133. -webkit-animation: flyleft;
  134. animation: flyleft;
  135. }
  136. .fly-center {
  137. left: 60rpx;
  138. z-index: 3;
  139. -webkit-animation: flycenter;
  140. animation: flycenter;
  141. }
  142. .fly-right {
  143. right: 0px;
  144. z-index: 5;
  145. -webkit-animation: flyright;
  146. animation: flyright;
  147. }
  148. }
  149. // 动画
  150. @keyframes flyleft {
  151. 0% {
  152. // top: 100%;
  153. -webkit-transform: scale(0) translateX(0);
  154. transform: scale(0) translateX(0);
  155. opacity: 0.6;
  156. }
  157. 3% {
  158. // top: 95%;
  159. }
  160. 5% {
  161. -webkit-transform: scale(1) translateX(0) translateY(-80%);
  162. transform: scale(1) translateX(0) translateY(-80%);
  163. opacity: 0.8;
  164. }
  165. 20% {
  166. opacity: 1;
  167. }
  168. 30% {
  169. opacity: 0.2;
  170. }
  171. 32% {
  172. opacity: 0;
  173. visibility: hidden;
  174. }
  175. 50% {
  176. -webkit-transform: scale(1.9) translateX(-40px) translateY(-340%);
  177. transform: scale(1.9) translateX(-40px) translateY(-340%);
  178. }
  179. 100% {
  180. // top: 0%;
  181. -webkit-transform: translateX(-100px);
  182. transform: translateX(-100px);
  183. }
  184. }
  185. @keyframes flycenter {
  186. 0% {
  187. // top: 100%;
  188. -webkit-transform: scale(0) translateX(0);
  189. transform: scale(0) translateX(0);
  190. opacity: 0.6;
  191. }
  192. 3% {
  193. // top: 95%;
  194. }
  195. 5% {
  196. -webkit-transform: scale(1) translateX(0) translateY(-80%);
  197. transform: scale(1) translateX(0) translateY(-80%);
  198. opacity: 0.8;
  199. }
  200. 20% {
  201. opacity: 1;
  202. }
  203. 30% {
  204. opacity: 0.2;
  205. }
  206. 32% {
  207. opacity: 0;
  208. visibility: hidden;
  209. }
  210. 34% {
  211. opacity: 0;
  212. }
  213. 50% {
  214. -webkit-transform: scale(1.9) translateX(0) translateY(-340%);
  215. transform: scale(1.9) translateX(0) translateY(-340%);
  216. }
  217. 100% {
  218. // top: 0%;
  219. -webkit-transform: translateX(0);
  220. transform: translateX(0);
  221. }
  222. }
  223. @keyframes flyright {
  224. 0% {
  225. // top: 100%;
  226. -webkit-transform: scale(0) translateX(0);
  227. transform: scale(0) translateX(0);
  228. opacity: 0.6;
  229. }
  230. 3% {
  231. // top: 95%;
  232. }
  233. 5% {
  234. -webkit-transform: scale(1) translateX(0) translateY(-80%);
  235. transform: scale(1) translateX(0) translateY(-80%);
  236. opacity: 0.8;
  237. }
  238. 20% {
  239. opacity: 1;
  240. }
  241. 30% {
  242. opacity: 0.2;
  243. }
  244. 32% {
  245. opacity: 0;
  246. visibility: hidden;
  247. }
  248. 34% {
  249. opacity: 0;
  250. }
  251. 50% {
  252. -webkit-transform: scale(1.9) translateX(40px) translateY(-340%);
  253. transform: scale(1.9) translateX(40px) translateY(-340%);
  254. }
  255. 100% {
  256. // top: 0%;
  257. -webkit-transform: translateX(100px);
  258. transform: translateX(100px);
  259. }
  260. }
  261. </style>