让交互更加生动!有意思的鼠标跟随 3D 旋转动效
作者:chokcoco
来源:SegmentFault 思否社区
今天,群友问了这样一个问题,如下所示的鼠标跟随交互效果,如何实现:
简单分析一下,这个交互效果主要有两个核心:
借助了 CSS 3D 的能力
元素的旋转需要和鼠标的移动相结合
纯 CSS 实现元素的 3D 旋转
{
transform: rotate(90deg);
}
<div class="reverseRotate">
<div class="rotate">
<div class="content">正负旋转相消3D动画</div>
</div>
</div>

.rotate {
animation: rotate 5s linear infinite;
}
.reverseRotate {
animation: reverseRotate 5s linear infinite;
}
@keyframes rotate {
100% {
transform: rotate(360deg);
}
}
@keyframes reverseRotate {
100% {
transform: rotate(-360deg);
}
}


div {
transform-style: preserve-3d;
perspective: 100px;
}
@keyframes rotate {
0% {
transform: rotateX(0deg) rotateZ(0deg);
}
50% {
transform: rotateX(40deg) rotateZ(180deg);
}
100% {
transform: rotateX(0deg) rotateZ(360deg);
}
}

借助 Javascript 实现鼠标跟随 3D 旋转动效

鼠标活动区域
旋转物体本身
<body>
<div id="element"></div>
</body>

body {
width: 100vw;
height: 100vh;
transform-style: preserve-3d;
perspective: 500px;
}
div {
width: 200px;
height: 200px;
background: #000;
transform-style: preserve-3d;
}

div {
transform: rotateX(15deg) rotateY(30deg);
}

控制 X 方向的移动

当鼠标在中心右侧连续移动,元素绕 Y 轴移动,并且值从 0 开始,越来越大,范围为(0, +∞)deg
反之,当鼠标在中心左侧连续移动,元素绕 Y 轴移动,并且值从 0 开始,越来越小,范围为(-∞, 0)deg
const mouseOverContainer = document.getElementsByTagName("body")[0];
const element = document.getElementById("element");
mouseOverContainer.onmousemove = function(e) {
let box = element.getBoundingClientRect();
let calcY = e.clientX - box.x - (box.width / 2);
element.style.transform = "rotateY(" + calcY + "deg) ";
}

const multiple = 20;
const mouseOverContainer = document.getElementsByTagName("body")[0];
const element = document.getElementById("element");
mouseOverContainer.onmousemove = function(e) {
let box = element.getBoundingClientRect();
let calcY = (e.clientX - box.x - (box.width / 2)) / multiple;
element.style.transform = "rotateY(" + calcY + "deg) ";
}

控制 Y 方向的移动
const multiple = 20;
const mouseOverContainer = document.getElementsByTagName("body")[0];
const element = document.getElementById("element");
mouseOverContainer.onmousemove = function(e) {
let box = element.getBoundingClientRect();
let calcX = (e.clientY - box.y - (box.height / 2)) / multiple;
element.style.transform = "rotateX(" + calcX + "deg) ";
};

let calcX = (e.clientY - box.y - (box.height / 2)) / multiple * -1;
结合 X、Y 方向的移动
const multiple = 20;
const mouseOverContainer = document.getElementsByTagName("body")[0];
const element = document.getElementById("element");
function transformElement(x, y) {
let box = element.getBoundingClientRect();
let calcX = -(y - box.y - (box.height / 2)) / multiple;
let calcY = (x - box.x - (box.width / 2)) / multiple;
element.style.transform = "rotateX("+ calcX +"deg) "
+ "rotateY("+ calcY +"deg)";
}
mouseOverContainer.addEventListener('mousemove', (e) => {
window.requestAnimationFrame(function(){
transformElement(e.clientX, e.clientY);
});
});

设置平滑出入
div {
// 与上述保持一致...
transition: all .1s;
}
mouseOverContainer.addEventListener('mouseleave', (e) => {
window.requestAnimationFrame(function(){
element.style.transform = "rotateX(0) rotateY(0)";
});
});



关注公众号:拾黑(shiheibook)了解更多
赞助链接:
关注数据与安全,洞悉企业级服务市场:https://www.ijiandao.com/
四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/

随时掌握互联网精彩
- 澳元兑换人民币汇率2024年10月12日
- 澳元兑换人民币汇率2023年12月21日
- 新冠阳性大麦网拒绝退票?平台方回应来了
- 社区精选|万能的 CSS 渐变!单标签绘制一个足球场
- 性能旗舰不是偏科生!拯救者Y70全面评测
- 电商打价格战,到底能否有利于行业的发展?
- 谁是中国反垄断监管下的赢家,心动网络、哈啰出行、名创优品、元气森林、小红书?
- 899元的“华为Mate40保时捷”,把我看傻了!
- 工信部:提升5G服务质量,严守四条营销红线
- 交货期延至40周,现货价格翻几倍,MCU市场怎么了?
- 特斯拉虎入羊群?
- 华为:Mate 40每个生产线只需要14个人;阿里、腾讯、中国移动等133家企业签署网络数据安全自律公约【Do说】
赞助链接