@gm-pc/tour 1.25.0-beta.0 → 1.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/utils.ts CHANGED
@@ -1,172 +1,172 @@
1
- import { ReactText } from 'react'
2
- import _ from 'lodash'
3
-
4
- const isNumeric = (n: ReactText): boolean =>
5
- !isNaN(parseFloat(n as string)) && isFinite(n as number)
6
-
7
- const setPosition = (
8
- begin: number,
9
- end: number,
10
- elapsed: number,
11
- duration: number
12
- ): number => {
13
- const easeInOutCubic = (t: number) =>
14
- t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1
15
- return elapsed > duration
16
- ? end
17
- : begin + (end - begin) * easeInOutCubic(elapsed / duration)
18
- }
19
-
20
- const calcEndPoint = (
21
- target: ReactText | HTMLElement,
22
- context: HTMLElement | Window = window,
23
- offset = 0
24
- ): number => {
25
- if (isNumeric(target as ReactText)) {
26
- return parseInt(`${target}`) + offset
27
- }
28
-
29
- const elementContext = context as HTMLElement
30
-
31
- const y =
32
- context === window || context === document.documentElement
33
- ? window.pageYOffset
34
- : elementContext.scrollTop - elementContext.getBoundingClientRect().top
35
- const distance =
36
- (target as HTMLElement).nodeName.toLowerCase() === 'html'
37
- ? -y
38
- : (target as HTMLElement).getBoundingClientRect().top + y
39
- return distance + offset
40
- }
41
-
42
- export const scrollSmooth = (
43
- target: ReactText | HTMLElement,
44
- options: {
45
- duration: number
46
- context: Window | HTMLElement
47
- offset: number
48
- callback(target: ReactText | HTMLElement): void
49
- } = {
50
- duration: 500,
51
- context: window,
52
- offset: 0,
53
- callback: _.noop,
54
- }
55
- ) => {
56
- const { duration, context, offset, callback } = options
57
- const start = (context as HTMLElement).scrollTop ?? window.pageYOffset
58
- const end = calcEndPoint(target, context, offset)
59
- const clock = window.performance.now()
60
- const rAF = window.requestAnimationFrame
61
-
62
- const tick = () => {
63
- const elapsed = window.performance.now() - clock
64
- const pos = setPosition(start, end, elapsed, duration)
65
- if (context !== window) {
66
- ;(context as HTMLElement).scrollTop = pos
67
- } else {
68
- window.scroll(0, pos)
69
- }
70
-
71
- if (elapsed > duration) {
72
- callback(target)
73
- } else {
74
- rAF(tick)
75
- }
76
- }
77
-
78
- tick()
79
- }
80
-
81
- const regex = /(auto|scroll)/
82
-
83
- const parents = function (node: Element, ps: Element[]): Element[] {
84
- if (_.isNil(node.parentNode)) {
85
- return ps
86
- }
87
- return parents(node.parentNode as Element, ps.concat([node]))
88
- }
89
-
90
- const style = function (node: Element, prop: string): string {
91
- return window.getComputedStyle(node, null).getPropertyValue(prop)
92
- }
93
-
94
- const overflow = function (node: Element): string {
95
- return `${style(node, 'overflow')} ${style(node, 'overflow-y')} ${style(
96
- node,
97
- 'overflow-x'
98
- )}`
99
- }
100
-
101
- const scroll = function (node: Element): boolean {
102
- return regex.test(overflow(node))
103
- }
104
-
105
- export const scrollParent = function (node: Element) {
106
- if (!(node instanceof HTMLElement || node instanceof SVGElement)) {
107
- return
108
- }
109
- const ps = parents(node.parentNode as Element, [])
110
- for (let i = 0; i < ps.length; i += 1) {
111
- if (scroll(ps[i])) {
112
- return ps[i]
113
- }
114
- }
115
- return document.scrollingElement ?? document.documentElement
116
- }
117
-
118
- export interface GetNodeRectOptions {
119
- top: number
120
- right: number
121
- bottom: number
122
- left: number
123
- width: number
124
- height: number
125
- }
126
-
127
- export function getNodeRect(node: HTMLElement): GetNodeRectOptions {
128
- const { top, right, bottom, left, width, height } = node.getBoundingClientRect()
129
- return { top, right, bottom, left, width, height }
130
- }
131
-
132
- export function inView({
133
- top,
134
- right,
135
- bottom,
136
- left,
137
- w,
138
- h,
139
- }: {
140
- top: number
141
- right: number
142
- bottom: number
143
- left: number
144
- w: number
145
- h: number
146
- }) {
147
- return top >= 0 && left >= 0 && bottom <= h && right <= w
148
- }
149
-
150
- export function isBody(node: HTMLElement) {
151
- return (
152
- node === document.querySelector('body') || node === document.querySelector('html')
153
- )
154
- }
155
-
156
- export const isHoriz = (pos: string) => /(left|right)/.test(pos)
157
- export const isOutsideX = (val: number, windowWidth: number) => val > windowWidth
158
- export const isOutsideY = (val: number, windowHeight: number) => val > windowHeight
159
- export const safe = (sum: number) => (sum < 0 ? 0 : sum)
160
-
161
- export function bestPositionOf(positions: { [key: string]: number }) {
162
- return Object.keys(positions)
163
- .map((p) => ({ position: p, value: positions[p] }))
164
- .sort((a, b) => b.value - a.value)
165
- .map((p) => p.position)
166
- }
167
-
168
- export function getWindow() {
169
- const w = Math.max(document.documentElement.clientWidth, window.innerWidth ?? 0)
170
- const h = Math.max(document.documentElement.clientHeight, window.innerHeight ?? 0)
171
- return { w, h }
172
- }
1
+ import { ReactText } from 'react'
2
+ import _ from 'lodash'
3
+
4
+ const isNumeric = (n: ReactText): boolean =>
5
+ !isNaN(parseFloat(n as string)) && isFinite(n as number)
6
+
7
+ const setPosition = (
8
+ begin: number,
9
+ end: number,
10
+ elapsed: number,
11
+ duration: number
12
+ ): number => {
13
+ const easeInOutCubic = (t: number) =>
14
+ t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1
15
+ return elapsed > duration
16
+ ? end
17
+ : begin + (end - begin) * easeInOutCubic(elapsed / duration)
18
+ }
19
+
20
+ const calcEndPoint = (
21
+ target: ReactText | HTMLElement,
22
+ context: HTMLElement | Window = window,
23
+ offset = 0
24
+ ): number => {
25
+ if (isNumeric(target as ReactText)) {
26
+ return parseInt(`${target}`) + offset
27
+ }
28
+
29
+ const elementContext = context as HTMLElement
30
+
31
+ const y =
32
+ context === window || context === document.documentElement
33
+ ? window.pageYOffset
34
+ : elementContext.scrollTop - elementContext.getBoundingClientRect().top
35
+ const distance =
36
+ (target as HTMLElement).nodeName.toLowerCase() === 'html'
37
+ ? -y
38
+ : (target as HTMLElement).getBoundingClientRect().top + y
39
+ return distance + offset
40
+ }
41
+
42
+ export const scrollSmooth = (
43
+ target: ReactText | HTMLElement,
44
+ options: {
45
+ duration: number
46
+ context: Window | HTMLElement
47
+ offset: number
48
+ callback(target: ReactText | HTMLElement): void
49
+ } = {
50
+ duration: 500,
51
+ context: window,
52
+ offset: 0,
53
+ callback: _.noop,
54
+ }
55
+ ) => {
56
+ const { duration, context, offset, callback } = options
57
+ const start = (context as HTMLElement).scrollTop ?? window.pageYOffset
58
+ const end = calcEndPoint(target, context, offset)
59
+ const clock = window.performance.now()
60
+ const rAF = window.requestAnimationFrame
61
+
62
+ const tick = () => {
63
+ const elapsed = window.performance.now() - clock
64
+ const pos = setPosition(start, end, elapsed, duration)
65
+ if (context !== window) {
66
+ ;(context as HTMLElement).scrollTop = pos
67
+ } else {
68
+ window.scroll(0, pos)
69
+ }
70
+
71
+ if (elapsed > duration) {
72
+ callback(target)
73
+ } else {
74
+ rAF(tick)
75
+ }
76
+ }
77
+
78
+ tick()
79
+ }
80
+
81
+ const regex = /(auto|scroll)/
82
+
83
+ const parents = function (node: Element, ps: Element[]): Element[] {
84
+ if (_.isNil(node.parentNode)) {
85
+ return ps
86
+ }
87
+ return parents(node.parentNode as Element, ps.concat([node]))
88
+ }
89
+
90
+ const style = function (node: Element, prop: string): string {
91
+ return window.getComputedStyle(node, null).getPropertyValue(prop)
92
+ }
93
+
94
+ const overflow = function (node: Element): string {
95
+ return `${style(node, 'overflow')} ${style(node, 'overflow-y')} ${style(
96
+ node,
97
+ 'overflow-x'
98
+ )}`
99
+ }
100
+
101
+ const scroll = function (node: Element): boolean {
102
+ return regex.test(overflow(node))
103
+ }
104
+
105
+ export const scrollParent = function (node: Element) {
106
+ if (!(node instanceof HTMLElement || node instanceof SVGElement)) {
107
+ return
108
+ }
109
+ const ps = parents(node.parentNode as Element, [])
110
+ for (let i = 0; i < ps.length; i += 1) {
111
+ if (scroll(ps[i])) {
112
+ return ps[i]
113
+ }
114
+ }
115
+ return document.scrollingElement ?? document.documentElement
116
+ }
117
+
118
+ export interface GetNodeRectOptions {
119
+ top: number
120
+ right: number
121
+ bottom: number
122
+ left: number
123
+ width: number
124
+ height: number
125
+ }
126
+
127
+ export function getNodeRect(node: HTMLElement): GetNodeRectOptions {
128
+ const { top, right, bottom, left, width, height } = node.getBoundingClientRect()
129
+ return { top, right, bottom, left, width, height }
130
+ }
131
+
132
+ export function inView({
133
+ top,
134
+ right,
135
+ bottom,
136
+ left,
137
+ w,
138
+ h,
139
+ }: {
140
+ top: number
141
+ right: number
142
+ bottom: number
143
+ left: number
144
+ w: number
145
+ h: number
146
+ }) {
147
+ return top >= 0 && left >= 0 && bottom <= h && right <= w
148
+ }
149
+
150
+ export function isBody(node: HTMLElement) {
151
+ return (
152
+ node === document.querySelector('body') || node === document.querySelector('html')
153
+ )
154
+ }
155
+
156
+ export const isHoriz = (pos: string) => /(left|right)/.test(pos)
157
+ export const isOutsideX = (val: number, windowWidth: number) => val > windowWidth
158
+ export const isOutsideY = (val: number, windowHeight: number) => val > windowHeight
159
+ export const safe = (sum: number) => (sum < 0 ? 0 : sum)
160
+
161
+ export function bestPositionOf(positions: { [key: string]: number }) {
162
+ return Object.keys(positions)
163
+ .map((p) => ({ position: p, value: positions[p] }))
164
+ .sort((a, b) => b.value - a.value)
165
+ .map((p) => p.position)
166
+ }
167
+
168
+ export function getWindow() {
169
+ const w = Math.max(document.documentElement.clientWidth, window.innerWidth ?? 0)
170
+ const h = Math.max(document.documentElement.clientHeight, window.innerHeight ?? 0)
171
+ return { w, h }
172
+ }