-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathindex.ts
71 lines (61 loc) · 2.27 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import { useCallback, useState } from 'react';
import { PowerGlitch, PowerGlitchOptions, RecursivePartial } from 'powerglitch';
/**
* Handle to control the glitch once useGlitch is called.
*/
export type GlitchHandle = {
/**
* Function to use as ref for the element to glitch.
*/
ref: (node: HTMLElement | null) => void,
/**
* Glitch control to start the glitch animation.
*/
startGlitch: () => void,
/**
* Glitch control to stop the glitch animation.
*/
stopGlitch: () => void,
/**
* Change the glitch options.
*/
setOptions: (options: RecursivePartial<PowerGlitchOptions>) => void,
};
/**
* Hook to glitch one element.
* @param userOptions Options given to PowerGlitch
* @returns A glitch handle with glitch controls, a function to update the options and
*/
export function useGlitch(userOptions?: RecursivePartial<PowerGlitchOptions>): GlitchHandle {
/**
* Copy the options into a state object to avoid unecessary re-renders if the client is re-creating an options object in the main block.
*/
const [options, setOptions] = useState(userOptions);
/**
* Placeholder functions to start/stop the glitch, set after actually glitching the element.
*/
const [startGlitch, setStartGlitch] = useState<(() => void)>(() => () => void 0);
const [stopGlitch, setStopGlitch] = useState<(() => void)>(() => () => void 0);
/**
* Will run each time the ref to the node to glitch changes.
* E.g. after mount or when added/removed due to conditional rendering.
*/
const ref = useCallback((node: HTMLElement | null) => {
// If glitching an element inside a conditional render,
// `node` might not exist at some point, in which case we have nothing to glitch.
if (! node) {
return;
}
// When/if node is visible, glitch it
// Because of useCallback, we should not glitch an already glitched element, even though the underlying library supports it.
const result = PowerGlitch.glitch(node, options);
setStartGlitch(() => result.startGlitch);
setStopGlitch(() => result.stopGlitch);
}, [options]);
return {
ref,
startGlitch,
stopGlitch,
setOptions,
};
}