React Js中的3D卡片悬停效果



我正在尝试在React中创建3D卡片悬停效果,但悬停行为与纯javascript不同。

我不明白为什么同样的逻辑,行为却不同。

纯Javascript演示:https://codepen.io/markmiro/pen/wbqMPa

<div class="card">
3D Card
<div class="glow" />
</div>
* {
box-sizing: border-box;
}
html, body {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
body {
font-family: system-ui, sans-serif;
perspective: 1500px;
background: linear-gradient(white, #efefef);
}
.card {
font-weight: bold;
padding: 1em;
text-align: right;
color: #181a1a;

width:  300px;
height: 400px;
box-shadow: 0 1px 5px #00000099;

border-radius: 10px;
background-image: url(https://images.unsplash.com/photo-1557672199-6e8c8b2b8fff?ixlib=rb-1.2.1&auto=format&fit=crop&w=934&q=80);
background-size: cover;

position: relative;

transition-duration: 300ms;
transition-property: transform, box-shadow;
transition-timing-function: ease-out;
transform: rotate3d(0);
}
.card:hover {
transition-duration: 150ms;
box-shadow: 0 5px 20px 5px #00000044;
}
.card .glow {
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;

background-image: radial-gradient(circle at 50% -20%, #ffffff22, #0000000f);
}
const $card = document.querySelector('.card');
let bounds;
function rotateToMouse(e) {
const mouseX = e.clientX;
const mouseY = e.clientY;
const leftX = mouseX - bounds.x;
const topY = mouseY - bounds.y;
const center = {
x: leftX - bounds.width / 2,
y: topY - bounds.height / 2
}
const distance = Math.sqrt(center.x**2 + center.y**2);

$card.style.transform = `
scale3d(1.07, 1.07, 1.07)
rotate3d(
${center.y / 100},
${-center.x / 100},
0,
${Math.log(distance)* 2}deg
)
`;

console.log(center.y / 100) ;$card.querySelector('.glow').style.backgroundImage = `
radial-gradient(
circle at
${center.x * 2 + bounds.width/2}px
${center.y * 2 + bounds.height/2}px,
#ffffff55,
#0000000f
)
`;
}
$card.addEventListener('mouseenter', () => {
bounds = $card.getBoundingClientRect();
document.addEventListener('mousemove', rotateToMouse);
});
$card.addEventListener('mouseleave', () => {
document.removeEventListener('mousemove', rotateToMouse);
$card.style.transform = '';
$card.style.background = '';
});

React实现:https://stackblitz.com/edit/react-eghmd8

我已经用useRef钩子改变了所有的queryselectors

似乎需要将此属性perspective: 1500px添加到组件的输出容器中才能正常工作。

fork live示例,修复:

style.css中创建一个类:

.app {
perspective: 1500px;
}

App.js中将className添加到输出容器中:

// 👇 Add the class here
return (
<div className="app">
<div
ref={inputRef}
className="card"
onMouseLeave={removeListener}
onMouseMove={rotateToMouse}
>
3D Card
<div ref={glowRef} className="glow" />
</div>
</div>
);

可能还有其他问题需要解决,但希望这仍然是一个参考。

最新更新