UNPKG

svelte-motion

Version:

Svelte animation library based on the React library framer-motion.

308 lines (307 loc) 8.87 kB
/** based on framer-motion@4.1.17, Copyright (c) 2018 Framer B.V. */ import { RefObject } from "react"; import { PanInfo } from "../PanSession"; import { Inertia, TargetAndTransition } from "../../types"; import { Axis, BoundingBox2D } from "../../types/geometry"; import { DragControls } from "./use-drag-controls"; import { MotionValue } from "../../value"; import { VariantLabels } from "../../motion/types"; export declare type DragHandler = (event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo) => void; export declare type DragElastic = boolean | number | Partial<BoundingBox2D>; export interface ResolvedConstraints { x: Partial<Axis>; y: Partial<Axis>; } export interface ResolvedElastic { x: Axis; y: Axis; } /** * @public */ export interface DragHandlers { /** * Callback function that fires when dragging starts. * * @motion * * ```jsx * <MotionDiv * drag * onDragStart={ * (event, info) => console.log(info.point.x, info.point.y) * } * /> * ``` * * @public */ onDragStart?(event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo): void; /** * Callback function that fires when dragging ends. * * @motion * * ```jsx * <MotionDiv * drag * onDragEnd={ * (event, info) => console.log(info.point.x, info.point.y) * } * /> * ``` * * @public */ onDragEnd?(event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo): void; /** * Callback function that fires when the component is dragged. * * @motion * * ```jsx * <MotionDiv * drag * onDrag={ * (event, info) => console.log(info.point.x, info.point.y) * } * /> * ``` * * @public */ onDrag?(event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo): void; /** * Callback function that fires a drag direction is determined. * * @motion * * ```jsx * <MotionDiv * drag * dragDirectionLock * onDirectionLock={axis => console.log(axis)} * /> * ``` * * @public */ onDirectionLock?(axis: "x" | "y"): void; /** * Callback function that fires when drag momentum/bounce transition finishes. * * @motion * * ```jsx * <MotionDiv * drag * onDragTransitionEnd={() => console.log('Drag transition complete')} * /> * ``` * * @public */ onDragTransitionEnd?(): void; } /** * @public */ export declare type InertiaOptions = Partial<Omit<Inertia, "velocity" | "type">>; /** * @public */ export interface DraggableProps extends DragHandlers { /** * Enable dragging for this element. Set to `false` by default. * Set `true` to drag in both directions. * Set `"x"` or `"y"` to only drag in a specific direction. * * @motion * * ```jsx * <MotionDiv drag="x" /> * ``` */ drag?: boolean | "x" | "y"; /** * Properties or variant label to animate to while the drag gesture is recognised. * * ```jsx * <MotionDiv whileDrag={{ scale: 1.2 }} /> * ``` */ whileDrag?: VariantLabels | TargetAndTransition; /** * If `true`, this will lock dragging to the initially-detected direction. Defaults to `false`. * * @motion * * ```jsx * <MotionDiv drag dragDirectionLock /> * ``` */ dragDirectionLock?: boolean; /** * Allows drag gesture propagation to child components. Set to `false` by * default. * * @motion * * ```jsx * <MotionDiv drag="x" dragPropagation /> * ``` */ dragPropagation?: boolean; /** * Applies constraints on the permitted draggable area. * * It can accept an object of optional `top`, `left`, `right`, and `bottom` values, measured in pixels. * This will define a distance the named edge of the draggable component. * * Alternatively, it can accept a `ref` to another component created with React's `useRef` hook. * This `ref` should be passed both to the draggable component's `dragConstraints` prop, and the `ref` * of the component you want to use as constraints. * * @motion * * ```jsx * // In pixels * <MotionDiv * drag="x" * dragConstraints={{ left: 0, right: 300 }} * /> * * // As a ref to another component * let constraintsRef; * * <MotionDiv bind:this={constraintsRef}> * <MotionDiv drag dragConstraints={constraintsRef} /> * </MotionDiv> * ) * } * ``` */ dragConstraints?: false | Partial<BoundingBox2D> | RefObject<Element>; /** * The degree of movement allowed outside constraints. 0 = no movement, 1 = * full movement. * * Set to `0.5` by default. Can also be set as `false` to disable movement. * * By passing an object of `top`/`right`/`bottom`/`left`, individual values can be set * per constraint. Any missing values will be set to `0`. * * @motion * * ```jsx * <MotionDiv * drag * dragConstraints={{ left: 0, right: 300 }} * dragElastic={0.2} * /> * ``` */ dragElastic?: DragElastic; /** * Apply momentum from the pan gesture to the component when dragging * finishes. Set to `true` by default. * * @motion * * ```jsx * <MotionDiv * drag * dragConstraints={{ left: 0, right: 300 }} * dragMomentum={false} * /> * ``` */ dragMomentum?: boolean; /** * Allows you to change dragging inertia parameters. * When releasing a draggable Frame, an animation with type `inertia` starts. The animation is based on your dragging velocity. This property allows you to customize it. * See {@link https://framer.com/api/animation/#inertia | Inertia} for all properties you can use. * * @motion * * ```jsx * <MotionDiv * drag * dragTransition={{ bounceStiffness: 600, bounceDamping: 10 }} * /> * ``` */ dragTransition?: InertiaOptions; /** * Usually, dragging is initiated by pressing down on a component and moving it. For some * use-cases, for instance clicking at an arbitrary point on a video scrubber, we * might want to initiate dragging from a different component than the draggable one. * * By creating a `dragControls` using the `useDragControls` hook, we can pass this into * the draggable component's `dragControls` prop. It exposes a `start` method * that can start dragging from pointer events on other components. * * @motion * * ```jsx * const dragControls = useDragControls() * * function startDrag(event) { * dragControls.start(event, { snapToCursor: true }) * } * * <div onPointerDown={startDrag} /> * <MotionDiv drag="x" dragControls={dragControls} /> * ``` */ dragControls?: DragControls; /** * By default, if `drag` is defined on a component then an event listener will be attached * to automatically initiate dragging when a user presses down on it. * * By setting `dragListener` to `false`, this event listener will not be created. * * @motion * * ```jsx * const dragControls = useDragControls() * * function startDrag(event) { * dragControls.start(event, { snapToCursor: true }) * } * * <div onPointerDown={startDrag} /> * <MotionDiv * drag="x" * dragControls={dragControls} * dragListener={false} * /> * ``` */ dragListener?: boolean; /** * If `dragConstraints` is set to a React ref, this callback will call with the measured drag constraints. * * @public */ onMeasureDragConstraints?: (constraints: BoundingBox2D) => BoundingBox2D | void; /** * Usually, dragging uses the layout project engine, and applies transforms to the underlying VisualElement. * Passing MotionValues as _dragX and _dragY instead applies drag updates to these motion values. * This allows you to manually control how updates from a drag gesture on an element is applied. * * @public */ _dragX?: MotionValue<number>; /** * Usually, dragging uses the layout project engine, and applies transforms to the underlying VisualElement. * Passing MotionValues as _dragX and _dragY instead applies drag updates to these motion values. * This allows you to manually control how updates from a drag gesture on an element is applied. * * @public */ _dragY?: MotionValue<number>; }