|
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'; |
7 | 4 |
|
8 | 5 | 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 | | - |
116 | 6 | const Outer = props.tag; |
117 | 7 | const Inner = props.innerTag; |
118 | | - |
| 8 | + const { ref } = useParallax(props); |
119 | 9 | return ( |
120 | 10 | <Outer className={props.className} style={props.style}> |
121 | 11 | <Inner |
122 | 12 | className={props.innerClassName} |
123 | | - ref={refInner} |
| 13 | + ref={ref} |
124 | 14 | style={props.innerStyle} |
125 | 15 | > |
126 | 16 | {props.children} |
|
0 commit comments