Skip to content

Commit 96c700e

Browse files
committed
add useParallax hook
1 parent 1e4f44c commit 96c700e

File tree

4 files changed

+129
-116
lines changed

4 files changed

+129
-116
lines changed

src/components/Parallax/index.tsx

Lines changed: 5 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1,126 +1,16 @@
1-
import React, { PropsWithChildren, useEffect, useRef, useState } from 'react';
2-
import { CreateElementOptions, Element } from 'parallax-controller';
3-
import { useController } from '../../hooks/useController';
4-
import { removeUndefinedObjectKeys } from '../../utils/removeUndefinedObjectKeys';
5-
import { ParallaxProps } from './types';
6-
import { useVerifyController } from './hooks';
1+
import React, { PropsWithChildren } from 'react';
2+
import { useParallax } from '../../hooks/useParallax';
3+
import { ParallaxProps } from '../../types';
74

85
export function Parallax(props: PropsWithChildren<ParallaxProps>) {
9-
const controller = useController();
10-
const refInner = useRef<HTMLElement>();
11-
12-
useVerifyController(controller);
13-
14-
function _getElementOptions(): CreateElementOptions {
15-
const useSpeedProp = typeof props.speed !== 'undefined';
16-
const isHorizontal = controller?.scrollAxis == 'horizontal';
17-
const isVertical = controller?.scrollAxis == 'vertical';
18-
19-
let translateX = props.translateX;
20-
let translateY = props.translateY;
21-
22-
if (useSpeedProp && isHorizontal) {
23-
translateX = [
24-
`${(props.speed || 0) * 10}px`,
25-
`${(props.speed || 0) * -10}px`,
26-
];
27-
}
28-
29-
if (useSpeedProp && isVertical) {
30-
translateY = [
31-
`${(props.speed || 0) * 10}px`,
32-
`${(props.speed || 0) * -10}px`,
33-
];
34-
}
35-
36-
return {
37-
// @ts-expect-error
38-
el: refInner.current,
39-
props: removeUndefinedObjectKeys({
40-
translateX,
41-
translateY,
42-
disabled: props.disabled,
43-
rotate: props.rotate,
44-
rotateX: props.rotateX,
45-
rotateY: props.rotateY,
46-
rotateZ: props.rotateZ,
47-
scale: props.scale,
48-
scaleX: props.scaleX,
49-
scaleY: props.scaleY,
50-
scaleZ: props.scaleZ,
51-
opacity: props.opacity,
52-
easing: props.easing,
53-
rootMargin: props.rootMargin,
54-
shouldStartAnimationInitialInView:
55-
props.shouldStartAnimationInitialInView,
56-
onProgressChange: props.onProgressChange,
57-
onChange: props.onChange,
58-
onEnter: props.onEnter,
59-
onExit: props.onExit,
60-
startScroll: props.startScroll,
61-
endScroll: props.endScroll,
62-
targetElement: props.targetElement,
63-
}),
64-
};
65-
}
66-
67-
const [element, setElement] = useState<Element>();
68-
69-
// create element
70-
useEffect(() => {
71-
const newElement = controller?.createElement(_getElementOptions());
72-
setElement(newElement);
73-
74-
return () => {
75-
if (newElement) {
76-
controller?.removeElementById(newElement.id);
77-
}
78-
};
79-
}, []);
80-
81-
// update element
82-
useEffect(() => {
83-
if (element) {
84-
if (props.disabled) {
85-
controller?.resetElementStyles(element);
86-
} else {
87-
controller?.updateElementPropsById(
88-
element.id,
89-
_getElementOptions().props
90-
);
91-
}
92-
}
93-
}, [
94-
props.disabled,
95-
props.translateX,
96-
props.translateY,
97-
props.rotate,
98-
props.rotateX,
99-
props.rotateY,
100-
props.rotateZ,
101-
props.scale,
102-
props.scaleX,
103-
props.scaleY,
104-
props.scaleZ,
105-
props.speed,
106-
props.opacity,
107-
props.easing,
108-
props.rootMargin,
109-
props.onProgressChange,
110-
props.onChange,
111-
props.onEnter,
112-
props.onExit,
113-
props.targetElement,
114-
]);
115-
1166
const Outer = props.tag;
1177
const Inner = props.innerTag;
118-
8+
const { ref } = useParallax(props);
1199
return (
12010
<Outer className={props.className} style={props.style}>
12111
<Inner
12212
className={props.innerClassName}
123-
ref={refInner}
13+
ref={ref}
12414
style={props.innerStyle}
12515
>
12616
{props.children}

src/hooks/useParallax.ts

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import { CreateElementOptions, Element } from 'parallax-controller';
2+
import { useEffect, useRef, useState } from 'react';
3+
import { useVerifyController } from '../components/Parallax/hooks';
4+
import { ParallaxProps } from '../types';
5+
import { removeUndefinedObjectKeys } from '../utils/removeUndefinedObjectKeys';
6+
import { useController } from './useController';
7+
8+
export function useParallax(props: ParallaxProps) {
9+
const controller = useController();
10+
const ref = useRef<HTMLElement>();
11+
12+
useVerifyController(controller);
13+
14+
function _getElementOptions(): CreateElementOptions {
15+
const useSpeedProp = typeof props.speed !== 'undefined';
16+
const isHorizontal = controller?.scrollAxis == 'horizontal';
17+
const isVertical = controller?.scrollAxis == 'vertical';
18+
19+
let translateX = props.translateX;
20+
let translateY = props.translateY;
21+
22+
// TODO: move to parallax-controller
23+
if (useSpeedProp && isHorizontal) {
24+
translateX = [
25+
`${(props.speed || 0) * 10}px`,
26+
`${(props.speed || 0) * -10}px`,
27+
];
28+
}
29+
30+
if (useSpeedProp && isVertical) {
31+
translateY = [
32+
`${(props.speed || 0) * 10}px`,
33+
`${(props.speed || 0) * -10}px`,
34+
];
35+
}
36+
37+
return {
38+
// @ts-expect-error
39+
el: ref.current,
40+
props: removeUndefinedObjectKeys({
41+
translateX,
42+
translateY,
43+
disabled: props.disabled,
44+
rotate: props.rotate,
45+
rotateX: props.rotateX,
46+
rotateY: props.rotateY,
47+
rotateZ: props.rotateZ,
48+
scale: props.scale,
49+
scaleX: props.scaleX,
50+
scaleY: props.scaleY,
51+
scaleZ: props.scaleZ,
52+
opacity: props.opacity,
53+
easing: props.easing,
54+
rootMargin: props.rootMargin,
55+
shouldStartAnimationInitialInView:
56+
props.shouldStartAnimationInitialInView,
57+
onProgressChange: props.onProgressChange,
58+
onChange: props.onChange,
59+
onEnter: props.onEnter,
60+
onExit: props.onExit,
61+
startScroll: props.startScroll,
62+
endScroll: props.endScroll,
63+
targetElement: props.targetElement,
64+
}),
65+
};
66+
}
67+
68+
const [element, setElement] = useState<Element>();
69+
70+
// create element
71+
useEffect(() => {
72+
const newElement = controller?.createElement(_getElementOptions());
73+
74+
setElement(newElement);
75+
76+
return () => {
77+
if (newElement) {
78+
controller?.removeElementById(newElement.id);
79+
}
80+
};
81+
}, []);
82+
83+
// update element
84+
useEffect(() => {
85+
if (element) {
86+
if (props.disabled) {
87+
controller?.resetElementStyles(element);
88+
} else {
89+
controller?.updateElementPropsById(
90+
element.id,
91+
_getElementOptions().props
92+
);
93+
}
94+
}
95+
}, [
96+
props.disabled,
97+
props.translateX,
98+
props.translateY,
99+
props.rotate,
100+
props.rotateX,
101+
props.rotateY,
102+
props.rotateZ,
103+
props.scale,
104+
props.scaleX,
105+
props.scaleY,
106+
props.scaleZ,
107+
props.speed,
108+
props.opacity,
109+
props.easing,
110+
props.rootMargin,
111+
props.onProgressChange,
112+
props.onChange,
113+
props.onEnter,
114+
props.onExit,
115+
props.targetElement,
116+
]);
117+
118+
return { ref };
119+
}

src/index.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@ import { Parallax } from './components/Parallax';
44
import { ParallaxBanner } from './components/ParallaxBanner';
55
import { ParallaxProvider } from './components/ParallaxProvider';
66
import { ParallaxContext } from './context/ParallaxContext';
7-
export { useController } from './hooks/useController';
7+
import { useParallax } from './hooks/useParallax';
8+
import { useController } from './hooks/useController';
9+
810
export {
11+
useParallax,
12+
useController,
913
Parallax,
1014
ParallaxBanner,
1115
ParallaxProvider,
File renamed without changes.

0 commit comments

Comments
 (0)