์ค๋ ํด๋ณผ ๊ฒ์ ์์ ๊ฐ์ด ์์ง์ด๋ ์นด๋ ๋ทฐ๋ฅผ ๋ง๋ค์ด๋ณผ ๊ฒ์ด๋ค.
Index.js
import React from 'react'
import ReactDOM from 'react-dom'
import { useSpring, animated } from 'react-spring'
import './styles.css'
const calc = (x, y) => [-(y - window.innerHeight / 2) / 20, (x - window.innerWidth / 2) / 20, 1.1]
const trans = (x, y, s) => `perspective(600px) rotateX(${x}deg) rotateY(${y}deg) scale(${s})`
function Card() {
const [props, set] = useSpring(() => ({ xys: [0, 0, 1], config: { mass: 5, tension: 350, friction: 40 } }))
return (
<animated.div
class="card"
onMouseMove={({ clientX: x, clientY: y }) => set({ xys: calc(x, y) })}
onMouseLeave={() => set({ xys: [0, 0, 1] })}
style={{ transform: props.xys.interpolate(trans) }}
/>
)
}
ReactDOM.render(<Card />, document.getElementById('root'))
์ฌ๊ธฐ์ calc ํจ์์ trans ํจ์๊ฐ ์ฐ์๋๋ฐ, ๊ฐ๋จํ๊ฒ ์ค๋ช ํ์๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
ํ์ฌ window์ฐฝ์ ๋์ด์ ๋๋น์ ์ค์ ๊ฐ๊ณผ ์์ง์์ ์์กด ๊ฐ๋ค์ ์ ๋ฐฐ์ด๋ก ๋ง๋ค์ด์ฃผ๊ณ , transํจ์๋ก css์ perspective ์ฝ๋๋ฅผ ์ฝ์ ํด์ค๋ค.
useSpring() ํจ์์์ ์ด๊ธฐ ์ด๋ฏธ์ง์ xys ๊ฐ์ 0, 0, 1๋ก ์ง์ ํด์ค๋ค.
๊ทธ๋ฆฌ๊ณ config์์ ๊ฐ์ข ํ ์ ๋ฐ ์ด๋ฏธ์ง ๊ฐ๋ค์ ๋ฃ์ด์ฃผ๊ณ , animation์ div๋ฅผ ํธ์ถํด mouse ์ด๋ฒคํธ ๋ฐ์ดํฐ ๊ฐ์ calc ํจ์์ ๋งค๊ฐ๋ณ์๋ก ๋ฃ๊ณ , ๊ฒฐ๊ณผ๋ฅผ ๋ณด๊ฐ์ผ๋ก ๋ณ๊ฒฝํ๊ณ style ํ๊ทธ๋ฅผ ์ฝ์ ์ํจ๋ค.
style.css
html,
body,
#root {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
background-color: white;
}
body {
font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, helvetica neue, helvetica, ubuntu,
roboto, noto, segoe ui, arial, sans-serif;
background: transparent;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
cursor: default;
}
#root {
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
background: #f0f0f0;
}
.card {
width: 45ch;
height: 45ch;
background: grey;
border-radius: 5px;
background-image: url(https://drscdn.500px.org/photo/435236/q%3D80_m%3D1500/v2?webp=true&sig=67031bdff6f582f3e027311e2074be452203ab637c0bd21d89128844becf8e40);
background-size: cover;
background-position: center center;
box-shadow: 0px 10px 30px -5px rgba(0, 0, 0, 0.3);
transition: box-shadow 0.5s;
will-change: transform;
border: 15px solid white;
}
.card:hover {
box-shadow: 0px 30px 100px -10px rgba(0, 0, 0, 0.4);
}
๋๊ธ