본문 바로가기
Frontend/- Framer motion

Framer motion : 제스처(Gestures)에 대해서 (2) drag, pan

by 코딩쥐 2024. 9. 28.

hover, focus, tap에 대한 내용은 따로 작성한 글이 있다. 이번 글에서는 제스체 중에 drag와 pan에 대해서 알아보고자 한다.

제스처 설명
hover 마우스 커서가 요소 위에 올려졌을 때 발생하는 제스처
focus 요소가 포커스를 받을 때 발생하는 제스처
tap 사용자가 요소를 클릭하거나 터치했을 때 발생하는 제스처
drag 사용자가 요소를 클릭하고 드래그하여 위치를 변경할 수 있는 제스처
pan 사용자가 요소를 누르고 기존의 화면서에서 3픽셀 이동해야 인식되는 제스처

 

Drag관련 이벤트

이벤트는 사용자가 요소를 클릭하고 드래그하여 다른 위치로 이동할 수 있도록 하는 기능을 제공한다. 

이벤트 설명
drag 드래그 가능 여부를 설정한다. 
onDragStart 사용자가 드래그를 시작할 때 호출되는 함수 (드래그 시작 시)
onDrag 드래그 중에 호출되는 함수로, 요소가 이동할 때마다 발생
onDragEnd 사용자가 드래그를 종료했을 때 호출되는 함수 (드래그 종료 시)
whileDrag 요소를 드래그하는 동안 적용할 애니메이션 상태정의
프로퍼티  설명
dragSnapToOrigin 사용자가 드래그를 종료한 후 요소가 원래 위치로 돌아가도록 설정하는 프로퍼티
dragConstraints 드래그가 가능한 범위를 제한하는 프로퍼티
dragElastic 드래그하는 동안의 탄성을 조절하는 프로퍼티
(기본값: 0.5, 값이 클수록 탄성효과 큼)
dragMomentum 드래그 후 요소가 이동할 때 관성을 설정하는 프로퍼티
(true : 드래그 종료 후 관성에 따라 움직임)
import { motion } from "framer-motion";
import styles from "./Comp01.module.css"
import { useRef } from "react";

export default function Comp01() {
    const containerRef = useRef(null);

    return (
        //부모요소로 드래그 범위 제한
        <div className={styles.container} ref={containerRef}>
            <motion.div className={styles.box}
                drag // 드래그 가능하게 설정
                dragConstraints={containerRef} // 드래그 범위 제한
                dragSnapToOrigin={true}  // 원래 위치로 돌아오게 설정
                dragElastic={0.2} // 드래그 탄성 설정
                dragMomentum={true} // 관성 적용
                onDragStart={() => console.log("onDragStart 실행")}
                onDrag={() => console.log("onDrag 실행")}
                onDragEnd={() => console.log("onDragEnd 실행")}
                whileDrag={{ scale: 1.1, backgroundColor: "rgb(144, 238, 144)" }}
            />
        </div>
    );
}

dragControls

dragControls를 사용하여 다른 요소를 통해 드래그를 수동으로 시작하고 중지할 수 잇도록 설정할 수 있다.

속성 및 함수 설명
useDragControls 드래그 컨트롤러를 생성하는 데 사용된다. 
controls.start(event, options) 드래그를 시작하는 메서드로 event는 포인터 객체를 나타내고, options에는 snapToCursor 속성을 설정할 수 있다. snapToCursor은 드래그 시작 시에 요소의 위치를 마우스 커서에 맞추는 기능이다.
drag.Listener 드래그 이벤트를 수신할 수 있는 리스너를 설정한다. 
false로 설정 시에 자동 드래그 시작을 비활성화 할 수 있다.
controls.updateConstraints() 드래그 가능한 요소의 제약 조건을 업데이트 한다.
import { motion, useDragControls } from "framer-motion";
import styles from "./Comp01.module.css"

