核心是监听 mousemove 实时计算鼠标相对卡片中心的坐标偏移量并映射为 ±10° 内的 rotatex/y 角度,需用 getboundingclientrect() 获取位置、transform-origin: center 设定旋转中心、requestanimationframe 节流、保留按钮 pointer-events:auto 且 z-index 高于装饰层,移动端适配 touchmove,避免 preserve-3d 误用和 perspective 过大。

用 transform: rotateX() 和 rotateY() 动态响应鼠标位置
核心不是靠 CSS 动画循环,而是监听 mousemove 实时计算偏移量,把鼠标相对卡片中心的坐标映射为旋转角度。角度必须控制在 ±10° 以内,否则会失真;建议用 getBoundingClientRect() 获取卡片边界,再减去 clientX/Y 算出相对偏移。
- 不要直接用
event.pageX/pageY—— 它们受页面滚动影响,会导致倾斜抖动 - 旋转中心点必须设为
transform-origin: center,否则倾斜轴会偏移 - 推荐用
Math.atan2(dy, dx) * 180 / Math.PI换算角度更平滑,但简单场景直接线性映射(如dy / height * 8)也够用
避免按钮交互失效:pointer-events: none 别乱加
常见错误是给伪元素或阴影层加了 pointer-events: none,结果点击穿透、按钮没反应。倾斜效果通常靠伪元素 ::before 或子容器实现,但主按钮本身必须保留 pointer-events: auto(默认值),且不能被遮挡。
- 如果用了
position: absolute的装饰层,确保它不覆盖按钮的点击热区 - 检查
z-index层级:按钮的z-index至少比装饰层高 1 - 用浏览器开发者工具的「元素选择器」点选按钮,确认高亮区域完整覆盖可点击区域
性能关键:用 requestAnimationFrame 节流 + will-change: transform
高频 mousemove 直接触发样式重绘,卡顿明显。必须把更新逻辑放进 requestAnimationFrame,且只在鼠标真正进入按钮区域时绑定事件(进 mouseenter 绑,出 mouseleave 解绑)。
-
will-change: transform要加在被倾斜的元素上,不是父容器 - 别用
transition混合transform—— 它会强制触发 layout,抵消优化效果 - 移动端无
mousemove,需额外监听touchmove并换算touches[0]坐标
兼容性陷阱:transform-style: preserve-3d 不是万能解
这个属性只对拥有子元素的容器生效,单纯给按钮加它没用。如果你用伪元素模拟卡片翻转,preserve-3d 必须设在按钮的父容器(比如一个 div 包裹器),且该容器不能有 overflow: hidden —— 否则 3D 变换会被裁剪。
- IE 完全不支持
preserve-3d,倾斜效果退化为纯 2Drotate()是合理 fallback - Firefox 对
transform的小数精度更敏感,角度建议保留 1 位小数(如rotateX(2.5deg)) - 不要依赖
perspective值过大(>1000px),否则倾斜幅度不可控
实际最难的部分是让倾斜幅度和鼠标移动距离形成自然比例感——这没法靠一套固定公式解决,得在真实设备上反复调 multiplier 系数,尤其要兼顾触屏拖拽和鼠标快速划过的响应差异。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











