在 Cyber Crayon 主题中,全站背景使用了一层 CSS 网格作为视觉基底。最近我们为它增加了两层交互效果——视差偏移和局部高亮,让原本单纯的装饰网格变得”活”了起来。本文记录这个实现过程。
问题背景
最初的网格背景是纯 CSS 实现的:两个方向重复的线性渐变交叉形成网格,配合一个 20 秒的 translateY 循环动画让网格缓慢滚动。功能没问题,但太”安静”了——它和用户没有任何交互。
.lc-tech-bg__grid {
position: absolute;
inset: 0;
background-image:
linear-gradient(rgba(74, 108, 244, 0.03) 1px, transparent 1px),
linear-gradient(90deg, rgba(74, 108, 244, 0.03) 1px, transparent 1px);
background-size: 50px 50px;
animation: lc-tech-grid-move 20s linear infinite;
}
最终方案
两层网格结构
核心思路:底层保持原本的透明度(3%),上层使用更高的透明度(12%),并通过 CSS mask-image 用径向渐变只露出鼠标附近区域。
.lc-tech-bg__grid--highlight {
background-image:
linear-gradient(rgba(74, 108, 244, 0.12) 1px, transparent 1px),
linear-gradient(90deg, rgba(74, 108, 244, 0.12) 1px, transparent 1px);
mask-image: radial-gradient(
150px circle at var(--mouse-x, 50%) var(--mouse-y, 50%),
black 50%,
transparent 100%
);
}
mask-image 以鼠标位置为中心画一个径向渐变,从完全不透明(black)渐变到完全透明,让高亮网格只在鼠标附近可见。鼠标位置通过 CSS 自定义属性 --mouse-x 和 --mouse-y 由 JavaScript 实时更新。
JavaScript 鼠标跟踪
(function initTechBgMouse() {
var grid = document.querySelector('.lc-tech-bg__grid');
var highlight = document.querySelector('.lc-tech-bg__grid--highlight');
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
var currentX = 0, currentY = 0;
var targetX = 0, targetY = 0;
var ticking = false;
function update() {
currentX += (targetX - currentX) * 0.08;
var tx = 'translate(' + currentX + 'px, ' + currentY + 'px)';
grid.style.transform = tx;
if (highlight) highlight.style.transform = tx;
ticking = false;
}
document.addEventListener('mousemove', function (e) {
targetX = (e.clientX / window.innerWidth - 0.5) * 40;
targetY = (e.clientY / window.innerHeight - 0.5) * 40;
if (highlight) {
highlight.style.setProperty('--mouse-x', (e.clientX / window.innerWidth * 100) + '%');
highlight.style.setProperty('--mouse-y', (e.clientY / window.innerHeight * 100) + '%');
}
if (!ticking) {
requestAnimationFrame(update);
ticking = true;
}
});
})();
几个关键点
- 性能:
requestAnimationFrame+ ticking 锁,避免 mousemove 高频触发 - 平滑:lerp 线性插值让偏移过渡自然
- 同步:两层网格共享同一个
transform,偏移始终对齐 - 可访问性:
prefers-reduced-motion时完全禁用
@media (prefers-reduced-motion: reduce) {
.lc-tech-bg__grid--highlight {
display: none;
}
}
总结
这个实现的核心架构是:两层网格 + mask-image + CSS 自定义属性 + requestAnimationFrame lerp。整个过程没有依赖任何第三方库,纯 CSS + 原生 JS 实现。最终的视觉效果是:网格随着鼠标移动微微浮动,鼠标扫过的区域网格线自然亮起,像是背景在”呼吸”。
讨论
还没有留言,来留下第一条评论吧!