最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
CSS如何制作类似探照灯的文字遮罩动画_利用mask-position动态位移
时间:2026-07-17 11:00:54 编辑:袖梨 来源:一聚教程网
mask-position 动画无反应主因是 SVG mask 未设 maskUnits="userSpaceOnUse" 或 PNG 未启用 alpha 通道;推荐用 mask-image 径向渐变+自定义属性动画,配合 mask-size 放大和 mask-repeat:no-repeat 确保光斑覆盖。
mask-position 动画为什么没反应?
直接对 mask-position 加 transition 或 @keyframes 却看不到变化,大概率是因为 mask 源是 SVG <mask> 且未设 mask-type: luminance,或用了 PNG 位图但未开启 alpha 通道解析。CSS mask 默认按亮度(luminance)解析遮罩,纯黑/白 PNG 在部分浏览器中会被当全透或全遮,必须显式声明:mask-type: luminance(Chrome 115+ 支持,旧版需用 -webkit-mask + -webkit-mask-type)。
常见错误写法:mask: url(#spotlight) 0 0; —— 这里 0 0 是初始偏移,但若 SVG <mask> 内部 <rect> 或 <circle> 没设 width/height 覆盖整个容器,位移就“动在空处”,视觉无变化。
用 CSS mask-image + linear-gradient 做轻量探照灯
不依赖 SVG,用渐变做动态遮罩更可控。核心是:一个高斯模糊的径向渐变作“光斑”,配合 mask-composite: exclude(或反向叠加)挖出文字。
-
mask-image: radial-gradient(circle at var(--x) var(--y), transparent 60%, black 75%)——--x/--y控制光心位置,transparent区域透出文字,black区域遮住 - 必须加
mask-size: 300% 300%(或更大),否则光斑太小,位移时很快移出文字范围 -
mask-repeat: no-repeat防止重复平铺干扰效果 - 动画只需改
--x和--y自定义属性,再用transition: --x, --y 0.4s ease-out
示例关键代码:
立即学习“前端免费学习笔记(深入)”;
h1 { --x: 50%; --y: 50%; -webkit-mask: radial-gradient(circle at var(--x) var(--y), transparent 60%, black 75%); mask: radial-gradient(circle at var(--x) var(--y), transparent 60%, black 75%); -webkit-mask-size: 300% 300%; mask-size: 300% 300%; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; transition: --x, --y 0.4s ease-out;}h1:hover { --x: 80%; --y: 20%; }
SVG mask 中 mask-position 的实际生效条件
当 mask 源是 SVG 元素(如 url(#spotlight)),mask-position 是否起作用,取决于该 SVG <mask> 的 maskUnits 属性值:
-
maskUnits="userSpaceOnUse":此时mask-position的像素值才真正映射到容器坐标系,可动画 -
maskUnits="objectBoundingBox"(默认):mask-position: 100px 100px会被忽略,因为坐标系是归一化的(0–1) - 务必在 SVG
<mask>标签上显式写maskUnits="userSpaceOnUse",并设width/height足够大(如width="2000"),否则位移超出范围即失效
容易被忽略的一点:CSS 中写的 mask-position: 200px 150px,其参考原点是 mask 图像左上角,不是文字容器——如果 mask 图像本身尺寸小,位移后光斑可能早已脱离文字区域。
鼠标跟随探照灯的坑:position: fixed 导致坐标错乱
想实现鼠标移动时光斑跟随,用 mousemove 更新 --x/--y 很自然,但若文字容器有 transform、scroll 或父级 position: fixed,clientX/clientY 直接赋值会偏移。
- 优先用
element.getBoundingClientRect()获取文字容器视口位置,再计算相对偏移 - 避免在
body上监听mousemove后直接设全局变量——滚动时clientY不变,但文字已上移,光斑悬空 - 更稳的做法:监听容器上的
mousemove,取e.offsetX/e.offsetY(注意兼容性,Firefox 不支持offsetX/Y,需 fallback 到getBoundingClientRect()计算) - 性能敏感场景记得
throttle,不然高频触发导致--x/--y更新卡顿
复杂点在于:mask 渐变中心要对齐鼠标热区,但文字若有 line-height、padding 或 transform: scale(),单纯用 offset 值仍会偏差——这时候得把容器的 getComputedStyle 所有影响布局的属性都纳入偏移修正。
相关文章
- 生存33天 天怒模式高效通关攻略与对战技巧详解 07-31
- 遗忘之海海螺如何获取 遗忘之海海螺作用是什么 07-31
- 遗忘之海渡桥岛遗迹跑图操作步骤 遗忘之海渡桥岛遗迹怎么跑图 07-31
- 遗忘之海小斧头技能选择 遗忘之海小斧头技能选哪个 07-31
- 微博手机网页版入口怎么找-微博网页版最新访问地址 07-31
- 遗忘之海小斧头职业选择 遗忘之海小斧头转职选哪个 07-31