Skip to content

Commit

Permalink
main 🧊 add use parallax, add use device orientation, add use screen o…
Browse files Browse the repository at this point in the history
…rientation
  • Loading branch information
debabin committed Sep 2, 2024
1 parent 5d7de03 commit bcfe1eb
Show file tree
Hide file tree
Showing 10 changed files with 508 additions and 12 deletions.
2 changes: 2 additions & 0 deletions src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export * from './useDebounceCallback/useDebounceCallback';
export * from './useDebounceValue/useDebounceValue';
export * from './useDefault/useDefault';
export * from './useDeviceMotion/useDeviceMotion';
export * from './useDeviceOrientation/useDeviceOrientation';
export * from './useDidUpdate/useDidUpdate';
export * from './useDisclosure/useDisclosure';
export * from './useDocumentEvent/useDocumentEvent';
Expand Down Expand Up @@ -76,6 +77,7 @@ export * from './useRenderCount/useRenderCount';
export * from './useRenderInfo/useRenderInfo';
export * from './useRerender/useRerender';
export * from './useResizeObserver/useResizeObserver';
export * from './useScreenOrientation/useScreenOrientation';
export * from './useScript/useScript';
export * from './useSessionStorage/useSessionStorage';
export * from './useSet/useSet';
Expand Down
4 changes: 2 additions & 2 deletions src/hooks/useDeviceMotion/useDeviceMotion.demo.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { useDeviceMotion } from './useDeviceMotion';

const Demo = () => {
const deviceMotionData = useDeviceMotion();
const deviceMotion = useDeviceMotion();

return (
<pre lang='json'>
<b>Device motion data:</b>
<p>{JSON.stringify(deviceMotionData, null, 2)}</p>
<p>{JSON.stringify(deviceMotion, null, 2)}</p>
</pre>
);
};
Expand Down
15 changes: 9 additions & 6 deletions src/hooks/useDeviceMotion/useDeviceMotion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ export interface UseDeviceMotionReturn {
}

export interface UseDeviceMotionParams {
/** The delay in milliseconds */
delay?: number;
/** The callback function to be invoked */
callback?: (event: DeviceMotionEvent) => void;
/** Whether to enable the hook */
enabled?: boolean;
}

