Skip to content

Commit 38b8e7a

Browse files
committed
main ?? use pointer lock rework
1 parent 510bec5 commit 38b8e7a

File tree

7 files changed

+63
-52
lines changed

7 files changed

+63
-52
lines changed

src/hooks/useCssVar/useCssVar.demo.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import { useCssVar } from './useCssVar';
22

33
const Demo = () => {
4-
const key = '--color';
5-
const colorVar = useCssVar(key, '#7fa998');
4+
const colorVar = useCssVar('--color', '#7fa998');
65

76
const switchColor = () => {
87
if (colorVar.value === '#df8543') colorVar.set('#7fa998');

src/hooks/useElementSize/useElementSize.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ export const useElementSize = ((...params: any[]) => {
6868
useEffect(() => {
6969
if (!target && !internalRef) return;
7070
const element = (target ? getElement(target) : internalRef) as Element;
71-
71+
if (element) return;
7272
const observer = new ResizeObserver(([entry]) => {
7373
const { inlineSize: width, blockSize: height } = entry.borderBoxSize[0];
7474

src/hooks/useEventListener/useEventListener.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,8 @@ export const useEventListener = ((...params: any[]) => {
7373
const internalListener = useEvent(listener);
7474

7575
useEffect(() => {
76-
if (!target && !internalRef) return;
7776
const callback = (event: Event) => internalListener(event);
78-
const element = target ? getElement(target) : internalRef;
77+
const element = target ? getElement(target) : (internalRef ?? window);
7978
if (element) {
8079
events.forEach((event) => element.addEventListener(event, callback, options));
8180
return () => {

src/hooks/useMap/useMap.demo.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const Demo = () => {
1212

1313
return (
1414
<>
15-
<div style={{ display: 'flex', gap: 8 }}>
15+
<div className='flex gap-2'>
1616
<input placeholder='Name' {...nameInput.register()} />
1717
<input type='number' placeholder='Age' {...ageInput.register()} />
1818

@@ -28,7 +28,7 @@ const Demo = () => {
2828
</button>
2929
</div>
3030

31-
<div style={{ marginTop: 8 }}>
31+
<div className='mt-4 flex gap-2 flex-col'>
3232
{Array.from(users.value).map(([name, age], index) => (
3333
<div key={index}>
3434
{name}: <code>{age}</code>
Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,44 @@
1+
12
import type { CSSProperties } from 'react';
23

4+
import { useRef } from 'react';
5+
6+
import { useEventListener } from '../useEventListener/useEventListener';
37
import { usePointerLock } from './usePointerLock';
48

5-
const Demo = () => {
6-
const { lock, unlock } = usePointerLock();
9+
const getSideStyles = (index: number) => ({
10+
"--i": index,
11+
transform: "rotateY(calc(90deg * var(--i))) translateZ(50px)"
12+
} as CSSProperties)
13+
const getBaseStyles = (index: number) => ({ "--i": index, transform: "rotateX(calc(90deg * var(--i))) translateZ(50px)" } as CSSProperties)
14+
const face = 'absolute top-0 left-0 w-full h-full border-1 border-solid border-black backface-hidden bg-cyan-500 opacity-50'
715

8-
const containerStyle: CSSProperties = {
9-
display: 'flex',
10-
justifyContent: 'center',
11-
alignItems: 'center'
12-
};
1316

14-
const elementStyle: CSSProperties = {
15-
border: '1px solid #949CE0',
16-
color: '#949CE0',
17-
padding: '25px',
18-
cursor: 'move'
19-
};
17+
const Demo = () => {
18+
const { element, unlock, lock } = usePointerLock();
19+
const positionRef = useRef({ x: 0, y: 0 });
20+
21+
useEventListener('mousemove', (event) => {
22+
positionRef.current = { x: positionRef.current.x + event.movementX, y: positionRef.current.y + event.movementY };
23+
if (!element) return
24+
const cube = element as HTMLElement;
25+
const x = positionRef.current.y + event.movementY / 2
26+
const y = positionRef.current.x + event.movementX / 2
27+
cube.style.transform = `rotateY(calc(${y} * 1deg)) rotateX(calc(${x} * 1deg))`
28+
}, { passive: true })
2029

2130
return (
22-
<div style={containerStyle}>
23-
<div style={elementStyle} onMouseDownCapture={lock} onMouseUpCapture={unlock}>
24-
Move me
31+
<div className='flex justify-center items-center perspective-normal h-32'>
32+
<div className='cursor-all-scroll relative w-[100px] h-[100px] transform-3d' onMouseDownCapture={lock} onMouseUpCapture={unlock}>
33+
<span className={face} style={getBaseStyles(1)} />
34+
<span className={face} style={getBaseStyles(-1)} />
35+
<span className={face} style={getSideStyles(0)} />
36+
<span className={face} style={getSideStyles(1)} />
37+
<span className={face} style={getSideStyles(2)} />
38+
<span className={face} style={getSideStyles(3)} />
2539
</div>
2640
</div>
27-
);
41+
)
2842
};
2943

3044
export default Demo;

src/hooks/usePointerLock/usePointerLock.ts

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
import type { MouseEvent, RefObject } from 'react';
1+
import type { MouseEvent } from 'react';
22

33
import { useEffect, useState } from 'react';
44

5-
type UsePointerLockTarget = RefObject<Element | null | undefined>;
6-
5+
/** The use pointer lock return type */
76
interface UsePointerLockReturn {
87
element?: Element;
98
supported: boolean;
10-
lock: (event: Event | MouseEvent<Element>) => void;
9+
lock: (event: MouseEvent) => void;
1110
unlock: () => boolean;
1211
}
1312

@@ -16,16 +15,13 @@ interface UsePointerLockReturn {
1615
* @description - Hook that provides reactive pointer lock
1716
* @category Sensors
1817
*
19-
* @param {UsePointerLockTarget} target The target element for the pointer lock
2018
* @returns {UsePointerLockReturn} An object containing the pointer lock element and functions to interact with the pointer lock
2119
*
2220
* @example
2321
* const { supported, lock, unlock, element } = usePointerLock();
2422
*/
25-
26-
export const usePointerLock = (target?: UsePointerLockTarget): UsePointerLockReturn => {
27-
const supported = !!document && 'pointerLockElement' in document;
28-
23+
export const usePointerLock = (): UsePointerLockReturn => {
24+
const supported = typeof document !== 'undefined' && 'pointerLockElement' in document;
2925
const [element, setElement] = useState<Element>();
3026

3127
useEffect(() => {
@@ -59,25 +55,25 @@ export const usePointerLock = (target?: UsePointerLockTarget): UsePointerLockRet
5955
document.removeEventListener('pointerlockchange', handlePointerLockChange);
6056
document.removeEventListener('pointerlockerror', handlePointerLockError);
6157
};
62-
}, [supported, element]);
63-
64-
const lock = (event: Event | MouseEvent<Element>) => {
65-
if (!supported) return;
58+
}, []);
6659

67-
const element = event instanceof Event ? target?.current : event.currentTarget;
60+
const lock = (event: MouseEvent) => {
61+
if (!supported) return false;
6862

69-
if (!element) return;
63+
if (event instanceof Event) return false;
7064

71-
element.requestPointerLock();
65+
event.currentTarget.requestPointerLock();
7266

73-
setElement(element);
67+
setElement(event.currentTarget);
68+
return true;
7469
};
7570

7671
const unlock = () => {
72+
if (!supported) return false;
73+
7774
if (!element) return false;
7875

7976
document.exitPointerLock();
80-
8177
setElement(undefined);
8278

8379
return true;

src/hooks/useScrollTo/useScrollTo.demo.tsx

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,22 @@ const Demo = () => {
1818
return (
1919
<div>
2020
<div ref={scrollTo.ref} style={{ overflow: 'auto', height: 300, padding: 20 }}>
21-
<div style={blockStyle}>First amazing block</div>
22-
<div style={blockStyle}>Second amazing block</div>
23-
<div style={blockStyle}>Third amazing block</div>
21+
<div style={blockStyle}><code>First</code> amazing block</div>
22+
<div style={blockStyle}><code>Second</code> amazing block</div>
23+
<div style={blockStyle}><code>Third</code> amazing block</div>
2424
</div>
25-
<div>
26-
<button type='button' onClick={() => scrollTo.trigger({ x: 0, y: 0 })}>
27-
Scroll to block 1
25+
<p>
26+
Scroll to:
27+
</p>
28+
<div className='flex w-full gap-2'>
29+
<button type='button' onClick={() => scrollTo.trigger({ x: 0, y: 0, behavior: 'smooth' })}>
30+
1
2831
</button>
29-
<button type='button' onClick={() => scrollTo.trigger({ x: 0, y: 260 })}>
30-
Scroll to block 2
32+
<button type='button' onClick={() => scrollTo.trigger({ x: 0, y: 260, behavior: 'smooth' })}>
33+
2
3134
</button>
32-
<button type='button' onClick={() => scrollTo.trigger({ x: 0, y: 520 })}>
33-
Scroll to block 3
35+
<button type='button' onClick={() => scrollTo.trigger({ x: 0, y: 520, behavior: 'smooth' })}>
36+
3
3437
</button>
3538
</div>
3639
</div>

0 commit comments

Comments
 (0)