prize-flying.vue 5.5 KB

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