export default function Comp01() {
    // useDragControls 생성
    const controls = useDragControls();

    function startDrag(e) {
        // 드래그 되는 옵션을 활성화 한다. 
        controls.start(e, { snapToCursor: true });
    }

    return (
        <div>
            <motion.div className={styles.box}
                drag
                // controls라는 useDragControls를 해당 객체와 연결
                dragControls={controls}
                // 자동 드래그가 되는 것을 방지
                dragListener={false}
            />
            <button onClick={startDrag}>드래그 시작</button>
        </div>
    );
}

 

dragTransition

Framer motion의 drag의 경우에는 dragTransition 속성을 통해서 드래그 동작이 끝난 후 요소가 이동하는 애니메이션의 물리적 특성을 정의할 수 있다.

속성 설명 기본값
bounceStriffness 요소가 드래그 된 후 반동하는 강도, 값이 클수록 반동 강해짐 300
bounceDamping 요소가 드래그 된 후 반동하는 감쇠, 값이 클수록 반동이 빨리 멈춤 10
power 드래그 된 요소의 속조를 조정, 값이 클수록 더 멀리 이동 0.8
timeConstant 요소가 드래그된 후 감속하는 시간 설정 750
import { motion } from "framer-motion";
import styles from "./Comp01.module.css"
import { useRef } from "react";

export default function Comp01() {
    const containerRef = useRef(null);

    return (
        //부모요소로 드래그 범위 제한
        <div className={styles.container} ref={containerRef}>
            <motion.div className={styles.box}
                drag // 드래그 가능하게 설정
                dragConstraints={containerRef} // 드래그 범위 제한
                dragElastic={0.2} // 드래그 탄성 설정
                dragMomentum={true} // 관성 적용
                onDragStart={() => console.log("onDragStart 실행")}
                onDrag={() => console.log("onDrag 실행")}
                onDragEnd={() => console.log("onDragEnd 실행")}
                whileDrag={{ scale: 1.1, backgroundColor: "rgb(144, 238, 144)" }}

                // 드래그 후의 반동 효과 설정
                dragTransition={{
                    bounceStiffness: 500, // 반동 강도
                    bounceDamping: 8, // 반동 감쇠
                    power: 1.0, // 속도 조정
                    timeConstant: 750, // 감속 시간
                }}
            />
        </div>
    );
}


Pan관련 이벤트

Pan의 경우에는 요소를 클릭한 후 3픽셀 이동하면 인식하는데, 직접적인 이벤트를 주는 드래그와는 다르게 주로 요소의 위치 파악이나 인터페이스의 탐색에 사용된다. Drag 제스처와 함께 사용하여 상호보완하여 이벤트를 만들 수 있다. 

  • event : 기본적인 DOM 이벤트 객체로, 이벤트가 발생한 요소와 관련된 정보를 포함한다.
  • info 
    - point : Pan 동작의 현재 위치를 나타낸다. point.x와 point.y를 통해 좌표를 얻을 수 있다.
    - delta : 마지막 이벤트 이후에 이동한 거리를 나타낸다. delta.x와 delta.y를 통해 변화량을 얻을 수 있다. 
    - offset : Pan 동작의 시작 위치로부터 offset을 나타낸다. offset.x와 offset.y를 통해 얻을 수 있다. 
    - velocity: Pan 동작의 속도를 나타낸다. velocity.x와 velocity.y를 통해 얻을 수 있다. 
이벤트 설명
onPan 요소를 클릭한 후 3픽셀 이동하면 호출되는 함수 
import { motion } from "framer-motion";
import styles from "./Comp01.module.css"
import { useState } from "react";

export default function Comp01() {
    const [position, setPosition] = useState({ x: 0, y: 0 });

    const handlePan = (event, info) => {
        setPosition({ x: info.point.x, y: info.point.y });
        console.log("현재 Pan 위치 : ", info.point);
        console.log("이벤트 타입 : ", event.type);
        console.log("변화량 : ", info.delta);
        console.log("오프셋 : ", info.offset);
        console.log("속도 : ", info.velocity);
    }

    return (
        <div className={styles.container}>
            <motion.div className={styles.box}
                drag
                onPan={handlePan}
            />
        </div>
    );
}