@teleporthq/teleport-shared 0.43.70 → 0.43.71
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/__tests__/motion-runtime/motion-engine.ts +102 -0
- package/__tests__/motion-runtime/scroll-video-engine.ts +28 -0
- package/__tests__/scroll-scene/story-lanes.ts +126 -0
- package/dist/cjs/index.d.ts +5 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +9 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/motion-runtime/index.d.ts +3 -0
- package/dist/cjs/motion-runtime/index.d.ts.map +1 -0
- package/dist/cjs/motion-runtime/index.js +8 -0
- package/dist/cjs/motion-runtime/index.js.map +1 -0
- package/dist/cjs/motion-runtime/motion-engine-source.d.ts +16 -0
- package/dist/cjs/motion-runtime/motion-engine-source.d.ts.map +1 -0
- package/dist/cjs/motion-runtime/motion-engine-source.js +20 -0
- package/dist/cjs/motion-runtime/motion-engine-source.js.map +1 -0
- package/dist/cjs/motion-runtime/scroll-video-engine-source.d.ts +9 -0
- package/dist/cjs/motion-runtime/scroll-video-engine-source.d.ts.map +1 -0
- package/dist/cjs/motion-runtime/scroll-video-engine-source.js +13 -0
- package/dist/cjs/motion-runtime/scroll-video-engine-source.js.map +1 -0
- package/dist/cjs/page-transition/index.d.ts +4 -0
- package/dist/cjs/page-transition/index.d.ts.map +1 -0
- package/dist/cjs/page-transition/index.js +20 -0
- package/dist/cjs/page-transition/index.js.map +1 -0
- package/dist/cjs/page-transition/morph-source.d.ts +20 -0
- package/dist/cjs/page-transition/morph-source.d.ts.map +1 -0
- package/dist/cjs/page-transition/morph-source.js +25 -0
- package/dist/cjs/page-transition/morph-source.js.map +1 -0
- package/dist/cjs/page-transition/variants.d.ts +87 -0
- package/dist/cjs/page-transition/variants.d.ts.map +1 -0
- package/dist/cjs/page-transition/variants.js +330 -0
- package/dist/cjs/page-transition/variants.js.map +1 -0
- package/dist/cjs/page-transition/view-transition-css.d.ts +21 -0
- package/dist/cjs/page-transition/view-transition-css.d.ts.map +1 -0
- package/dist/cjs/page-transition/view-transition-css.js +188 -0
- package/dist/cjs/page-transition/view-transition-css.js.map +1 -0
- package/dist/cjs/scroll-scene/chapter-index.d.ts +15 -0
- package/dist/cjs/scroll-scene/chapter-index.d.ts.map +1 -0
- package/dist/cjs/scroll-scene/chapter-index.js +30 -0
- package/dist/cjs/scroll-scene/chapter-index.js.map +1 -0
- package/dist/cjs/scroll-scene/controller-source.d.ts +26 -0
- package/dist/cjs/scroll-scene/controller-source.d.ts.map +1 -0
- package/dist/cjs/scroll-scene/controller-source.js +34 -0
- package/dist/cjs/scroll-scene/controller-source.js.map +1 -0
- package/dist/cjs/scroll-scene/engine-source.d.ts +2 -0
- package/dist/cjs/scroll-scene/engine-source.d.ts.map +1 -0
- package/dist/cjs/scroll-scene/engine-source.js +26 -0
- package/dist/cjs/scroll-scene/engine-source.js.map +1 -0
- package/dist/cjs/scroll-scene/index.d.ts +7 -0
- package/dist/cjs/scroll-scene/index.d.ts.map +1 -0
- package/dist/cjs/scroll-scene/index.js +22 -0
- package/dist/cjs/scroll-scene/index.js.map +1 -0
- package/dist/cjs/scroll-scene/moment.d.ts +21 -0
- package/dist/cjs/scroll-scene/moment.d.ts.map +1 -0
- package/dist/cjs/scroll-scene/moment.js +50 -0
- package/dist/cjs/scroll-scene/moment.js.map +1 -0
- package/dist/cjs/scroll-scene/points.d.ts +23 -0
- package/dist/cjs/scroll-scene/points.d.ts.map +1 -0
- package/dist/cjs/scroll-scene/points.js +51 -0
- package/dist/cjs/scroll-scene/points.js.map +1 -0
- package/dist/cjs/scroll-scene/unclip.d.ts +15 -0
- package/dist/cjs/scroll-scene/unclip.d.ts.map +1 -0
- package/dist/cjs/scroll-scene/unclip.js +44 -0
- package/dist/cjs/scroll-scene/unclip.js.map +1 -0
- package/dist/cjs/state-bindings/index.d.ts +74 -0
- package/dist/cjs/state-bindings/index.d.ts.map +1 -0
- package/dist/cjs/state-bindings/index.js +193 -0
- package/dist/cjs/state-bindings/index.js.map +1 -0
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/index.d.ts +5 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +5 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/motion-runtime/index.d.ts +3 -0
- package/dist/esm/motion-runtime/index.d.ts.map +1 -0
- package/dist/esm/motion-runtime/index.js +3 -0
- package/dist/esm/motion-runtime/index.js.map +1 -0
- package/dist/esm/motion-runtime/motion-engine-source.d.ts +16 -0
- package/dist/esm/motion-runtime/motion-engine-source.d.ts.map +1 -0
- package/dist/esm/motion-runtime/motion-engine-source.js +16 -0
- package/dist/esm/motion-runtime/motion-engine-source.js.map +1 -0
- package/dist/esm/motion-runtime/scroll-video-engine-source.d.ts +9 -0
- package/dist/esm/motion-runtime/scroll-video-engine-source.d.ts.map +1 -0
- package/dist/esm/motion-runtime/scroll-video-engine-source.js +9 -0
- package/dist/esm/motion-runtime/scroll-video-engine-source.js.map +1 -0
- package/dist/esm/page-transition/index.d.ts +4 -0
- package/dist/esm/page-transition/index.d.ts.map +1 -0
- package/dist/esm/page-transition/index.js +4 -0
- package/dist/esm/page-transition/index.js.map +1 -0
- package/dist/esm/page-transition/morph-source.d.ts +20 -0
- package/dist/esm/page-transition/morph-source.d.ts.map +1 -0
- package/dist/esm/page-transition/morph-source.js +21 -0
- package/dist/esm/page-transition/morph-source.js.map +1 -0
- package/dist/esm/page-transition/variants.d.ts +87 -0
- package/dist/esm/page-transition/variants.d.ts.map +1 -0
- package/dist/esm/page-transition/variants.js +318 -0
- package/dist/esm/page-transition/variants.js.map +1 -0
- package/dist/esm/page-transition/view-transition-css.d.ts +21 -0
- package/dist/esm/page-transition/view-transition-css.d.ts.map +1 -0
- package/dist/esm/page-transition/view-transition-css.js +161 -0
- package/dist/esm/page-transition/view-transition-css.js.map +1 -0
- package/dist/esm/scroll-scene/chapter-index.d.ts +15 -0
- package/dist/esm/scroll-scene/chapter-index.d.ts.map +1 -0
- package/dist/esm/scroll-scene/chapter-index.js +26 -0
- package/dist/esm/scroll-scene/chapter-index.js.map +1 -0
- package/dist/esm/scroll-scene/controller-source.d.ts +26 -0
- package/dist/esm/scroll-scene/controller-source.d.ts.map +1 -0
- package/dist/esm/scroll-scene/controller-source.js +26 -0
- package/dist/esm/scroll-scene/controller-source.js.map +1 -0
- package/dist/esm/scroll-scene/engine-source.d.ts +2 -0
- package/dist/esm/scroll-scene/engine-source.d.ts.map +1 -0
- package/dist/esm/scroll-scene/engine-source.js +22 -0
- package/dist/esm/scroll-scene/engine-source.js.map +1 -0
- package/dist/esm/scroll-scene/index.d.ts +7 -0
- package/dist/esm/scroll-scene/index.d.ts.map +1 -0
- package/dist/esm/scroll-scene/index.js +7 -0
- package/dist/esm/scroll-scene/index.js.map +1 -0
- package/dist/esm/scroll-scene/moment.d.ts +21 -0
- package/dist/esm/scroll-scene/moment.d.ts.map +1 -0
- package/dist/esm/scroll-scene/moment.js +46 -0
- package/dist/esm/scroll-scene/moment.js.map +1 -0
- package/dist/esm/scroll-scene/points.d.ts +23 -0
- package/dist/esm/scroll-scene/points.d.ts.map +1 -0
- package/dist/esm/scroll-scene/points.js +45 -0
- package/dist/esm/scroll-scene/points.js.map +1 -0
- package/dist/esm/scroll-scene/unclip.d.ts +15 -0
- package/dist/esm/scroll-scene/unclip.d.ts.map +1 -0
- package/dist/esm/scroll-scene/unclip.js +40 -0
- package/dist/esm/scroll-scene/unclip.js.map +1 -0
- package/dist/esm/state-bindings/index.d.ts +74 -0
- package/dist/esm/state-bindings/index.d.ts.map +1 -0
- package/dist/esm/state-bindings/index.js +176 -0
- package/dist/esm/state-bindings/index.js.map +1 -0
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/index.ts +8 -0
- package/src/motion-runtime/index.ts +2 -0
- package/src/motion-runtime/motion-engine-source.ts +289 -0
- package/src/motion-runtime/scroll-video-engine-source.ts +591 -0
- package/src/page-transition/index.ts +3 -0
- package/src/page-transition/morph-source.ts +86 -0
- package/src/page-transition/variants.ts +407 -0
- package/src/page-transition/view-transition-css.ts +237 -0
- package/src/scroll-scene/chapter-index.ts +25 -0
- package/src/scroll-scene/controller-source.ts +451 -0
- package/src/scroll-scene/engine-source.ts +330 -0
- package/src/scroll-scene/index.ts +12 -0
- package/src/scroll-scene/moment.ts +64 -0
- package/src/scroll-scene/points.ts +46 -0
- package/src/scroll-scene/unclip.ts +44 -0
- package/src/state-bindings/index.ts +207 -0
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The element-motion engine as SOURCE TEXT: easing curves, the preset table, the
|
|
3
|
+
* from/to state helpers and the viewport-fraction maths. Plain JavaScript with
|
|
4
|
+
* no framework in it, shared word for word by the two exports:
|
|
5
|
+
*
|
|
6
|
+
* - the Next export wraps it in the TqMotion React component (framer-motion
|
|
7
|
+
* plays the entrance and supplies the scroll progress);
|
|
8
|
+
* - the HTML export wraps it in a vanilla controller (the Web Animations API
|
|
9
|
+
* plays the entrance, a scroll listener supplies the progress).
|
|
10
|
+
*
|
|
11
|
+
* One copy means a new preset reaches both exports at once. It mirrors the
|
|
12
|
+
* canvas renderer's motion-keyframes module. (No backticks in the engine's own
|
|
13
|
+
* comments unless escaped: it is a template literal.)
|
|
14
|
+
*/
|
|
15
|
+
export const motionEngineSource = (): string => `const EASINGS = {
|
|
16
|
+
ease: [0.25, 0.1, 0.25, 1],
|
|
17
|
+
'ease-in': [0.42, 0, 1, 1],
|
|
18
|
+
'ease-out': [0, 0, 0.58, 1],
|
|
19
|
+
'ease-in-out': [0.42, 0, 0.58, 1],
|
|
20
|
+
linear: [0, 0, 1, 1],
|
|
21
|
+
spring: [0.34, 1.56, 0.64, 1],
|
|
22
|
+
back: [0.68, -0.6, 0.32, 1.6],
|
|
23
|
+
bounce: [0.22, 1.2, 0.36, 1],
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Mirrors the canvas renderer's motion-keyframes helpers so a scroll-linked
|
|
27
|
+
// element interpolates EVERY from/to property (x/y/scale/rotate/opacity/filter)
|
|
28
|
+
// identically in the canvas, the preview and the published site. The key ORDER
|
|
29
|
+
// is the order the canvas composes them in: it has to match \`cssFromState\` in
|
|
30
|
+
// the renderer's motion-keyframes exactly, or a staggered card and its canvas
|
|
31
|
+
// twin would compose the same values differently. Both the scroll-linked path
|
|
32
|
+
// (\`applyScrollState\`) and the in-place stagger (\`cssFromState\`) build on these.
|
|
33
|
+
const TRANSFORM_KEYS = ['x', 'y', 'scale', 'rotate']
|
|
34
|
+
|
|
35
|
+
// The transform family is written as the INDIVIDUAL transform properties
|
|
36
|
+
// (translate / scale / rotate) and never as the transform property itself, so
|
|
37
|
+
// whatever the author put in transform (a translateX(-50%) centering, a tilt)
|
|
38
|
+
// survives the animation and the browser composes the two. Mirrors the canvas.
|
|
39
|
+
const withUnit = (value, unit) => (typeof value === 'number' ? value + unit : String(value))
|
|
40
|
+
|
|
41
|
+
const writeTransformProps = (css, state) => {
|
|
42
|
+
if (state.x !== undefined || state.y !== undefined) {
|
|
43
|
+
css.translate =
|
|
44
|
+
withUnit(state.x !== undefined ? state.x : 0, 'px') +
|
|
45
|
+
' ' +
|
|
46
|
+
withUnit(state.y !== undefined ? state.y : 0, 'px')
|
|
47
|
+
}
|
|
48
|
+
if (state.scale !== undefined) {
|
|
49
|
+
css.scale = String(state.scale)
|
|
50
|
+
}
|
|
51
|
+
if (state.rotate !== undefined) {
|
|
52
|
+
css.rotate = withUnit(state.rotate, 'deg')
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Composed filters (blur(10px) grayscale(1) -> blur(0px) grayscale(0))
|
|
57
|
+
// interpolate function-by-function when both sides carry the same sequence —
|
|
58
|
+
// mirrors the canvas contract.
|
|
59
|
+
const FILTER_LIST_RE = /^(?:[a-z-]+\\(\\s*-?\\d*\\.?\\d+(?:px|deg|%)?\\s*\\)\\s*)+$/
|
|
60
|
+
const FILTER_FN_RE = /([a-z-]+)\\(\\s*(-?\\d*\\.?\\d+)(px|deg|%)?\\s*\\)/g
|
|
61
|
+
|
|
62
|
+
const interpolateFilter = (from, to, p) => {
|
|
63
|
+
if (!FILTER_LIST_RE.test(from.trim()) || !FILTER_LIST_RE.test(to.trim())) {
|
|
64
|
+
return null
|
|
65
|
+
}
|
|
66
|
+
const fromFns = Array.from(from.matchAll(FILTER_FN_RE))
|
|
67
|
+
const toFns = Array.from(to.matchAll(FILTER_FN_RE))
|
|
68
|
+
if (fromFns.length !== toFns.length || fromFns.length === 0) {
|
|
69
|
+
return null
|
|
70
|
+
}
|
|
71
|
+
const parts = []
|
|
72
|
+
for (let index = 0; index < fromFns.length; index++) {
|
|
73
|
+
const fn = fromFns[index][1]
|
|
74
|
+
const unit = fromFns[index][3] || ''
|
|
75
|
+
if (fn !== toFns[index][1] || unit !== (toFns[index][3] || '')) {
|
|
76
|
+
return null
|
|
77
|
+
}
|
|
78
|
+
const value =
|
|
79
|
+
parseFloat(fromFns[index][2]) +
|
|
80
|
+
(parseFloat(toFns[index][2]) - parseFloat(fromFns[index][2])) * p
|
|
81
|
+
parts.push(fn + '(' + value + unit + ')')
|
|
82
|
+
}
|
|
83
|
+
return parts.join(' ')
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// A value with a unit (-50%, 2rem) glides in that unit when both ends use the
|
|
87
|
+
// same one, as it does on the canvas. A played entrance gets this from
|
|
88
|
+
// framer-motion or the Web Animations API; the scroll-linked path gets it here.
|
|
89
|
+
const UNIT_VALUE_RE = /^(-?\\d*\\.?\\d+)(px|%|deg|rem|em|vw|vh)$/
|
|
90
|
+
|
|
91
|
+
const interpolateUnitValue = (from, to, p) => {
|
|
92
|
+
const start = UNIT_VALUE_RE.exec(from.trim())
|
|
93
|
+
const end = UNIT_VALUE_RE.exec(to.trim())
|
|
94
|
+
if (!start || !end || start[2] !== end[2]) {
|
|
95
|
+
return null
|
|
96
|
+
}
|
|
97
|
+
const startAmount = parseFloat(start[1])
|
|
98
|
+
return startAmount + (parseFloat(end[1]) - startAmount) * p + start[2]
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const interpolateValue = (from, to, p) => {
|
|
102
|
+
if (typeof from === 'number' && typeof to === 'number') {
|
|
103
|
+
return from + (to - from) * p
|
|
104
|
+
}
|
|
105
|
+
if (typeof from === 'string' && typeof to === 'string') {
|
|
106
|
+
const united = interpolateUnitValue(from, to, p)
|
|
107
|
+
if (united !== null) {
|
|
108
|
+
return united
|
|
109
|
+
}
|
|
110
|
+
const filter = interpolateFilter(from, to, p)
|
|
111
|
+
if (filter !== null) {
|
|
112
|
+
return filter
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return p >= 1 ? to : from
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const applyScrollState = (element, fromVars, toVars, p) => {
|
|
119
|
+
if (!element) {
|
|
120
|
+
return
|
|
121
|
+
}
|
|
122
|
+
const keys = new Set([...Object.keys(fromVars), ...Object.keys(toVars)])
|
|
123
|
+
const transformState = {}
|
|
124
|
+
keys.forEach((key) => {
|
|
125
|
+
const fromValue = fromVars[key] !== undefined ? fromVars[key] : toVars[key]
|
|
126
|
+
const toValue = toVars[key] !== undefined ? toVars[key] : fromVars[key]
|
|
127
|
+
const value = interpolateValue(fromValue, toValue, p)
|
|
128
|
+
if (TRANSFORM_KEYS.includes(key)) {
|
|
129
|
+
transformState[key] = value
|
|
130
|
+
} else {
|
|
131
|
+
element.style[key] = String(value)
|
|
132
|
+
}
|
|
133
|
+
})
|
|
134
|
+
const transformCss = {}
|
|
135
|
+
writeTransformProps(transformCss, transformState)
|
|
136
|
+
Object.keys(transformCss).forEach((prop) => {
|
|
137
|
+
element.style[prop] = transformCss[prop]
|
|
138
|
+
})
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// useScroll offset pairs per motion-scroll-offset mode — mirrors the canvas
|
|
142
|
+
// runtime's scrollProgressForOffset semantics.
|
|
143
|
+
const SCROLL_OFFSET_RANGES = {
|
|
144
|
+
pass: ['start end', 'end start'],
|
|
145
|
+
contained: ['start start', 'end end'],
|
|
146
|
+
enter: ['start end', 'start start'],
|
|
147
|
+
exit: ['end end', 'end start'],
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const presetStates = (preset, distance) => {
|
|
151
|
+
switch (preset) {
|
|
152
|
+
case 'fade-in':
|
|
153
|
+
return { from: { opacity: 0 }, to: { opacity: 1 } }
|
|
154
|
+
case 'slide-up':
|
|
155
|
+
return { from: { opacity: 0, y: distance }, to: { opacity: 1, y: 0 } }
|
|
156
|
+
case 'slide-down':
|
|
157
|
+
return { from: { opacity: 0, y: -distance }, to: { opacity: 1, y: 0 } }
|
|
158
|
+
case 'slide-left':
|
|
159
|
+
return { from: { opacity: 0, x: distance }, to: { opacity: 1, x: 0 } }
|
|
160
|
+
case 'slide-right':
|
|
161
|
+
return { from: { opacity: 0, x: -distance }, to: { opacity: 1, x: 0 } }
|
|
162
|
+
case 'scale-in':
|
|
163
|
+
return { from: { opacity: 0, scale: 0.8 }, to: { opacity: 1, scale: 1 } }
|
|
164
|
+
case 'zoom-in':
|
|
165
|
+
return { from: { opacity: 0, scale: 0.5 }, to: { opacity: 1, scale: 1 } }
|
|
166
|
+
case 'pop-in':
|
|
167
|
+
return { from: { opacity: 0, scale: 0.6 }, to: { opacity: 1, scale: 1 } }
|
|
168
|
+
case 'rotate-in':
|
|
169
|
+
return { from: { opacity: 0, rotate: -8 }, to: { opacity: 1, rotate: 0 } }
|
|
170
|
+
case 'tilt-in':
|
|
171
|
+
return { from: { opacity: 0, rotate: -10, y: distance }, to: { opacity: 1, rotate: 0, y: 0 } }
|
|
172
|
+
case 'blur-in':
|
|
173
|
+
return { from: { opacity: 0, filter: 'blur(12px)' }, to: { opacity: 1, filter: 'blur(0px)' } }
|
|
174
|
+
case 'blur-up':
|
|
175
|
+
return {
|
|
176
|
+
from: { opacity: 0, y: distance, filter: 'blur(8px)' },
|
|
177
|
+
to: { opacity: 1, y: 0, filter: 'blur(0px)' },
|
|
178
|
+
}
|
|
179
|
+
case 'drop-in':
|
|
180
|
+
return {
|
|
181
|
+
from: { opacity: 0, y: -distance, scale: 1.05 },
|
|
182
|
+
to: { opacity: 1, y: 0, scale: 1 },
|
|
183
|
+
}
|
|
184
|
+
case 'swing-in':
|
|
185
|
+
return { from: { opacity: 0, rotate: -20, y: distance }, to: { opacity: 1, rotate: 0, y: 0 } }
|
|
186
|
+
case 'spin-in':
|
|
187
|
+
return {
|
|
188
|
+
from: { opacity: 0, rotate: -180, scale: 0.6 },
|
|
189
|
+
to: { opacity: 1, rotate: 0, scale: 1 },
|
|
190
|
+
}
|
|
191
|
+
case 'blur-zoom':
|
|
192
|
+
return {
|
|
193
|
+
from: { opacity: 0, scale: 1.35, filter: 'blur(10px)' },
|
|
194
|
+
to: { opacity: 1, scale: 1, filter: 'blur(0px)' },
|
|
195
|
+
}
|
|
196
|
+
case 'zoom-out':
|
|
197
|
+
return { from: { opacity: 0, scale: 1.4 }, to: { opacity: 1, scale: 1 } }
|
|
198
|
+
case 'develop':
|
|
199
|
+
return {
|
|
200
|
+
from: { opacity: 0, filter: 'blur(6px) grayscale(1)' },
|
|
201
|
+
to: { opacity: 1, filter: 'blur(0px) grayscale(0)' },
|
|
202
|
+
}
|
|
203
|
+
case 'glow-in':
|
|
204
|
+
return {
|
|
205
|
+
from: { opacity: 0, filter: 'brightness(1.8) saturate(0.4)' },
|
|
206
|
+
to: { opacity: 1, filter: 'brightness(1) saturate(1)' },
|
|
207
|
+
}
|
|
208
|
+
// Attention loops: rest at the natural state (NO opacity ramp — a looping
|
|
209
|
+
// opacity would strobe) and read as animation only when repeated (mirror).
|
|
210
|
+
case 'pulse':
|
|
211
|
+
return { from: { scale: 1 }, to: { scale: 1.06 } }
|
|
212
|
+
case 'float':
|
|
213
|
+
return { from: { y: 0 }, to: { y: -12 } }
|
|
214
|
+
case 'spin':
|
|
215
|
+
return { from: { rotate: 0 }, to: { rotate: 360 } }
|
|
216
|
+
case 'wobble':
|
|
217
|
+
return { from: { rotate: -3 }, to: { rotate: 3 } }
|
|
218
|
+
case 'none':
|
|
219
|
+
return { from: {}, to: {} }
|
|
220
|
+
default:
|
|
221
|
+
return { from: { opacity: 0 }, to: { opacity: 1 } }
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Turn a resolved motion state ({ opacity, x, y, scale, rotate, filter, … }) into
|
|
226
|
+
// an inline style object: the transform keys become the individual translate /
|
|
227
|
+
// scale / rotate properties and every other key passes through as its own CSS
|
|
228
|
+
// property. Mirrors the canvas.
|
|
229
|
+
const cssFromState = (state) => {
|
|
230
|
+
const css = {}
|
|
231
|
+
writeTransformProps(css, state)
|
|
232
|
+
Object.keys(state).forEach((key) => {
|
|
233
|
+
if (TRANSFORM_KEYS.indexOf(key) !== -1) {
|
|
234
|
+
return
|
|
235
|
+
}
|
|
236
|
+
css[key] = state[key]
|
|
237
|
+
})
|
|
238
|
+
return css
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// How much of the element is inside the viewport right now, as a 0..1 fraction
|
|
242
|
+
// of its own area — the same quantity IntersectionObserver thresholds on, so the
|
|
243
|
+
// failsafe below can apply exactly the threshold useInView was given.
|
|
244
|
+
const visibleFraction = (rect, vh, vw) => {
|
|
245
|
+
const height = rect.bottom - rect.top
|
|
246
|
+
const width = rect.right - rect.left
|
|
247
|
+
if (height <= 0 || width <= 0) {
|
|
248
|
+
return 0
|
|
249
|
+
}
|
|
250
|
+
const visibleHeight = Math.max(0, Math.min(rect.bottom, vh) - Math.max(rect.top, 0))
|
|
251
|
+
const visibleWidth = Math.max(0, Math.min(rect.right, vw) - Math.max(rect.left, 0))
|
|
252
|
+
return (visibleHeight * visibleWidth) / (height * width)
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// The largest fraction this element could EVER have on screen. An element taller
|
|
256
|
+
// than the viewport can never be 60% visible, so an inViewAmount above that is
|
|
257
|
+
// unsatisfiable and would hold the content at opacity 0 permanently. Clamping to
|
|
258
|
+
// what is physically reachable turns "impossible" into "as visible as it gets".
|
|
259
|
+
const reachableFraction = (rect, vh, vw) => {
|
|
260
|
+
const height = rect.bottom - rect.top
|
|
261
|
+
const width = rect.right - rect.left
|
|
262
|
+
if (height <= 0 || width <= 0) {
|
|
263
|
+
return 0
|
|
264
|
+
}
|
|
265
|
+
return Math.min(1, vh / height) * Math.min(1, vw / width)
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// A row that slides by itself is the editor's loop: a clipping frame
|
|
269
|
+
// (data-marquee) holding this Motion track, which holds the row and the hidden
|
|
270
|
+
// copy that closes the loop (data-marquee-copy). For a visitor who asks for
|
|
271
|
+
// less motion the track does not play, so the row stands still and the frame
|
|
272
|
+
// lets the visitor swipe it instead: every item stays reachable. The copy
|
|
273
|
+
// goes, or every item would show twice, and the track stops reserving room
|
|
274
|
+
// for it. Mirrors letMarqueeSwipe in the editor's marquee contract.
|
|
275
|
+
const MARQUEE_FRAME_ATTR = 'data-marquee'
|
|
276
|
+
const MARQUEE_COPY_ATTR = 'data-marquee-copy'
|
|
277
|
+
const letMarqueeSwipe = (track) => {
|
|
278
|
+
const frame = track && track.parentElement
|
|
279
|
+
if (!frame || !frame.hasAttribute(MARQUEE_FRAME_ATTR)) {
|
|
280
|
+
return
|
|
281
|
+
}
|
|
282
|
+
frame.style.overflowX = 'auto'
|
|
283
|
+
track.style.minWidth = '100%'
|
|
284
|
+
for (const child of Array.from(track.children)) {
|
|
285
|
+
if (child.hasAttribute(MARQUEE_COPY_ATTR)) {
|
|
286
|
+
child.style.display = 'none'
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}`
|