@omicrxn/mercury
Version:
Mercury is a Svelte animation library powered by Motion. It simplifies complex animations with Svelte actions, provides layout and exit animations, and integrates seamlessly with Svelte features.
52 lines (51 loc) • 1.81 kB
JavaScript
import { animate as motionAnimate, motionValue, styleEffect } from 'motion';
import { DragGesture } from '@use-gesture/vanilla';
function runInertia(mv, to, velocity, bounds) {
return motionAnimate(mv, to, {
type: 'inertia',
velocity,
...(bounds ? { min: bounds[0], max: bounds[1] } : {})
});
}
export const handleDrag = (element, params) => {
if (params?.drag === true) {
const prevTouchAction = element.style.touchAction;
const prevCursor = element.style.cursor;
element.style.touchAction = 'none';
element.style.cursor = 'pointer';
const x = motionValue(0);
const y = motionValue(0);
styleEffect(element, { x, y });
const { axis, bounds, rubberband } = params.dragOptions ?? {};
let inertiaX;
let inertiaY;
const gesture = new DragGesture(element, ({ _bounds, event, first, last, offset: [ox, oy], velocity: [vx, vy], direction: [dx, dy] }) => {
if (first) {
inertiaX?.stop();
inertiaY?.stop();
params.onDragStart?.(event);
}
if (last) {
params.onDragEnd?.(event);
inertiaX = runInertia(x, ox, vx * dx * 100, _bounds?.[0]);
inertiaY = runInertia(y, oy, vy * dy * 100, _bounds?.[1]);
}
else {
x.jump(ox);
y.jump(oy);
}
}, {
from: () => [x.get(), y.get()],
axis,
bounds,
rubberband
});
return () => {
inertiaX?.stop();
inertiaY?.stop();
gesture.destroy();
element.style.touchAction = prevTouchAction;
element.style.cursor = prevCursor;
};
}
};