일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- sub태그
- iframe 태그
- not 의사클래스
- 자식결합자
- id 선택자
- reveal in file explorer
- iframe
- width속성
- br 태그
- height속성
- background-color 속성
- html tag i
- 전체 선택자
- Live Server
- html 태그
- i 태그
- 임베디드
- css
- 일반 형제 결합자
- 인접 형제 결합자
- tag html
- 아두이노
- RGBA
- Checked 의사 클래스
- RGB
- padding 속성
- focus 의사클래스
- html
- sup태그
- go live
- Today
- Total
so woon!
[FRAMER MOTION] Drag Constraint (드래그 제약) 본문
학습일 : 2023. 05. 12
이번에는 드래그에 제약을 걸어보도록 하겠다.
저번글까지를 보면 그냥 drag 라는prop을 전달하여
범위에 제약 없이 그냥 튕겨나가는 것을 볼 수 있었다.
drag="x"
or
drag="y"
그냥 drag가 아닌
drag="x" 를 작성해주게 되면 x축으로만 드래그 할 수 있게 되고,
drag="y" 를 작성해주게 되면 y축으로만 드래그 할 수 있게 된다.
<App.tsx>
drag="x"를 작성
function App() {
return (
<Wrapper>
<Box
drag="x"
whileDrag="drag"
variants={boxVariants}
whileHover="hover"
whileTap="tap"
></Box>
</Wrapper>
);
}
export default App;
결과
y축으로는 이동이 잠기게 되고
이렇게 하면 x축안에 갇혀있게 된다.
하지만 여전히 x축 안에서는 화면 밖으로 날라가게 된다.
<App.tsx>
drag="y"를 작성
function App() {
return (
<Wrapper>
<Box
drag="y"
whileDrag="drag"
variants={boxVariants}
whileHover="hover"
whileTap="tap"
></Box>
</Wrapper>
);
}
export default App;
결과
y축으로만 드래그 할 수 있게 된다.
dragConstraints
기본적으로 어떤 box를 만들 수 있다.
제약이 있는 box 이며,
드래깅이 허용될 수 있는 영역인 것이다.
dragConstraints={{ top: 0, bottom: 0, left: 0, right: 0 }} 이렇게 적어주었기 때문에
클릭을 떼면
아이템이 다시 중앙으로 돌아오게 된다.
하지만 이럴 필요가 없고 숏컷이 있음
뒤에도 나오겠지만 소개하자면
dragSnapToOrigin
이란 숏컷임
function App() {
return (
<Wrapper>
<Box
drag
dragConstraints={{ top: 0, bottom: 0, left: 0, right: 0 }}
whileDrag="drag"
variants={boxVariants}
whileHover="hover"
whileTap="tap"
></Box>
</Wrapper>
);
}
export default App;
실행결과
다른 박스에 넣어진 채로
드래깅 제약하기
그러기 위해 좀 더 큰 박스를 만들어주겠음;
import { styled } from "styled-components";
import { motion } from "framer-motion";
// style
const Wrapper = styled.div`
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
`;
// 큰 박스
const BiggerBox = styled.div`
width: 600px;
height: 600px;
background-color: rgba(255, 255, 255, 0.4);
border-radius: 40px;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
`;
// 박스
const Box = styled(motion.div)`
width: 200px;
height: 200px;
background-color: rgba(255, 255, 255, 1);
border-radius: 40px;
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1), 0 10px 20px rgba(0, 0, 0, 0.06);
`;
// Variants
const boxVariants = {
hover: { scale: 1.2, rotateZ: 90 },
tap: { borderRadius: "100px" },
};
function App() {
return (
<Wrapper>
<BiggerBox>
<Box
drag
dragConstraints={{ top: -200, bottom: 200, left: -200, right: 200 }} // (300 - 중앙박스의 절반)
variants={boxVariants}
whileHover="hover"
whileTap="tap"
></Box>
</BiggerBox>
</Wrapper>
);
}
export default App;
실행결과
이렇게 적어주는건 너무 귀찮은 과정이기 때문에
ref를 만들어주도록 하겠다.
import { styled } from "styled-components";
import { motion } from "framer-motion";
import { useRef } from "react";
// style
const Wrapper = styled.div`
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
`;
// 큰 박스
const BiggerBox = styled.div`
width: 600px;
height: 600px;
background-color: rgba(255, 255, 255, 0.4);
border-radius: 40px;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
`;
// 박스
const Box = styled(motion.div)`
width: 200px;
height: 200px;
background-color: rgba(255, 255, 255, 1);
border-radius: 40px;
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1), 0 10px 20px rgba(0, 0, 0, 0.06);
`;
// Variants
const boxVariants = {
hover: { scale: 1.2, rotateZ: 90 },
tap: { borderRadius: "100px" },
};
function App() {
// useRef 작성, 기본값 null, 타입스크립트 HTMLDIVELEMENT 적용
// 작성 후 BiggerBox 컴포넌트에 전달
const biggerBoxRef = useRef<HTMLDivElement>(null);
return (
<Wrapper>
<BiggerBox ref={biggerBoxRef}>
<Box
drag
dragConstraints={{ top: -200, bottom: 200, left: -200, right: 200 }} // (300 - 중앙박스의 절반)
variants={boxVariants}
whileHover="hover" // hover시 90도 z축 회전, 1.2배 커짐
whileTap="tap" // 클릭했을 경우 scale1로 돌리고 원이 됨
></Box>
</BiggerBox>
</Wrapper>
);
}
export default App;
ref를 작성해주고 적용해주었다.
그런다음 Box에게 제약을 걸어줄 것이다.
dragConstraints 안에 적어주었던 내용은 이제 없애고
dragConstraints={biggerBoxRef}
이렇게 적어주도록 한다.
준비가 끝났다.
지금까지 한 것은
레퍼런스를 만들었고, 레퍼런스를 BiggerBox에 적용했으며,
그 안에 속한 Box 컴포넌트에 constraints를 걸어주었는데
BiggerBox의 가장자리까지라고 설정해 주게 된 것이다.
실행결과
결과가 똑같음
dragSnapToOrigin
dragSnapToOrigin prop을 써주면
큰 박스에 작은 박스가 튕긴 후
중앙으로 돌아갈 수 있게 한다.
실행결과
dragElastic
dragElastic={값} 이렇게 써주면 된다.
dragElastic prop은 탄성 효과이다.
기본값은 0.5이며, 0과 1 사이의 값을 주어야만 한다.
값이 작을 수록 무거운 용수철이 달려있다 생각하면 될듯.
값 1을 주게 되면 용수철이 달려있지 않은 것처럼 느껴짐.
import { styled } from "styled-components";
import { motion } from "framer-motion";
import { useRef } from "react";
// style
const Wrapper = styled.div`
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
`;
// 큰 박스
const BiggerBox = styled.div`
width: 600px;
height: 600px;
background-color: rgba(255, 255, 255, 0.4);
border-radius: 40px;
display: flex;
align-items: center;
justify-content: center;
/* overflow: hidden; */
`;
// 박스
const Box = styled(motion.div)`
width: 200px;
height: 200px;
background-color: rgba(255, 255, 255, 1);
border-radius: 40px;
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1), 0 10px 20px rgba(0, 0, 0, 0.06);
`;
// Variants
const boxVariants = {
hover: { scale: 1.2, rotateZ: 90 },
tap: { borderRadius: "100px" },
};
function App() {
const biggerBoxRef = useRef<HTMLDivElement>(null);
return (
<Wrapper>
<BiggerBox ref={biggerBoxRef}>
<Box
drag
dragElastic={0.5} // 값이 작을수록 무거운 용수철
dragSnapToOrigin
dragConstraints={biggerBoxRef}
variants={boxVariants}
whileHover="hover"
whileTap="tap"
></Box>
</BiggerBox>
</Wrapper>
);
}
export default App;
실행결과
'Framer Motion > 개념정리' 카테고리의 다른 글
[FRAMER MOTION] useScroll (0) | 2023.05.14 |
---|---|
[FRAMER MOTION] useMotionValue + useTransform 사용하기 (0) | 2023.05.13 |
[FRAMER MOTION] Dragging (0) | 2023.05.11 |
[FRAMER MOTION] Gestures (0) | 2023.05.11 |
[FRAMER MOTION] Variants (1) | 2023.05.11 |