| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- <template>
- <canvas ref="canvasRef" class="particles-canvas" />
- </template>
- <script setup>
- import { onMounted, onUnmounted, ref } from 'vue'
- const canvasRef = ref(null)
- let animationId = null
- let particles = []
- const initParticles = (width, height) => {
- particles = []
- const particleCount = 30
- const centerX = width / 2
- const centerY = height / 2
- const maxDistance = Math.min(width, height * 2) * 0.4
- for (let i = 0; i < particleCount; i++) {
- const angle = Math.random() * Math.PI * 2
- const distance = maxDistance + Math.random() * 50
- particles.push({
- x: centerX + Math.cos(angle) * distance,
- y: centerY + Math.sin(angle) * distance,
- targetX: centerX,
- targetY: centerY,
- speed: 0.3 + Math.random() * 0.5,
- size: 1 + Math.random() * 1,
- opacity: 0.3 + Math.random() * 0.7
- })
- }
- }
- const drawAnimation = (ctx, width, height) => {
- const centerX = width / 2
- const centerY = height / 2
- ctx.clearRect(0, 0, width, height)
- if (particles.length > 0) {
- particles.forEach(particle => {
- const dx = particle.targetX - particle.x
- const dy = particle.targetY - particle.y
- const distance = Math.sqrt(dx * dx + dy * dy)
- if (distance < 5) {
- const angle = Math.random() * Math.PI * 2
- const maxDistance = Math.min(width, height * 2) * 0.4
- const newDistance = maxDistance + Math.random() * 50
- particle.x = centerX + Math.cos(angle) * newDistance
- particle.y = centerY + Math.sin(angle) * newDistance
- particle.opacity = 0.3 + Math.random() * 0.7
- } else {
- const moveX = (dx / distance) * particle.speed
- const moveY = (dy / distance) * particle.speed
- particle.x += moveX
- particle.y += moveY
- }
- ctx.globalAlpha = particle.opacity
- ctx.fillStyle = '#ffffff'
- ctx.beginPath()
- ctx.arc(particle.x, particle.y, particle.size, 0, Math.PI * 2)
- ctx.fill()
- ctx.globalAlpha = 1
- })
- }
- }
- const startAnimation = () => {
- stopAnimation()
- const canvas = canvasRef.value
- if (!canvas) return
- const rect = canvas.getBoundingClientRect()
- const width = rect.width || window.innerWidth
- const height = rect.height || rect.width / 2
- canvas.width = width
- canvas.height = height
- const ctx = canvas.getContext('2d')
- initParticles(width, height)
- const loop = () => {
- drawAnimation(ctx, width, height)
- animationId = requestAnimationFrame(loop)
- }
- loop()
- }
- const stopAnimation = () => {
- if (animationId) {
- cancelAnimationFrame(animationId)
- animationId = null
- }
- }
- onMounted(() => {
- startAnimation()
- window.addEventListener('resize', startAnimation)
- })
- onUnmounted(() => {
- stopAnimation()
- window.removeEventListener('resize', startAnimation)
- })
- </script>
- <style scoped>
- .particles-canvas {
- width: 100%;
- height: 100%;
- display: block;
- pointer-events: none;
- }
- </style>
|