ConfettiCelebration.vue 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. <template>
  2. <view class="confetti-container" v-if="show">
  3. <view
  4. v-for="(particle, index) in particles"
  5. :key="index"
  6. class="confetti"
  7. :style="particle.style"
  8. >
  9. {{ particle.emoji }}
  10. </view>
  11. </view>
  12. </template>
  13. <script>
  14. export default {
  15. name: 'ConfettiCelebration',
  16. props: {
  17. show: { type: Boolean, default: false },
  18. duration: { type: Number, default: 2000 }
  19. },
  20. data() {
  21. return {
  22. particles: [],
  23. emojis: ['🎉', '⭐', '🌟', '✨', '💫', '🎊', '🏆', '🎁', '🌈', '💖']
  24. }
  25. },
  26. watch: {
  27. show(val) {
  28. if (val) {
  29. this.launch()
  30. }
  31. }
  32. },
  33. methods: {
  34. launch() {
  35. const particles = []
  36. for (let i = 0; i < 30; i++) {
  37. const x = Math.random() * 100
  38. const rotation = Math.random() * 360
  39. const scale = 0.5 + Math.random() * 0.5
  40. const duration = 1500 + Math.random() * 1000
  41. const delay = Math.random() * 300
  42. particles.push({
  43. x: x,
  44. y: -20,
  45. rotation: rotation,
  46. scale: scale,
  47. duration: duration,
  48. delay: delay,
  49. emoji: this.emojis[Math.floor(Math.random() * this.emojis.length)],
  50. style: `left: ${x}%; top: -20%; transform: rotate(${rotation}deg) scale(${scale}); animation: fall ${duration}ms ease-out ${delay}ms forwards;`
  51. })
  52. }
  53. this.particles = particles
  54. setTimeout(() => {
  55. this.particles = []
  56. }, this.duration)
  57. }
  58. }
  59. }
  60. </script>
  61. <style scoped>
  62. .confetti-container {
  63. position: fixed;
  64. top: 0;
  65. left: 0;
  66. width: 100%;
  67. height: 100%;
  68. pointer-events: none;
  69. z-index: 9999;
  70. overflow: hidden;
  71. }
  72. .confetti {
  73. position: absolute;
  74. font-size: 24px;
  75. animation-timing-function: ease-out;
  76. animation-fill-mode: forwards;
  77. }
  78. @keyframes fall {
  79. 0% {
  80. opacity: 1;
  81. transform: rotate(0deg) translateY(0) scale(1);
  82. }
  83. 100% {
  84. opacity: 0;
  85. transform: rotate(720deg) translateY(100vh) scale(0.5);
  86. }
  87. }
  88. </style>