import type { Directive } from 'vue' interface ActivatePoint { id: number x: number y: number progress: number } type NeuralCardElement = HTMLElement & { _neuralAnimationId?: number | null } const vNeuralCard: Directive = { mounted(el: HTMLElement) { const neuralEl = el as NeuralCardElement const points: ActivatePoint[] = [] let pointId = 0 let animationId: number | null = null let isHovering = false const createActivatePoint = () => { const rect = el.getBoundingClientRect() const edge = Math.floor(Math.random() * 4) let x: number, y: number switch (edge) { case 0: x = rect.left + Math.random() * rect.width y = rect.top break case 1: x = rect.right y = rect.top + Math.random() * rect.height break case 2: x = rect.left + Math.random() * rect.width y = rect.bottom break default: x = rect.left y = rect.top + Math.random() * rect.height } points.push({ id: pointId++, x, y, progress: 0 }) updateCSS() } const updateCSS = () => { if (points.length === 0) { el.style.setProperty('--neural-points', '') return } const pointData = points .map(p => `${p.x},${p.y},${p.progress}`) .join('|') el.style.setProperty('--neural-points', pointData) el.style.setProperty('--neural-count', String(points.length)) } const animate = () => { points.forEach(p => { p.progress += 0.02 }) const activePoints = points.filter(p => p.progress < 1) points.length = 0 points.push(...activePoints) updateCSS() if (isHovering && points.length < 6) { if (Math.random() > 0.7) { createActivatePoint() } } animationId = requestAnimationFrame(animate) } const handleMouseEnter = () => { isHovering = true el.classList.add('neural-active') el.classList.add('neural-card-active') } const handleMouseLeave = () => { isHovering = false el.classList.remove('neural-active') el.classList.remove('neural-card-active') } const handleMouseMove = (e: MouseEvent) => { const rect = el.getBoundingClientRect() const mouseX = ((e.clientX - rect.left) / rect.width) * 100 const mouseY = ((e.clientY - rect.top) / rect.height) * 100 el.style.setProperty('--mouse-x', `${mouseX}%`) el.style.setProperty('--mouse-y', `${mouseY}%`) } el.addEventListener('mouseenter', handleMouseEnter) el.addEventListener('mouseleave', handleMouseLeave) el.addEventListener('mousemove', handleMouseMove) animate() neuralEl._neuralAnimationId = animationId }, unmounted(el: HTMLElement) { const neuralEl = el as NeuralCardElement if (neuralEl._neuralAnimationId) { cancelAnimationFrame(neuralEl._neuralAnimationId) } } } export default vNeuralCard