Skip to content

Commit cf6f7a0

Browse files
committed
feat: add onScroll function
1 parent fc432be commit cf6f7a0

File tree

6 files changed

+125
-22
lines changed

6 files changed

+125
-22
lines changed

@types/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import * as React from 'react'
2-
31
export type UseIonHeaderParallxInput = {
42
image: string
53
expandedColor: string
@@ -10,3 +8,5 @@ export type UseIonHeaderParallxInput = {
108
export type UseIonHeaderParallxInputResult = {
119
ref: React.MutableRefObject<HTMLElement | null>
1210
}
11+
12+
export { useIonHeaderParallax } from '../src/useIonicHeaderParallax'

renovate.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
11
{
2-
"extends": [
3-
"config:base"
4-
]
2+
"extends": ["config:base"]
53
}

src/IonHeaderParallax.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import * as React from 'react'
2+
3+
type IonHeaderParallaxProps = {}
4+
5+
export const IonHeaderParallax: React.FC<IonHeaderParallaxProps> = ({}: IonHeaderParallaxProps) => {
6+
return (
7+
<div className="color-overlay">
8+
<div className="image-overlay"></div>
9+
</div>
10+
)
11+
}

src/index.tsx

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/useIonicHeaderParallax.ts

Lines changed: 110 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
11
import * as React from 'react'
22

3-
export type UseIonicHeaderParallxInput = {
3+
export type UseIonicHeaderParallaxInput = {
44
image: string
55
expandedColor: string
66
titleColor: string
77
maximumHeight?: number
88
}
99

10-
export type UseIonHeaderParallxInputResult = {
10+
export type UseIonHeaderParallaxInputResult = {
1111
ref: React.MutableRefObject<HTMLElement | null>
12+
onScroll: () => void
1213
}
1314

14-
export function UseIonHeaderParallxInputResult({}: UseIonicHeaderParallxInput): UseIonHeaderParallxInputResult {
15+
export function useIonHeaderParallax({
16+
titleColor,
17+
image,
18+
expandedColor,
19+
maximumHeight = 300,
20+
}: UseIonicHeaderParallaxInput): UseIonHeaderParallaxInputResult {
1521
const headerRef = React.useRef<HTMLElement>(null)
1622

1723
let header: HTMLElement
@@ -21,18 +27,18 @@ export function UseIonHeaderParallxInputResult({}: UseIonicHeaderParallxInput):
2127
let colorOverlay: HTMLElement
2228
let barButtons: HTMLElement | null
2329
let scrollContent: HTMLElement | null
24-
// let headerHeight: any
25-
// let headerMinHeight: number
26-
// let translateAmt: any
27-
// let scaleAmt: any
28-
// let scrollTop: any
29-
// let lastScrollTop: any
30-
// let ticking: any
31-
// let originalToolbarBgColor: string
30+
let headerHeight: number
31+
let headerMinHeight: number
32+
let translateAmt: any
33+
let scaleAmt: any
34+
let scrollTop: any
35+
let lastScrollTop: any
36+
let ticking: any
37+
let originalToolbarBgColor: string
3238
let overlayTitle: HTMLElement | null
3339
let ionTitle: HTMLElement | null
34-
// let overlayButtons: HTMLElement[]
35-
// let scrollContentPaddingTop: number
40+
let overlayButtons: HTMLElement[]
41+
let scrollContentPaddingTop: string | number
3642

3743
React.useEffect(() => {
3844
setTimeout(() => {
@@ -47,7 +53,7 @@ export function UseIonHeaderParallxInputResult({}: UseIonicHeaderParallxInput):
4753
}, [])
4854

4955
const initElements = () => {
50-
if (!(headerRef && headerRef.current)) throw new ReferenceError('Ref is required')
56+
if (!(headerRef && headerRef.current)) throw new ReferenceError('Ref is required to be set to <IonHeader />')
5157

5258
const parentElement = headerRef.current.parentElement
5359

@@ -74,7 +80,7 @@ export function UseIonHeaderParallxInputResult({}: UseIonicHeaderParallxInput):
7480

7581
barButtons = header.querySelector('IonButtons')
7682

77-
const ionContent = parentElement.querySelector('ion-content')
83+
const ionContent = parentElement.querySelector('IonContent')
7884

7985
if (!ionContent) throw new Error('Parallax directive requires an <IonContent> element on the page to work.')
8086

@@ -86,6 +92,10 @@ export function UseIonHeaderParallxInputResult({}: UseIonicHeaderParallxInput):
8692
throw new Error('Parallax directive requires an <IonContent> element on the page to work.')
8793
}
8894

95+
headerHeight = scrollContent.clientHeight
96+
97+
console!.log('headerHeight', headerHeight)
98+
8999
// Create image overlay
90100
imageOverlay = document.createElement('div')
91101
console.log('imageOverlay', imageOverlay)
@@ -119,11 +129,95 @@ export function UseIonHeaderParallxInputResult({}: UseIonicHeaderParallxInput):
119129
console.log('finished')
120130
}
121131

122-
const initStyles = () => {}
132+
const initStyles = () => {
133+
ticking = false
134+
135+
if (!scrollContent || !toolbar) {
136+
return
137+
}
138+
139+
// fetch styles
140+
141+
headerMinHeight = toolbar.offsetHeight
142+
143+
scrollContentPaddingTop = window.getComputedStyle(scrollContent, null).paddingTop.replace('px', '')
144+
scrollContentPaddingTop = parseFloat(scrollContentPaddingTop)
145+
146+
if (!toolbarBackground) return
147+
148+
originalToolbarBgColor = window.getComputedStyle(toolbarBackground, null).backgroundColor
149+
150+
if (!originalToolbarBgColor) {
151+
throw new Error('Error: toolbarBackround is null.')
152+
}
153+
154+
// header and title
155+
156+
header.style.position = 'relative'
157+
158+
if (overlayTitle) {
159+
// rerender here
160+
overlayTitle.style.color = titleColor
161+
overlayTitle.style.position = 'absolute'
162+
overlayTitle.style.width = '100%'
163+
overlayTitle.style.height = '100%'
164+
overlayTitle.style.textAlign = 'center'
165+
}
166+
167+
// color overlay
168+
colorOverlay.style.backgroundColor = originalToolbarBgColor
169+
colorOverlay.style.height = `${maximumHeight}px`
170+
colorOverlay.style.position = 'absolute'
171+
colorOverlay.style.top = `${-headerMinHeight * 0}px`
172+
colorOverlay.style.left = '0'
173+
colorOverlay.style.width = '100%'
174+
colorOverlay.style.zIndex = '10'
175+
colorOverlay.style.pointerEvents = 'none'
176+
177+
// image overlay
178+
179+
imageOverlay.style.backgroundColor = expandedColor
180+
181+
imageOverlay.style.backgroundImage = `url(${image || ''})`
182+
183+
imageOverlay.style.height = '100%'
184+
imageOverlay.style.width = '100%'
185+
186+
imageOverlay.style.pointerEvents = 'none'
187+
imageOverlay.style.backgroundSize = 'cover'
188+
imageOverlay.style.backgroundPosition = 'center'
189+
}
123190

124191
const initEvents = () => {}
125192

193+
const onScroll = () => {
194+
if (!scrollContent || !toolbar) {
195+
return
196+
}
197+
198+
scrollTop = scrollContent.scrollTop
199+
if (scrollTop >= 0) {
200+
translateAmt = scrollTop / 2
201+
scaleAmt = 1
202+
} else {
203+
translateAmt = 0
204+
scaleAmt = -scrollTop / headerHeight + 1
205+
}
206+
207+
// Parallax total progress
208+
headerMinHeight = toolbar.offsetHeight
209+
let progress = (maximumHeight - scrollTop - headerMinHeight) / (maximumHeight - headerMinHeight)
210+
progress = Math.max(progress, 0)
211+
212+
// ion-header: set height
213+
let targetHeight = maximumHeight - scrollTop
214+
targetHeight = Math.max(targetHeight, headerMinHeight)
215+
216+
console.log(lastScrollTop, ticking, overlayButtons)
217+
}
218+
126219
return {
127220
ref: headerRef,
221+
onScroll,
128222
}
129223
}

tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"compilerOptions": {
3+
"jsx": "react",
34
/* Basic Options */
45
// "incremental": true, /* Enable incremental compilation */
56
"target": "es6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */,

0 commit comments

Comments
 (0)