Framer Motion(2)
✔️ Drag
- DragConstraints
- 허용된 드래그 가능 영역에 제약 조건을 적용한다.
dragConstraints
에는 드래그 가능한 컴포넌트의 가장자리 거리를 정의한다.
(드래그 가능한 영역에 가장자리에서 얼마만큼까지 허용할 것인지 지정)
- 사용 방법
// px 이용
< motion.div drag="x" dragConstraints={{ left:- 50, right: 50, top: -50, bottom: 50 }}/ >
// ref 이용
const MyComponent = () => {
const constraintsRef = useRef(null)
return (
< motion.div ref={constraintsRef}>
< motion.div drag dragConstraints={constraintsRef} />
// → constraintsRef box 안에 제약되도록 설정
< /motion.div>
)
}
- dragSnapToOrigin
- dragElastic
- 외부 제약 조건에서 허용되는 이동 정도를 0 과 1 사이의 값으로 설정할 수 있다.
- 0 = 움직임 없음, 1 = 전체 움직임. 기본적으로 0.5로 설정한다.
움직임을 비활성화하기 위해 false로 설정할 수도 있다.
0일 경우, 애니메이션 없이(움직임 없이) 마우스를 따라 따라온다.
✔️ MotionValues
- 애니메이션 값의 상태(state)와 속도(velocity)를 추적한다. 애니메이션 내의 수치를 트래킹할 때 유용하다.
- MotionValue는 React State가 아니기 때문에 Motion Value값이 바뀌어도 리랜더링이 일어나지 않는다!
- 사용 방법
import { motion, useMotionValue } from "framer-motion";
export function MyComponent() {
const x = useMotionValue(0);
return < motion.div style={{ x }} />
// → motion.div 의 x 좌표를 추적
}
function App() {
const x = useMotionValue(0);
return(
<Wrapper>
<Box style={{ x:x }} drga="x" />
</Wrapper>
);
- 유저가
Box
를 드래그할때마다(style
의 x
좌표가 바뀔 때마다)
x
값은 업데이트된다.
x
값이 업데이트 될때마다, 그러니까 Motion Value 값이 바뀌어도 리랜더링이 일어나지 않기 때문에 x
의 실제 값을 확인하려면 useEffect()
내에서 x.get()
를 사용해야한다.
function App() {
const x = useMotionValue(0);
useEffect(() => {x.onChange(() => console.log(x.get())), [x]};
return(
<Wrapper>
<Box style={{ x:x }} drga="x" />
</Wrapper>
);
x.set(100)
x.get()
- MotionValue는 문자열이나 숫자가 될 수 있습니다.
get 메소드로 값을 읽을 수 있습니다.
- 하나의
MotionValue
출력값을 가져와서 어떤 방식으로든 변경한 다음 새로운 모션 값으로 출력해준다!
- 즉, Motion Value(x) 값을 다른 output 값으로 변환해준다!
하나의 모션 값의
- 예를들어, x 의 값 -400 를 1로 바꾸고 싶을때 사용!
- 사용 방법
import { useTransform } from "framer-motion";
function App() {
const x = useMotionValue(0)
const value = useTransform(
x,
[ -800, 0, 800 ], // input
[ 1, 0, 1 ] // output
);
return < motion.div drag="x" style={{ x, scale : value }} />
input
과 ouput
은 반드시 같은 배열 크기를 가져야 한다.
- 위와 같이 작성시,
x
의 값이 -800이라면 1로, 0 이라면 0 을, 800 이라면 1로 바꿔준다.
- 물론 0과 1 사이의 값도 전부 읽어온다. ( 0 → 0.001 → 0.002 → 0.003 ... 1 )
- x축을 따라 왼쪽으로 드래그 하면 커지고, 오른쪽으로 갈수록 작아지는 div 박스 완성
- 위와 같은 방법으로
background-color
도 변경할 수 있다.
function App() {
const x = useMotionValue(0);
const rotateZ = useTransform(x, [-800, 800], [-360, 360]);
const gradient = useTransform(
x,
[-800, 800],
[
"linear-gradient(135deg, rgb(0, 210, 238), rgb(0, 83, 238))",
"linear-gradient(135deg, rgb(0, 238, 155), rgb(238, 178, 0))",
]
);
return (
<Wrapper style={{ background : gradient }} >
<Box style={{ x, rotateZ }} drag="x" />
</Wrapper>
);
- 아래처럼,
왼쪽으로 갈수록 점점 파란색으로, 오른쪽으로 갈수록 초록색이 되는 그라디언트 애니메이션을 구현해봤다!
- 구)
useViewportScroll
- 뷰포트가 스크롤될 때 업데이트되는 MotionValues 를 리턴한다.
scrollX
, scrollY
scrollXProgress
, scrollYProgress
- 0~1 사이의 수평/수직 스크롤 (수직의 경우 가장 상단이 0, 가장 하단이 1)
import { useScroll } from "framer-motion"
const { scrollY, scrollYProgress } = useScroll();
useEffect(() => {
return scrollY.onChange((latest) => {
console.log("Page scroll: ", latest)
})
}, [scrollY])
- 실행 결과
- 수직으로 스크롤한 만큼의 픽셀이 콘솔에 찍히고(scrollY), 스크롤의 진행도가 0~1 사이의 값으로 찍히는걸 확인할 수 있다.(scrollYProgress)