-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Expand file tree
/
Copy pathoffset-to-range.ts
More file actions
63 lines (55 loc) · 1.76 KB
/
offset-to-range.ts
File metadata and controls
63 lines (55 loc) · 1.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import { ScrollOffset as ScrollOffsetPresets } from "../offsets/presets"
import { ProgressIntersection, ScrollOffset } from "../types"
interface ViewTimelineRange {
rangeStart: string
rangeEnd: string
}
/**
* Maps from ProgressIntersection pairs used by Motion's preset offsets to
* ViewTimeline named ranges. Returns undefined for unrecognised patterns,
* which signals the caller to fall back to JS-based scroll tracking.
*/
const presets: [ProgressIntersection[], string][] = [
[ScrollOffsetPresets.Enter, "entry"],
[ScrollOffsetPresets.Exit, "exit"],
[ScrollOffsetPresets.Any, "cover"],
[ScrollOffsetPresets.All, "contain"],
]
function normaliseOffset(offset: ScrollOffset): ProgressIntersection[] | undefined {
if (offset.length !== 2) return undefined
const result: ProgressIntersection[] = []
for (const item of offset) {
if (Array.isArray(item)) {
result.push(item as ProgressIntersection)
} else {
return undefined
}
}
return result
}
function matchesPreset(
offset: ScrollOffset,
preset: ProgressIntersection[]
): boolean {
const normalised = normaliseOffset(offset)
if (!normalised) return false
for (let i = 0; i < 2; i++) {
const o = normalised[i]
const p = preset[i]
if (o[0] !== p[0] || o[1] !== p[1]) return false
}
return true
}
export function offsetToViewTimelineRange(
offset?: ScrollOffset
): ViewTimelineRange | undefined {
if (!offset) {
return { rangeStart: "contain 0%", rangeEnd: "contain 100%" }
}
for (const [preset, name] of presets) {
if (matchesPreset(offset, preset)) {
return { rangeStart: `${name} 0%`, rangeEnd: `${name} 100%` }
}
}
return undefined
}