mirror of
https://gitcode.com/leisileken/cloud-smart.git
synced 2026-09-11 10:27:20 +08:00
feat: 恢复深色主题版本,替换星空背景视频
This commit is contained in:
120
src/directives/neuralCard.ts
Normal file
120
src/directives/neuralCard.ts
Normal file
@@ -0,0 +1,120 @@
|
||||
import type { Directive } from 'vue'
|
||||
|
||||
interface ActivatePoint {
|
||||
id: number
|
||||
x: number
|
||||
y: number
|
||||
progress: number
|
||||
}
|
||||
|
||||
const vNeuralCard: Directive = {
|
||||
mounted(el: HTMLElement) {
|
||||
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()
|
||||
|
||||
el._neuralAnimationId = animationId
|
||||
},
|
||||
|
||||
unmounted(el: HTMLElement) {
|
||||
if (el._neuralAnimationId) {
|
||||
cancelAnimationFrame(el._neuralAnimationId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default vNeuralCard
|
||||
Reference in New Issue
Block a user