Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Event for animations and dragging #107

Open
VityaSchel opened this issue Nov 18, 2024 · 1 comment
Open

Event for animations and dragging #107

VityaSchel opened this issue Nov 18, 2024 · 1 comment

Comments

@VityaSchel
Copy link

Describe the feature in detail (code, mocks, or screenshots encouraged)

The component already has onDrag callback which reports percentage of dragging, but I need to get currently visible portion of drawer on screen, including all animations and dragging

What type of pull request would this be?

New Feature

Provide relevant links or additional information.

No response

@VityaSchel
Copy link
Author

Here is a temporary patch for 0.3.2 version. It requires bezier-easing package from npm in order to run CSS cubic-bezier transitions in js, so just install it on your project where you use vaul-svelte. You can apply the patch by placing it to patches/[email protected] directory and running bun install. Then use onDrag prop on Drawer.Root with percentage argument on callback:

<Drawer.Root onDrag={(_, p) => console.log('progress in range [0-1]', p)} />
diff --git a/dist/internal/vaul.js b/dist/internal/vaul.js
index 6ced7405f010443705cbfef58060d050994842f6..584eb6161b4f95a5027d51acb015a4f119c17602 100644
--- a/dist/internal/vaul.js
+++ b/dist/internal/vaul.js
@@ -5,6 +5,24 @@ import { isIOS, preventScroll } from "./prevent-scroll.js";
 import { TRANSITIONS, VELOCITY_THRESHOLD } from "./constants.js";
 import { handleEscapeKeydown } from "./escape-keydown.js";
 import { handlePositionFixed } from "./position-fixed.js";
+import bezierEasing from 'bezier-easing'
+function animateTransition(callback, from, to) {
+    const startTime = performance.now()
+    const durationMs = TRANSITIONS.DURATION * 1000
+    const easing = bezierEasing(...TRANSITIONS.EASE)
+    function step(currentTime) {
+        const elapsed = currentTime - startTime
+        const progress = Math.min(elapsed / durationMs, 1)
+        const easedProgress = easing(progress)
+
+        callback(from + easedProgress * (to - from))
+
+        if (elapsed < durationMs) {
+            requestAnimationFrame(step)
+        }
+    }
+    requestAnimationFrame(step)
+}
 const CLOSE_THRESHOLD = 0.25;
 const SCROLL_LOCK_TIMEOUT = 100;
 const BORDER_RADIUS = 8;
@@ -419,6 +437,12 @@ export function createVaul(props) {
         if (!$drawerRef)
             return;
         const $direction = get(direction);
+        const drawerStyles = window.getComputedStyle($drawerRef)
+        const drawerOffsetFromSnapPoint = new DOMMatrix(drawerStyles.transform).m42
+        const drawerHeight = parseFloat(drawerStyles.height)
+        animateTransition(x => {
+            onDragProp?.(undefined, x / drawerHeight)
+        }, drawerOffsetFromSnapPoint, drawerHeight)
         onClose?.();
         set($drawerRef, {
             transform: isVertical($direction)
@@ -469,6 +493,12 @@ export function createVaul(props) {
             transform: "translate3d(0, 0, 0)",
             transition: `transform ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(",")})`,
         });
+        const drawerStyles = window.getComputedStyle($drawerRef)
+        const drawerOffsetFromSnapPoint = new DOMMatrix(drawerStyles.transform).m42
+        const drawerHeight = parseFloat(drawerStyles.height)
+        animateTransition(x => {
+            onDragProp?.(undefined, x / drawerHeight)
+        }, drawerOffsetFromSnapPoint, 0)
         set($overlayRef, {
             transition: `opacity ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(",")})`,
             opacity: "1",
@@ -566,6 +596,14 @@ export function createVaul(props) {
         }
         openTime.set(new Date());
         scaleBackground(true, props.backgroundColor);
+        setTimeout(() => {
+            const $drawerRef = get(drawerRef);
+            const drawerStyles = window.getComputedStyle($drawerRef)
+            const drawerHeight = parseFloat(drawerStyles.height)
+            animateTransition(x => {
+                onDragProp?.(undefined, 1 - (x / drawerHeight))
+            }, 0, drawerHeight)
+        }, 0)
     });
     effect([visible], ([$visible]) => {
         if (!$visible)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant