Skip to content

Commit

Permalink
fix: add pull-down visual effect
Browse files Browse the repository at this point in the history
  • Loading branch information
igordanchenko committed May 15, 2023
1 parent 3ec038b commit ac6013f
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 13 deletions.
96 changes: 85 additions & 11 deletions src/modules/Controller/Controller.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
makeComposePrefix,
makeUseContext,
parseLengthPercentage,
round,
} from "../../utils.js";
import {
SubscribeSensors,
Expand Down Expand Up @@ -65,12 +66,15 @@ export function Controller({ children, ...props }: ComponentProps) {

const [swipeState, setSwipeState] = React.useState(SwipeState.NONE);
const swipeOffset = React.useRef(0);
const pullDownOffset = React.useRef(0);
const pullDownOpacity = React.useRef(1);

const { registerSensors, subscribeSensors } = useSensors<HTMLDivElement>();
const { subscribe, publish } = useEvents();

const cleanupAnimationIncrement = useDelay();
const cleanupSwipeOffset = useDelay();
const cleanupPullDownOffset = useDelay();

const { containerRef, setContainerRef, containerRect } = useContainerRect<HTMLDivElement>();
const handleContainerRef = useForkRef(usePreventSwipeNavigation(), setContainerRef);
Expand Down Expand Up @@ -104,6 +108,70 @@ export function Controller({ children, ...props }: ComponentProps) {
containerRef.current?.style.setProperty(cssVar("swipe_offset"), `${Math.round(offset)}px`);
};

const pullDownEnabled = controller.closeOnPullDown;

const setPullDownOffset = (offset: number) => {
pullDownOffset.current = offset;
pullDownOpacity.current = (() => {
const threshold = 60;
const minOpacity = 0.5;
return Math.min(Math.max(round(1 - (offset / threshold) * (1 - minOpacity), 2), minOpacity), 1);
})();

containerRef.current?.style.setProperty(cssVar("pull_down_offset"), `${Math.round(offset)}px`);
containerRef.current?.style.setProperty(cssVar("pull_down_opacity"), `${pullDownOpacity.current}`);
};

const { prepareAnimation: preparePullDownAnimation } = useAnimation<{
rect: DOMRect;
opacity: number;
duration: number;
}>(carouselRef, (snapshot, rect, translate) => {
if (carouselRef.current && containerRect) {
return {
keyframes: [
{
transform: `translate(0, ${snapshot.rect.y - rect.y + translate.y}px)`,
opacity: snapshot.opacity,
},
{ transform: "translate(0, 0)", opacity: 1 },
],
duration: snapshot.duration,
easing: animation.easing.fade,
};
}
return undefined;
});

const pullDown = (offset: number, cancel?: boolean) => {
if (pullDownEnabled) {
setPullDownOffset(offset);

let duration = 0;

if (carouselRef.current) {
duration = animation.fade * (cancel ? 2 : 1);

preparePullDownAnimation({
rect: carouselRef.current.getBoundingClientRect(),
opacity: pullDownOpacity.current,
duration,
});
}

cleanupPullDownOffset(() => {
setPullDownOffset(0);
setSwipeState(SwipeState.NONE);
}, duration);

setSwipeState(SwipeState.ANIMATION);

if (!cancel) {
close();
}
}
};

const { prepareAnimation, isAnimationPlaying } = useAnimation<{ rect: DOMRect; index: number }>(
carouselRef,
(snapshot, rect, translate) => {
Expand All @@ -117,14 +185,14 @@ export function Controller({ children, ...props }: ComponentProps) {
return {
keyframes: [
{
transform: `translateX(${
transform: `translate(${
rtl(state.globalIndex - snapshot.index) * (containerRect.width + spacingValue) +
snapshot.rect.x -
rect.x +
translate.x
}px)`,
}px, 0)`,
},
{ transform: "translateX(0)" },
{ transform: "translate(0, 0)" },
],
duration: state.animation.duration,
easing: state.animation.easing,
Expand Down Expand Up @@ -235,20 +303,20 @@ export function Controller({ children, ...props }: ComponentProps) {

const pullDownParams = [
// onPullDownStart
() => {},
// onPullDownProgress
() => {},
// onPullDownFinish
() => {
if (controller.closeOnPullDown) {
close();
if (pullDownEnabled) {
setSwipeState(SwipeState.PULL_DOWN);
}
},
// onPullDownProgress
(offset: number) => setPullDownOffset(offset),
// onPullDownFinish
(offset: number) => pullDown(offset),
// onPullDownCancel
() => {},
(offset: number) => pullDown(offset, true),
] as const;

usePointerSwipe(...swipeParams, ...pullDownParams);
usePointerSwipe(...swipeParams, pullDownEnabled, ...pullDownParams);

useWheelSwipe(swipeState, ...swipeParams);

Expand Down Expand Up @@ -337,6 +405,12 @@ export function Controller({ children, ...props }: ComponentProps) {
...(swipeState === SwipeState.SWIPE
? { [cssVar("swipe_offset")]: `${Math.round(swipeOffset.current)}px` }
: null),
...(swipeState === SwipeState.PULL_DOWN
? {
[cssVar("pull_down_offset")]: `${Math.round(pullDownOffset.current)}px`,
[cssVar("pull_down_opacity")]: `${pullDownOpacity.current}`,
}
: null),
...(controller.touchAction !== "none"
? { [cssVar("controller_touch_action")]: controller.touchAction }
: null),
Expand Down
1 change: 1 addition & 0 deletions src/modules/Controller/SwipeState.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export enum SwipeState {
NONE,
SWIPE,
PULL_DOWN,
ANIMATION,
}
3 changes: 2 additions & 1 deletion src/modules/Controller/usePointerSwipe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export function usePointerSwipe<T extends Element = Element>(
onSwipeProgress: (offset: number) => void,
onSwipeFinish: (offset: number, duration: number) => void,
onSwipeCancel: (offset: number) => void,
pullDownEnabled: boolean,
onPullDownStart: () => void,
onPullDownProgress: (offset: number) => void,
onPullDownFinish: (offset: number, duration: number) => void,
Expand Down Expand Up @@ -126,7 +127,7 @@ export function usePointerSwipe<T extends Element = Element>(
// start swipe gesture
startGesture(Gesture.SWIPE);
onSwipeStart();
} else if (Math.abs(deltaY) > Math.abs(deltaX) && Math.abs(deltaY) > SWIPE_THRESHOLD) {
} else if (pullDownEnabled && Math.abs(deltaY) > Math.abs(deltaX) && deltaY > SWIPE_THRESHOLD) {
// start pull-down gesture
startGesture(Gesture.PULL_DOWN);
onPullDownStart();
Expand Down
3 changes: 2 additions & 1 deletion src/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@
justify-content: center;
align-items: stretch;
width: calc(100% + (var(--yarl__carousel_slides_count) - 1) * (100% + var(--yarl__carousel_spacing_px, 0) * 1px + var(--yarl__carousel_spacing_percent, 0) * 1%));
transform: translateX(var(--yarl__swipe_offset, 0px));
transform: translate(var(--yarl__swipe_offset, 0px), var(--yarl__pull_down_offset, 0px));
opacity: var(--yarl__pull_down_opacity, 1);

&_with_slides {
column-gap: calc(var(--yarl__carousel_spacing_px, 0) * 1px + 100 / (100 * var(--yarl__carousel_slides_count) + (var(--yarl__carousel_slides_count) - 1) * var(--yarl__carousel_spacing_percent, 0)) * var(--yarl__carousel_spacing_percent, 0) * 1%);
Expand Down

0 comments on commit ac6013f

Please sign in to comment.