Expand All @@ -31,7 +34,7 @@ export interface UseDeviceMotionParams {
export const useDeviceMotion = (params?: UseDeviceMotionParams) => {
const enabled = params?.enabled ?? true;
const delay = params?.delay ?? 1000;
const [deviceMotionData, setDeviceMotionData] = useState<UseDeviceMotionReturn>({
const [value, setValue] = useState<UseDeviceMotionReturn>({
interval: 0,
rotationRate: { alpha: null, beta: null, gamma: null },
acceleration: { x: null, y: null, z: null },
Expand All @@ -45,18 +48,18 @@ export const useDeviceMotion = (params?: UseDeviceMotionParams) => {

const onDeviceMotion = throttle<[DeviceMotionEvent]>((event) => {
internalCallbackRef.current?.(event);
setDeviceMotionData({
setValue({
interval: event.interval,
rotationRate: {
...deviceMotionData.rotationRate,
...value.rotationRate,
...event.rotationRate
},
acceleration: {
...deviceMotionData.acceleration,
...value.acceleration,
...event.acceleration
},
accelerationIncludingGravity: {
...deviceMotionData.accelerationIncludingGravity,
...value.accelerationIncludingGravity,
...event.accelerationIncludingGravity
}
});
Expand All @@ -69,5 +72,5 @@ export const useDeviceMotion = (params?: UseDeviceMotionParams) => {
};
}, [delay, enabled]);

return deviceMotionData;
return value;
};
14 changes: 14 additions & 0 deletions src/hooks/useDeviceOrientation/useDeviceOrientation.demo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { useDeviceOrientation } from './useDeviceOrientation';

const Demo = () => {
const deviceOrientation = useDeviceOrientation();

return (
<pre lang='json'>
<b>Device orientation data:</b>
<p>{JSON.stringify(deviceOrientation.value, null, 2)}</p>
</pre>
);
};

export default Demo;
64 changes: 64 additions & 0 deletions src/hooks/useDeviceOrientation/useDeviceOrientation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { useEffect, useState } from 'react';

/* The use device orientation value type */
export interface UseDeviceOrientationValue {
/** A number representing the motion of the device around the z axis, express in degrees with values ranging from 0 to 360 */
alpha: number | null
/** A number representing the motion of the device around the x axis, express in degrees with values ranging from -180 to 180 */
beta: number | null
/** A number representing the motion of the device around the y axis, express in degrees with values ranging from -90 to 90 */
gamma: number | null
/** The current absolute value */
absolute: boolean
}

/* The use device orientation return type */
export interface UseDeviceOrientationReturn {
/** Whether the device orientation is supported */
supported: boolean
/** The current device orientation value */
value: UseDeviceOrientationValue
}

/**
* @name useDeviceOrientation
* @description - Hook that provides the current device orientation
* @category Sensors
*
* @returns {UseDeviceOrientationReturn} The current device orientation
*
* @example
* const { supported, value } = useDeviceOrientation();
*/
export const useDeviceOrientation = (): UseDeviceOrientationReturn => {
const supported = window && 'DeviceOrientationEvent' in window;

const [value, setValue] = useState<UseDeviceOrientationValue>({
alpha: null,
beta: null,
gamma: null,
absolute: false
});

useEffect(() => {
if (!supported) return;

const onDeviceOrientation = (event: DeviceOrientationEvent) =>
setValue({
alpha: event.alpha,
beta: event.beta,
gamma: event.gamma,
absolute: event.absolute
});

window.addEventListener('deviceorientation', onDeviceOrientation);
return () => {
window.removeEventListener('deviceorientation', onDeviceOrientation);
};
}, []);

return {
supported,
value
};
};
11 changes: 7 additions & 4 deletions src/hooks/useMouse/useMouse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ import { useEffect, useState } from 'react';
import { getElement } from '@/utils/helpers';

/** The use mouse target element type */
type UseMouseTarget = RefObject<Element | null | undefined> | (() => Element) | Element;
export type UseMouseTarget = RefObject<Element | null | undefined> | (() => Element) | Element;

/** The use mouse return type */
export interface UseMouseReturn {
/** The current mouse x position */
x: number;
/** The current mouse y position */
y: number;
/** The current element */
element: Element;
/** The current element x position */
elementX: number;
/** The current element y position */
Expand Down Expand Up @@ -63,6 +65,7 @@ export const useMouse = ((...params: any[]) => {
const [internalRef, setInternalRef] = useState<Element>();

useEffect(() => {
console.log('@@@@@', target);
if (!target && !internalRef) return;
const onMouseMove = (event: MouseEvent) => {
const element = (target ? getElement(target) : internalRef) as Element;
Expand Down Expand Up @@ -91,15 +94,15 @@ export const useMouse = ((...params: any[]) => {
};

document.addEventListener('mousemove', onMouseMove);

return () => {
document.removeEventListener('mousemove', onMouseMove);
};
}, [internalRef, target]);

if (target) return value;
if (target) return { ...value, element: target ?? internalRef };
return {
ref: setInternalRef,
...value
...value,
element: target ?? internalRef
};
}) as UseMouse;
125 changes: 125 additions & 0 deletions src/hooks/useParallax/useParallax.demo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import type { CSSProperties } from 'react';

import { useParallax } from './useParallax';

const Demo = () => {
const parallax = useParallax<HTMLDivElement>();

const layerBase: CSSProperties = {
position: 'absolute',
height: '100%',
width: '100%',
transition: '.3s ease-out all'
};

const layer0 = {
...layerBase,
transform: `translateX(${parallax.value.tilt * 10}px) translateY(${
parallax.value.roll * 10
}px)`
};

const layer1 = {
...layerBase,
transform: `translateX(${parallax.value.tilt * 20}px) translateY(${
parallax.value.roll * 20
}px)`
};

const layer2 = {
...layerBase,
transform: `translateX(${parallax.value.tilt * 30}px) translateY(${
parallax.value.roll * 30
}px)`
};

const layer3 = {
...layerBase,
transform: `translateX(${parallax.value.tilt * 40}px) translateY(${
parallax.value.roll * 40
}px)`
};

const cardStyle = {
background: '#fff',
height: '18rem',
width: '14rem',
borderRadius: '5px',
border: '1px solid #cdcdcd',
overflow: 'hidden',
transition: '.3s ease-out all',
boxShadow: '0 0 20px 0 rgba(255, 255, 255, 0.25)',
transform: `rotateX(${parallax.value.roll * 20}deg) rotateY(${
parallax.value.tilt * 20
}deg)`
};

const containerStyle: CSSProperties = {
margin: '3em auto',
perspective: '200px'
};

const cardContentStyle: CSSProperties = {
overflow: 'hidden',
fontSize: '6rem',
position: 'absolute',
top: 'calc(50% - 1em)',
left: 'calc(50% - 1em)',
height: '2em',
width: '2em',
margin: 'auto'
};

const targetStyle: CSSProperties = {
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
minHeight: '500px',
transition: '.3s ease-out all'
};

return (
<div ref={parallax.ref} style={targetStyle}>
<pre lang='json'>
<b>Parallax data:</b>
<p>{JSON.stringify(parallax.value, null, 2)}</p>
</pre>
<div style={containerStyle}>
<div style={cardStyle}>
<div style={cardContentStyle}>
<img
style={layer0}
src='https://jaromvogel.com/images/design/tiger_hunt_parallax/Tiger_hunt_3.png'
alt='layer0'
/>
<img
style={layer1}
src='https://jaromvogel.com/images/design/tiger_hunt_parallax/Tiger_hunt_2.png'
alt='layer1'
/>
<img
style={layer2}
src='https://jaromvogel.com/images/design/tiger_hunt_parallax/Tiger_hunt_1.png'
alt='layer2'
/>
<img
style={layer3}
src='https://jaromvogel.com/images/design/tiger_hunt_parallax/Tiger_hunt_0.png'
alt='layer3'
/>
</div>
</div>
</div>
<div>
Credit of images to{' '}
<a
href='https://codepen.io/jaromvogel'
target='__blank'
>Jarom Vogel
</a>
</div>
</div>
);
};

export default Demo;
Loading

0 comments on commit bcfe1eb

Please sign in to comment.