1- import * as React from ' react'
1+ import * as React from " react" ;
22
33export type UseIonHeaderParallaxInput = {
4- image : string
5- expandedColor ?: string
6- titleColor ?: string
7- maximumHeight ?: number
8- }
4+ image : string ;
5+ expandedColor ?: string ;
6+ titleColor ?: string ;
7+ maximumHeight ?: number ;
8+ } ;
99
1010export type UseIonHeaderParallaxResult = {
11- ref : React . RefObject < any >
12- }
11+ ref : React . RefObject < any > ;
12+ } ;
1313
1414export function useIonHeaderParallax ( {
1515 image,
16- titleColor = ' #AAA' ,
17- expandedColor = ' #313131' ,
16+ titleColor = " #AAA" ,
17+ expandedColor = " #313131" ,
1818 maximumHeight = 300 ,
1919} : UseIonHeaderParallaxInput ) : UseIonHeaderParallaxResult {
2020 /** styles */
21- const [ ticking , setTicking ] = React . useState < boolean > ( false )
21+ const [ ticking , setTicking ] = React . useState < boolean > ( false ) ;
2222
23- const ref : React . RefObject < any > = React . useRef < any > ( null )
23+ const ref : React . RefObject < any > = React . useRef < any > ( null ) ;
2424
2525 React . useEffect ( ( ) => {
2626 setTimeout ( ( ) => {
27- initElements ( )
28- } , 300 )
29- } , [ image , titleColor , expandedColor , maximumHeight , ref ] )
27+ initElements ( ) ;
28+ } , 300 ) ;
29+ } , [ image , titleColor , expandedColor , maximumHeight , ref ] ) ;
3030
3131 const initElements = ( ) => {
3232 // ion-header
3333 if ( ref && ref . current ) {
34- const header = ref . current
35- const parentElement = header . parentElement
36- if ( ! parentElement ) throw new Error ( ' No IonPage parent element' )
34+ const header = ref . current ;
35+ const parentElement = header . parentElement ;
36+ if ( ! parentElement ) throw new Error ( " No IonPage parent element" ) ;
3737
3838 // ion-toolbar
39- const toolbar = header . querySelector ( ' ion-toolbar' ) as HTMLElement
40- if ( ! toolbar ) throw new Error ( ' No <ion-toolbar>' )
39+ const toolbar = header . querySelector ( " ion-toolbar" ) as HTMLElement ;
40+ if ( ! toolbar ) throw new Error ( " No <ion-toolbar>" ) ;
4141
4242 // ion-toolbar background
43- const toolbarShadowRoot = toolbar . shadowRoot
43+ const toolbarShadowRoot = toolbar . shadowRoot ;
4444
45- if ( ! toolbarShadowRoot ) throw new Error ( 'No shadow' )
46- const toolbarBackground = toolbarShadowRoot . querySelector ( '.toolbar-background' ) as HTMLElement
45+ if ( ! toolbarShadowRoot ) throw new Error ( "No shadow" ) ;
46+ const toolbarBackground = toolbarShadowRoot . querySelector (
47+ ".toolbar-background"
48+ ) as HTMLElement ;
4749
4850 // ion-title
49- const ionTitle = toolbar . querySelector ( ' ion-title' )
51+ const ionTitle = toolbar . querySelector ( " ion-title" ) ;
5052
5153 // ion-buttons
52- const barButtons = header . querySelector ( ' ion-buttons' ) as HTMLElement
54+ const barButtons = header . querySelector ( " ion-buttons" ) as HTMLElement ;
5355
5456 // ion-content
55- const ionContent = parentElement . querySelector ( 'ion-content' )
56- if ( ! ionContent ) throw new Error ( 'Parallax requires an <ion-content> element on the page to work.' )
57- const scrollContent = ionContent . shadowRoot ?. querySelector ( '.inner-scroll' ) as HTMLElement
57+ const ionContent = parentElement . querySelector ( "ion-content" ) ;
58+ if ( ! ionContent )
59+ throw new Error (
60+ "Parallax requires an <ion-content> element on the page to work."
61+ ) ;
62+ const scrollContent = ionContent . shadowRoot ?. querySelector (
63+ ".inner-scroll"
64+ ) as HTMLElement ;
5865 if ( ! scrollContent ) {
59- throw new Error ( 'Parallax directive requires an <ion-content> element on the page to work.' )
66+ throw new Error (
67+ "Parallax directive requires an <ion-content> element on the page to work."
68+ ) ;
6069 }
6170
6271 // create image overly
63- const imageOverlay = document . createElement ( ' div' )
64- imageOverlay . classList . add ( ' image-overlay' )
65- const colorOverlay = document . createElement ( ' div' )
66- colorOverlay . classList . add ( ' color-overlay' )
67- colorOverlay . appendChild ( imageOverlay )
68- header . appendChild ( colorOverlay )
72+ const imageOverlay = document . createElement ( " div" ) ;
73+ imageOverlay . classList . add ( " image-overlay" ) ;
74+ const colorOverlay = document . createElement ( " div" ) ;
75+ colorOverlay . classList . add ( " color-overlay" ) ;
76+ colorOverlay . appendChild ( imageOverlay ) ;
77+ header . appendChild ( colorOverlay ) ;
6978
70- const overlayTitle = ionTitle && ( ionTitle . cloneNode ( true ) as HTMLElement )
79+ const overlayTitle =
80+ ionTitle && ( ionTitle . cloneNode ( true ) as HTMLElement ) ;
7181
7282 if ( overlayTitle ) {
73- overlayTitle . classList . add ( ' parallax-title' )
83+ overlayTitle . classList . add ( " parallax-title" ) ;
7484
7585 setTimeout ( ( ) => {
7686 if ( overlayTitle . shadowRoot ) {
77- const toolbarTitle = overlayTitle . shadowRoot . querySelector ( '.toolbar-title' ) as HTMLElement
78- toolbarTitle . style . pointerEvents = 'unset'
87+ const toolbarTitle = overlayTitle . shadowRoot . querySelector (
88+ ".toolbar-title"
89+ ) as HTMLElement ;
90+ toolbarTitle . style . pointerEvents = "unset" ;
7991 }
80- } , 200 )
92+ } , 200 ) ;
8193 }
8294
8395 if ( overlayTitle ) {
84- imageOverlay . appendChild ( overlayTitle )
96+ imageOverlay . appendChild ( overlayTitle ) ;
8597 }
8698 if ( barButtons ) {
87- imageOverlay . appendChild ( barButtons )
99+ imageOverlay . appendChild ( barButtons ) ;
88100 }
89101
90102 /*** initStyles ***/
91103 // still in init use JS DOM
92- setTicking ( false )
104+ setTicking ( false ) ;
93105
94106 // fetch styles
95- maximumHeight = parseFloat ( maximumHeight . toString ( ) )
96- let headerMinHeight = toolbar . offsetHeight
107+ maximumHeight = parseFloat ( maximumHeight . toString ( ) ) ;
108+ let headerMinHeight = toolbar . offsetHeight ;
97109
98- let scrollContentPaddingTop : number = parseFloat (
99- window . getComputedStyle ( scrollContent as Element , null ) . paddingTop . replace ( 'px' , '' )
100- )
101-
102- const originalToolbarBgColor = window . getComputedStyle ( toolbarBackground as Element , null ) . backgroundColor
110+ const originalToolbarBgColor = window . getComputedStyle (
111+ toolbarBackground as Element ,
112+ null
113+ ) . backgroundColor ;
103114 if ( ! originalToolbarBgColor ) {
104- throw new Error ( ' Error: toolbarBackround is null.' )
115+ throw new Error ( " Error: toolbarBackround is null." ) ;
105116 }
106117
107118 // header and title
108- header . style . position = ' relative'
119+ header . style . position = " relative" ;
109120
110121 if ( overlayTitle ) {
111- overlayTitle . style . color = titleColor
112- overlayTitle . style . position = ' absolute'
113- overlayTitle . style . width = ' 100%'
114- overlayTitle . style . height = ' 100%'
115- overlayTitle . style . textAlign = ' center'
122+ overlayTitle . style . color = titleColor ;
123+ overlayTitle . style . position = " absolute" ;
124+ overlayTitle . style . width = " 100%" ;
125+ overlayTitle . style . height = " 100%" ;
126+ overlayTitle . style . textAlign = " center" ;
116127 }
117128
118129 // color overlay
119- colorOverlay . style . backgroundColor = originalToolbarBgColor
120- colorOverlay . style . height = `${ maximumHeight } px`
121- colorOverlay . style . position = ' absolute'
122- colorOverlay . style . top = `${ - headerMinHeight * 0 } px`
123- colorOverlay . style . left = '0'
124- colorOverlay . style . width = ' 100%'
125- colorOverlay . style . zIndex = '10'
126- colorOverlay . style . pointerEvents = ' none'
130+ colorOverlay . style . backgroundColor = originalToolbarBgColor ;
131+ colorOverlay . style . height = `${ maximumHeight } px` ;
132+ colorOverlay . style . position = " absolute" ;
133+ colorOverlay . style . top = `${ - headerMinHeight * 0 } px` ;
134+ colorOverlay . style . left = "0" ;
135+ colorOverlay . style . width = " 100%" ;
136+ colorOverlay . style . zIndex = "10" ;
137+ colorOverlay . style . pointerEvents = " none" ;
127138
128139 // image overlay
129- imageOverlay . style . backgroundColor = expandedColor
130- imageOverlay . style . backgroundImage = `url(${ image } )`
131- imageOverlay . style . height = ' 100%'
132- imageOverlay . style . width = ' 100%'
133- imageOverlay . style . pointerEvents = ' none'
134- imageOverlay . style . backgroundSize = ' cover'
135- imageOverlay . style . backgroundPosition = ' center'
140+ imageOverlay . style . backgroundColor = expandedColor ;
141+ imageOverlay . style . backgroundImage = `url(${ image } )` ;
142+ imageOverlay . style . height = " 100%" ;
143+ imageOverlay . style . width = " 100%" ;
144+ imageOverlay . style . pointerEvents = " none" ;
145+ imageOverlay . style . backgroundSize = " cover" ;
146+ imageOverlay . style . backgroundPosition = " center" ;
136147
137148 // .toolbar-background
138- toolbarBackground . style . backgroundColor = originalToolbarBgColor
149+ toolbarBackground . style . backgroundColor = originalToolbarBgColor ;
139150
140151 // .bar-buttons
141152 if ( barButtons ) {
142- barButtons . style . pointerEvents = ' all'
153+ barButtons . style . pointerEvents = " all" ;
143154
144155 Array . from ( barButtons . children ) . forEach ( ( btn ) => {
145156 // console.log(btn, btn as HTMLElement)
146- const htmlBtn = btn as HTMLElement
147- htmlBtn . style . color = titleColor
148- } )
157+ const htmlBtn = btn as HTMLElement ;
158+ htmlBtn . style . color = titleColor ;
159+ } ) ;
149160 }
150161
151162 // .scroll-content
152163 if ( scrollContent ) {
153- scrollContent . setAttribute ( ' parallax' , '' )
154- scrollContent . style . paddingTop = `${ maximumHeight + scrollContentPaddingTop - headerMinHeight } px`
164+ scrollContent . setAttribute ( " parallax" , "" ) ;
165+ scrollContent . style . paddingTop = `250px` ;
155166 }
156167
157168 if ( scrollContent ) {
158- scrollContent . addEventListener ( ' scroll' , ( _e ) => {
169+ scrollContent . addEventListener ( " scroll" , ( _e ) => {
159170 if ( ! ticking ) {
160171 window . requestAnimationFrame ( ( ) => {
161172 // to do
162173
163- const scrollTop = scrollContent . scrollTop
174+ const scrollTop = scrollContent . scrollTop ;
164175
165176 // Parallax total progress
166- headerMinHeight = toolbar . offsetHeight
177+ headerMinHeight = toolbar . offsetHeight ;
167178
168- let progress = ( maximumHeight - scrollTop - headerMinHeight ) / ( maximumHeight - headerMinHeight )
169- progress = Math . max ( progress , 0 )
179+ let progress =
180+ ( maximumHeight - scrollTop - headerMinHeight ) /
181+ ( maximumHeight - headerMinHeight ) ;
182+ progress = Math . max ( progress , 0 ) ;
170183
171- let targetHeight = maximumHeight - scrollTop
172- targetHeight = Math . max ( targetHeight , headerMinHeight )
184+ let targetHeight = maximumHeight - scrollTop ;
185+ targetHeight = Math . max ( targetHeight , headerMinHeight ) ;
173186
174187 // .toolbar-background: change color
175- imageOverlay . style . height = `${ targetHeight } px`
176- imageOverlay . style . opacity = `${ progress } `
177- colorOverlay . style . height = `${ targetHeight } px`
178- colorOverlay . style . opacity = targetHeight > headerMinHeight ? '1' : '0'
188+ imageOverlay . style . height = `${ targetHeight } px` ;
189+ imageOverlay . style . opacity = `${ progress } ` ;
190+ colorOverlay . style . height = `${ targetHeight } px` ;
191+ colorOverlay . style . opacity =
192+ targetHeight > headerMinHeight ? "1" : "0" ;
179193 toolbarBackground . style . backgroundColor =
180- targetHeight > headerMinHeight ? 'transparent' : originalToolbarBgColor
194+ targetHeight > headerMinHeight
195+ ? "transparent"
196+ : originalToolbarBgColor ;
181197
182198 // .bar-buttons
183199 if ( barButtons ) {
184200 if ( targetHeight > headerMinHeight ) {
185- imageOverlay . append ( barButtons )
201+ imageOverlay . append ( barButtons ) ;
186202 Array . from ( barButtons . children ) . forEach ( ( btn ) => {
187- const htmlBtn = btn as HTMLElement
188- htmlBtn . style . color = titleColor
189- } )
203+ const htmlBtn = btn as HTMLElement ;
204+ htmlBtn . style . color = titleColor ;
205+ } ) ;
190206 } else {
191- toolbar . append ( barButtons )
207+ toolbar . append ( barButtons ) ;
192208 Array . from ( barButtons . children ) . forEach ( ( btn ) => {
193- const htmlBtn = btn as HTMLElement
194- htmlBtn . style . color = ' unset'
195- } )
209+ const htmlBtn = btn as HTMLElement ;
210+ htmlBtn . style . color = " unset" ;
211+ } ) ;
196212 }
197213 }
198- } )
214+ } ) ;
199215 }
200- setTicking ( true )
201- } )
216+ setTicking ( true ) ;
217+ } ) ;
202218 }
203219 }
204- }
220+ } ;
205221
206222 return {
207223 ref,
208- }
209- }
224+ } ;
225+ }
0 commit comments