Skip to content

Commit

Permalink
add swipe test
Browse files Browse the repository at this point in the history
  • Loading branch information
Puyodead1 committed Sep 6, 2023
1 parent ef1ec8e commit e111c18
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { BannerContext } from "./contexts/BannerContext";
import useLogger from "./hooks/useLogger";
import AppPage from "./pages/AppPage";
import LogoutPage from "./pages/LogoutPage";
import SwipeTest from "./pages/SwipeTest";
import ChannelPage from "./pages/subpages/ChannelPage";
import { useAppStore } from "./stores/AppStore";
import { Globals } from "./utils/Globals";
Expand Down Expand Up @@ -78,6 +79,7 @@ function App() {
<Route path="/login" element={<UnauthenticatedGuard component={LoginPage} />} />
<Route path="/register" element={<UnauthenticatedGuard component={RegistrationPage} />} />
<Route path="/logout" element={<AuthenticationGuard component={LogoutPage} />} />
<Route path="/swipe" element={<SwipeTest />} />
<Route path="*" element={<NotFoundPage />} />
</Routes>
</Loader>
Expand Down
24 changes: 24 additions & 0 deletions src/hooks/useWindowResize.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// https://github.com/ruvkr/react-components-by-ruvkr/blob/master/src/hooks/useWindowResize.ts

import { useCallback, useEffect, useRef } from "react";

// eslint-disable-next-line @typescript-eslint/no-empty-function
export const useWindowResize = (callback: () => void = () => {}, interval = 100) => {
const resizeTimeout = useRef<NodeJS.Timeout | null>(null);

const resizeHandler = useCallback(() => {
if (resizeTimeout.current != null) clearTimeout(resizeTimeout.current);
resizeTimeout.current = setTimeout(() => {
resizeTimeout.current = null;
callback();
}, interval);
}, [interval, callback]);

useEffect(() => {
window.addEventListener("resize", resizeHandler);
return () => {
if (resizeTimeout.current != null) clearTimeout(resizeTimeout.current);
window.removeEventListener("resize", resizeHandler);
};
}, [resizeHandler]);
};
1 change: 1 addition & 0 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ body {
font-family: "Roboto", Arial, Helvetica, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
overflow: hidden;
}

code {
Expand Down
122 changes: 122 additions & 0 deletions src/pages/SwipeTest.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import { PanInfo, motion, useAnimation } from "framer-motion";
import React, { useState } from "react";
import styled from "styled-components";

const Container = styled.div`
display: flex;
flex-direction: row;
flex: 1;
justify-content: space-between;
`;

const Left = styled.div`
flex: 0 0 15%;
background-color: red;
z-index: -100;
`;

const Center = styled(motion.div)`
background-color: green;
z-index: 100;
position: absolute;
// cover screen
top: 0;
bottom: 0;
left: 0;
right: 0;
flex: 0 0 100%;
box-shadow: -20px 0 20px rgba(0, 0, 0, 0.5), 20px 0 20px rgba(0, 0, 0, 0.5);
`;

const Right = styled.div`
flex: 0 0 15%;
background-color: blue;
z-index: -100;
`;

function LeftComponent() {
return <Left>left</Left>;
}

function RightComponent() {
return <Right>right</Right>;
}

function CenterComponent() {
// on drag, animate center component to the left or right

// max the container should move - 15% either way
const maxWidth = window.innerWidth * 0.15;
// const x = motionValue(0);
// const trans = useTransform(x, [0, window.innerWidth], [0, -maxWidth]);
const [isDragging, setIsDragging] = useState(false);
const [initialX, setInitialX] = useState(0);

const elementControls = useAnimation();

const handleDragStart = (event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo) => {
setIsDragging(true);
setInitialX(info.point.x); // Store the initial X position
};

const handleDrag = (event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo) => {
if (isDragging) {
const distanceDragged = info.point.x - initialX; // Use initialX as the starting point

// Update the element's X position based on the distance dragged
elementControls.start({ x: distanceDragged });
}
};

const handleDragEnd = (event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo) => {
// Determine if the element should snap left or right based on position
const snapLeftThreshold = -100; // Adjust as needed
const snapRightThreshold = 100; // Adjust as needed

// Determine the velocity of the drag
const velocityThreshold = 600; // Adjust as needed

const distanceDragged = info.point.x - initialX;

if (Math.abs(info.velocity.x) <= velocityThreshold) {
// Snap back to the center for low velocity
elementControls.start({
x: 0,
transition: { type: "spring", stiffness: 300, damping: 20 },
});
} else if (info.velocity.x > velocityThreshold) {
elementControls.start({ x: maxWidth }); // Snap right for high velocity
} else if (info.velocity.x < -velocityThreshold) {
elementControls.start({ x: -maxWidth }); // Snap left for high velocity
} else if (distanceDragged < -snapLeftThreshold) {
elementControls.start({ x: -maxWidth }); // Snap left if dragged a certain distance to the left
} else if (distanceDragged > snapRightThreshold) {
elementControls.start({ x: maxWidth }); // Snap right if dragged a certain distance to the right
}
};

return (
<Center
drag="x"
dragConstraints={{ left: -maxWidth, right: maxWidth }} // Adjust as needed
onDragStart={handleDragStart}
onDrag={handleDrag}
onDragEnd={handleDragEnd}
animate={elementControls}
>
center
</Center>
);
}

export default function SwipeTest() {
const centerRef = React.useRef<HTMLDivElement | null>(null);

return (
<Container>
<LeftComponent />
<CenterComponent />
<RightComponent />
</Container>
);
}

0 comments on commit e111c18

Please sign in to comment.