| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- <template>
- <view class="confetti-container" v-if="show">
- <view
- v-for="(particle, index) in particles"
- :key="index"
- class="confetti"
- :style="particle.style"
- >
- {{ particle.emoji }}
- </view>
- </view>
- </template>
- <script>
- export default {
- name: 'ConfettiCelebration',
- props: {
- show: { type: Boolean, default: false },
- duration: { type: Number, default: 2000 }
- },
- data() {
- return {
- particles: [],
- emojis: ['🎉', '⭐', '🌟', '✨', '💫', '🎊', '🏆', '🎁', '🌈', '💖']
- }
- },
- watch: {
- show(val) {
- if (val) {
- this.launch()
- }
- }
- },
- methods: {
- launch() {
- const particles = []
- for (let i = 0; i < 30; i++) {
- const x = Math.random() * 100
- const rotation = Math.random() * 360
- const scale = 0.5 + Math.random() * 0.5
- const duration = 1500 + Math.random() * 1000
- const delay = Math.random() * 300
-
- particles.push({
- x: x,
- y: -20,
- rotation: rotation,
- scale: scale,
- duration: duration,
- delay: delay,
- emoji: this.emojis[Math.floor(Math.random() * this.emojis.length)],
- style: `left: ${x}%; top: -20%; transform: rotate(${rotation}deg) scale(${scale}); animation: fall ${duration}ms ease-out ${delay}ms forwards;`
- })
- }
- this.particles = particles
-
- setTimeout(() => {
- this.particles = []
- }, this.duration)
- }
- }
- }
- </script>
- <style scoped>
- .confetti-container {
- position: fixed;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- pointer-events: none;
- z-index: 9999;
- overflow: hidden;
- }
- .confetti {
- position: absolute;
- font-size: 24px;
- animation-timing-function: ease-out;
- animation-fill-mode: forwards;
- }
- @keyframes fall {
- 0% {
- opacity: 1;
- transform: rotate(0deg) translateY(0) scale(1);
- }
- 100% {
- opacity: 0;
- transform: rotate(720deg) translateY(100vh) scale(0.5);
- }
- }
- </style>
|