

如何在 Astro 中为你的鼠标添加指针动画
如何在 Astro 中为你的鼠标添加指针动画
views
| comments
前言#
这篇博客会简单讲解一下如何在 Astro 中为你的鼠标添加指针动画。
方法#
在 Astro 中,Layout 这个概念非常重要。无论你的 Layout 如何设计,一般来说都会通过 <slot />
来支持内容的插入,并且一般的全部界面最终都会在 <BaseLayout />
中被包裹。
因此假如你想要添加一些全局效果,都可以编辑 src/layouts/BaseLayout.astro
文件。
对于指针效果来说,你可以在添加:
src/layouts/BaseLayout.astro
...
<body class='flex justify-center bg-background'>
<style define:vars={{ highlightColor }}>
...
/* 点击粒子效果样式 */
:global(.click-particle) {
position: fixed;
pointer-events: none;
width: 14px;
height: 14px;
border-radius: 50%;
z-index: 9999;
animation: particle-explosion 1.1s ease-out forwards;
box-shadow: 0 0 6px rgba(255, 255, 255, 0.8);
}
/* 暗色主题下的粒子效果 */
:global(.dark .click-particle) {
box-shadow: 0 0 8px rgba(255, 255, 255, 0.4);
}
@keyframes particle-explosion {
0% {
opacity: 1;
transform: scale(0.4) translate(0, 0);
}
15% {
opacity: 1;
transform: scale(1.3) translate(var(--dx), var(--dy));
}
60% {
opacity: 0.8;
transform: scale(1) translate(calc(var(--dx) * 2.5), calc(var(--dy) * 2.5));
}
100% {
opacity: 0;
transform: scale(0.3) translate(calc(var(--dx) * 3.5), calc(var(--dy) * 3.5));
}
}
/* 亮色主题粒子颜色 */
:global(.click-particle.color-1) {
background: #ffc1cc;
background: radial-gradient(circle, #ffb3ba 0%, #ffc1cc 100%);
}
:global(.click-particle.color-2) {
background: #bde4ff;
background: radial-gradient(circle, #a8d8ff 0%, #bde4ff 100%);
}
:global(.click-particle.color-3) {
background: #fff2a8;
background: radial-gradient(circle, #ffe66d 0%, #fff2a8 100%);
}
:global(.click-particle.color-4) {
background: #e6ccff;
background: radial-gradient(circle, #d4a5ff 0%, #e6ccff 100%);
}
:global(.click-particle.color-5) {
background: #c1ffc1;
background: radial-gradient(circle, #a8e6a8 0%, #c1ffc1 100%);
}
:global(.click-particle.color-6) {
background: #ffd4a3;
background: radial-gradient(circle, #ffcc99 0%, #ffd4a3 100%);
}
:global(.click-particle.color-7) {
background: #c4e8ff;
background: radial-gradient(circle, #b3deff 0%, #c4e8ff 100%);
}
:global(.click-particle.color-8) {
background: #f8d7da;
background: radial-gradient(circle, #f5c2c7 0%, #f8d7da 100%);
}
:global(.click-particle.color-9) {
background: #d1f2d1;
background: radial-gradient(circle, #c3e6c3 0%, #d1f2d1 100%);
}
:global(.click-particle.color-10) {
background: #fff0d4;
background: radial-gradient(circle, #ffe8b3 0%, #fff0d4 100%);
}
/* 暗色主题粒子颜色 - 更深更鲜艳 */
:global(.dark .click-particle.color-1) {
background: #ff6b8a;
background: radial-gradient(circle, #ff4757 0%, #ff6b8a 100%);
}
:global(.dark .click-particle.color-2) {
background: #4fc3f7;
background: radial-gradient(circle, #29b6f6 0%, #4fc3f7 100%);
}
:global(.dark .click-particle.color-3) {
background: #ffd54f;
background: radial-gradient(circle, #ffca28 0%, #ffd54f 100%);
}
:global(.dark .click-particle.color-4) {
background: #ba68c8;
background: radial-gradient(circle, #ab47bc 0%, #ba68c8 100%);
}
:global(.dark .click-particle.color-5) {
background: #81c784;
background: radial-gradient(circle, #66bb6a 0%, #81c784 100%);
}
:global(.dark .click-particle.color-6) {
background: #ffb74d;
background: radial-gradient(circle, #ffa726 0%, #ffb74d 100%);
}
:global(.dark .click-particle.color-7) {
background: #64b5f6;
background: radial-gradient(circle, #42a5f5 0%, #64b5f6 100%);
}
:global(.dark .click-particle.color-8) {
background: #f48fb1;
background: radial-gradient(circle, #f06292 0%, #f48fb1 100%);
}
:global(.dark .click-particle.color-9) {
background: #a5d6a7;
background: radial-gradient(circle, #81c784 0%, #a5d6a7 100%);
}
:global(.dark .click-particle.color-10) {
background: #ffe082;
background: radial-gradient(circle, #ffd54f 0%, #ffe082 100%);
}
</style>
...
<script>
document.addEventListener('DOMContentLoaded', () => {
function createParticle(
x: number,
y: number,
angle: number,
distance: number,
colorIndex: number
) {
const particle = document.createElement('div')
particle.className = `click-particle color-${colorIndex}`
const dx = Math.cos(angle) * distance
const dy = Math.sin(angle) * distance
particle.style.setProperty('--dx', dx + 'px')
particle.style.setProperty('--dy', dy + 'px')
particle.style.left = x + 'px'
particle.style.top = y + 'px'
const size = Math.random() * 6 + 8
particle.style.width = size + 'px'
particle.style.height = size + 'px'
document.body.appendChild(particle)
setTimeout(() => {
if (particle.parentNode) {
particle.parentNode.removeChild(particle)
}
}, 1100)
}
document.addEventListener('click', (e) => {
const particleCount = 10
const baseDistance = 18
for (let i = 0; i < particleCount; i++) {
const angle = ((Math.PI * 2) / particleCount) * i
const distance = baseDistance + Math.random() * 8
const colorIndex = (i % 10) + 1
setTimeout(() => {
createParticle(e.clientX, e.clientY, angle, distance, colorIndex)
}, i * 12)
}
for (let i = 0; i < 4; i++) {
const randomAngle = Math.random() * Math.PI * 2
const randomDistance = baseDistance + Math.random() * 10
const colorIndex = Math.floor(Math.random() * 10) + 1
setTimeout(
() => {
createParticle(e.clientX, e.clientY, randomAngle, randomDistance, colorIndex)
},
(particleCount + i) * 12
)
}
})
})
</script>
</body>
</html>
astro