@internetarchive/elements 0.2.13-webdev-9022.2 → 0.2.13
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/dist/src/elements/index.d.ts +0 -1
- package/dist/src/elements/index.d.ts.map +1 -1
- package/dist/src/elements/index.js +0 -1
- package/dist/src/elements/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/src/elements/ia-image-viewer/ia-image-viewer.d.ts +0 -147
- package/dist/src/elements/ia-image-viewer/ia-image-viewer.d.ts.map +0 -1
- package/dist/src/elements/ia-image-viewer/ia-image-viewer.js +0 -533
- package/dist/src/elements/ia-image-viewer/ia-image-viewer.js.map +0 -1
- package/dist/src/elements/ia-image-viewer/ia-imgview-controls.d.ts +0 -22
- package/dist/src/elements/ia-image-viewer/ia-imgview-controls.d.ts.map +0 -1
- package/dist/src/elements/ia-image-viewer/ia-imgview-controls.js +0 -145
- package/dist/src/elements/ia-image-viewer/ia-imgview-controls.js.map +0 -1
- package/dist/src/elements/ia-image-viewer/ia-imgview-slide.d.ts +0 -44
- package/dist/src/elements/ia-image-viewer/ia-imgview-slide.d.ts.map +0 -1
- package/dist/src/elements/ia-image-viewer/ia-imgview-slide.js +0 -213
- package/dist/src/elements/ia-image-viewer/ia-imgview-slide.js.map +0 -1
- package/dist/src/elements/ia-image-viewer/image-viewer-gestures.d.ts +0 -79
- package/dist/src/elements/ia-image-viewer/image-viewer-gestures.d.ts.map +0 -1
- package/dist/src/elements/ia-image-viewer/image-viewer-gestures.js +0 -254
- package/dist/src/elements/ia-image-viewer/image-viewer-gestures.js.map +0 -1
- package/dist/src/elements/ia-image-viewer/models.d.ts +0 -20
- package/dist/src/elements/ia-image-viewer/models.d.ts.map +0 -1
- package/dist/src/elements/ia-image-viewer/models.js +0 -2
- package/dist/src/elements/ia-image-viewer/models.js.map +0 -1
- package/dist/src/util/prefers-reduced-motion.d.ts +0 -10
- package/dist/src/util/prefers-reduced-motion.d.ts.map +0 -1
- package/dist/src/util/prefers-reduced-motion.js +0 -12
- package/dist/src/util/prefers-reduced-motion.js.map +0 -1
|
@@ -1,254 +0,0 @@
|
|
|
1
|
-
import { prefersReducedMotion } from '../../util/prefers-reduced-motion.js';
|
|
2
|
-
/** Minimum horizontal travel before a gesture counts as a swipe at all */
|
|
3
|
-
const SWIPE_THRESHOLD = 30;
|
|
4
|
-
/** Minimum swipe distance (fraction of width) to commit navigation */
|
|
5
|
-
const SWIPE_COMMIT_FRACTION = 0.25;
|
|
6
|
-
/** Minimum velocity (px/ms) for a flick to commit regardless of distance */
|
|
7
|
-
const SWIPE_FLICK_VELOCITY = 0.3;
|
|
8
|
-
/** Longest the track takes to settle after the finger lifts */
|
|
9
|
-
const SETTLE_MAX_MS = 300;
|
|
10
|
-
/** How long a snap-back takes when the swipe didn't go far enough */
|
|
11
|
-
const SNAP_BACK_MS = 200;
|
|
12
|
-
/** Horizontal wheel travel that adds up to one navigation */
|
|
13
|
-
const WHEEL_THRESHOLD = 80;
|
|
14
|
-
/** How long after an animation to keep ignoring wheel inertia */
|
|
15
|
-
const WHEEL_COOLDOWN_MS = 300;
|
|
16
|
-
/** How far a finger travels before the gesture locks in as horizontal */
|
|
17
|
-
const SWIPE_LOCK_DISTANCE = 10;
|
|
18
|
-
/**
|
|
19
|
-
* Touch, wheel and keyboard navigation for the image viewer.
|
|
20
|
-
*
|
|
21
|
-
* A drag is driven imperatively: it translates the track directly and asks the
|
|
22
|
-
* viewer to insert neighbouring slides by hand, because a re-render mid-gesture
|
|
23
|
-
* would replace the element the touch started on and the browser would fire
|
|
24
|
-
* touchcancel.
|
|
25
|
-
*/
|
|
26
|
-
export class ImageViewerGestures {
|
|
27
|
-
constructor(host) {
|
|
28
|
-
/** Whether a drag is in progress. The viewer reads this while rendering. */
|
|
29
|
-
this.dragging = false;
|
|
30
|
-
/**
|
|
31
|
-
* The element the touch and wheel listeners are currently on, so they can
|
|
32
|
-
* follow the image area when it's replaced. A boolean wouldn't: the area is
|
|
33
|
-
* removed whenever the image list empties, and a later refill renders a
|
|
34
|
-
* different element.
|
|
35
|
-
*/
|
|
36
|
-
this.listeningTo = null;
|
|
37
|
-
this.touchStartX = null;
|
|
38
|
-
this.touchStartY = null;
|
|
39
|
-
this.touchStartTime = 0;
|
|
40
|
-
/** Whether the current gesture has locked in as a horizontal swipe */
|
|
41
|
-
this.swiping = false;
|
|
42
|
-
/** Set when a swipe completes, so the tap it ends on doesn't open the image */
|
|
43
|
-
this.swipeHandled = false;
|
|
44
|
-
this.dragOffsetX = 0;
|
|
45
|
-
this.wheelDeltaX = 0;
|
|
46
|
-
this.wheelAnimating = false;
|
|
47
|
-
this.wheelAnimationEndTime = 0;
|
|
48
|
-
this.onTouchStart = (e) => {
|
|
49
|
-
if (this.host.imageCount <= 1)
|
|
50
|
-
return;
|
|
51
|
-
this.host.settleIfAnimating();
|
|
52
|
-
const touch = e.touches[0];
|
|
53
|
-
this.touchStartX = touch.clientX;
|
|
54
|
-
this.touchStartY = touch.clientY;
|
|
55
|
-
this.touchStartTime = e.timeStamp;
|
|
56
|
-
this.swiping = false;
|
|
57
|
-
this.dragOffsetX = 0;
|
|
58
|
-
};
|
|
59
|
-
this.onTouchMove = (e) => {
|
|
60
|
-
if (this.touchStartX === null || this.touchStartY === null)
|
|
61
|
-
return;
|
|
62
|
-
const dx = e.touches[0].clientX - this.touchStartX;
|
|
63
|
-
const dy = e.touches[0].clientY - this.touchStartY;
|
|
64
|
-
const locksHorizontal = Math.abs(dx) > Math.abs(dy) && Math.abs(dx) > SWIPE_LOCK_DISTANCE;
|
|
65
|
-
if (!this.swiping && locksHorizontal) {
|
|
66
|
-
this.swiping = true;
|
|
67
|
-
this.dragging = true;
|
|
68
|
-
this.host.preloadAroundIndex(this.host.currentIndex);
|
|
69
|
-
this.host.insertDragSlides();
|
|
70
|
-
}
|
|
71
|
-
if (!this.swiping)
|
|
72
|
-
return;
|
|
73
|
-
e.preventDefault();
|
|
74
|
-
this.dragOffsetX = dx;
|
|
75
|
-
this.applyDragTransform();
|
|
76
|
-
};
|
|
77
|
-
this.onTouchEnd = (e) => {
|
|
78
|
-
if (this.touchStartX === null)
|
|
79
|
-
return;
|
|
80
|
-
const dx = e.changedTouches[0].clientX - this.touchStartX;
|
|
81
|
-
const elapsed = e.timeStamp - this.touchStartTime;
|
|
82
|
-
this.touchStartX = null;
|
|
83
|
-
this.touchStartY = null;
|
|
84
|
-
if (!this.swiping)
|
|
85
|
-
return;
|
|
86
|
-
this.swiping = false;
|
|
87
|
-
const track = this.host.slideTrack;
|
|
88
|
-
const area = this.host.imageArea;
|
|
89
|
-
if (!track || !area) {
|
|
90
|
-
this.dragging = false;
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
const width = area.offsetWidth;
|
|
94
|
-
const velocity = Math.abs(dx) / Math.max(elapsed, 1);
|
|
95
|
-
const pastThreshold = Math.abs(dx) > width * SWIPE_COMMIT_FRACTION;
|
|
96
|
-
const flicked = velocity > SWIPE_FLICK_VELOCITY;
|
|
97
|
-
const shouldCommit = (pastThreshold || flicked) && Math.abs(dx) >= SWIPE_THRESHOLD;
|
|
98
|
-
const direction = dx < 0 ? 'next' : 'prev';
|
|
99
|
-
this.swipeHandled = true;
|
|
100
|
-
// The rest of the way is proportional to how far the finger already got,
|
|
101
|
-
// so a nearly complete swipe finishes almost instantly.
|
|
102
|
-
const remainingFraction = (width - Math.abs(dx)) / width;
|
|
103
|
-
const completionDuration = shouldCommit
|
|
104
|
-
? Math.round(Math.max(100, Math.min(SETTLE_MAX_MS, remainingFraction * SETTLE_MAX_MS)))
|
|
105
|
-
: SNAP_BACK_MS;
|
|
106
|
-
const finalTransform = !shouldCommit
|
|
107
|
-
? 'translateX(-100%)'
|
|
108
|
-
: direction === 'next'
|
|
109
|
-
? 'translateX(-200%)'
|
|
110
|
-
: 'translateX(0%)';
|
|
111
|
-
const finish = () => {
|
|
112
|
-
track.style.transition = '';
|
|
113
|
-
track.style.transform = '';
|
|
114
|
-
if (shouldCommit)
|
|
115
|
-
this.host.commitDrag(direction);
|
|
116
|
-
this.dragging = false;
|
|
117
|
-
this.dragOffsetX = 0;
|
|
118
|
-
// Remove the hand-inserted slides before the viewer renders, since it
|
|
119
|
-
// doesn't track them and would leave them in the track.
|
|
120
|
-
this.host.removeDragSlides();
|
|
121
|
-
this.host.preloadAroundIndex(this.host.currentIndex);
|
|
122
|
-
this.host.requestUpdate();
|
|
123
|
-
};
|
|
124
|
-
// With reduced motion there's nothing to transition, and a zero-duration
|
|
125
|
-
// transition doesn't fire transitionend, so settle straight away rather
|
|
126
|
-
// than waiting on the timeout that would otherwise cover for it.
|
|
127
|
-
if (prefersReducedMotion()) {
|
|
128
|
-
track.style.transform = finalTransform;
|
|
129
|
-
finish();
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
track.style.transition = `transform ${completionDuration}ms ease-out`;
|
|
133
|
-
track.style.transform = finalTransform;
|
|
134
|
-
let settled = false;
|
|
135
|
-
const onTransitionDone = () => {
|
|
136
|
-
if (settled)
|
|
137
|
-
return;
|
|
138
|
-
settled = true;
|
|
139
|
-
track.removeEventListener('transitionend', onTransitionDone);
|
|
140
|
-
finish();
|
|
141
|
-
};
|
|
142
|
-
track.addEventListener('transitionend', onTransitionDone);
|
|
143
|
-
// Fallback in case transitionend doesn't fire
|
|
144
|
-
setTimeout(onTransitionDone, completionDuration + 50);
|
|
145
|
-
};
|
|
146
|
-
this.onWheel = (e) => {
|
|
147
|
-
if (this.host.imageCount <= 1)
|
|
148
|
-
return;
|
|
149
|
-
// Ignore vertical-dominant scrolls
|
|
150
|
-
if (Math.abs(e.deltaY) > Math.abs(e.deltaX))
|
|
151
|
-
return;
|
|
152
|
-
if (e.deltaX === 0)
|
|
153
|
-
return;
|
|
154
|
-
e.preventDefault();
|
|
155
|
-
// Block during animation and for a brief cooldown after to absorb inertia
|
|
156
|
-
const inCooldown = performance.now() - this.wheelAnimationEndTime < WHEEL_COOLDOWN_MS;
|
|
157
|
-
if (this.wheelAnimating || inCooldown) {
|
|
158
|
-
this.wheelDeltaX = 0;
|
|
159
|
-
return;
|
|
160
|
-
}
|
|
161
|
-
this.wheelDeltaX += e.deltaX;
|
|
162
|
-
if (Math.abs(this.wheelDeltaX) < WHEEL_THRESHOLD)
|
|
163
|
-
return;
|
|
164
|
-
const forward = this.wheelDeltaX > 0;
|
|
165
|
-
this.wheelDeltaX = 0;
|
|
166
|
-
this.wheelAnimating = true;
|
|
167
|
-
if (forward)
|
|
168
|
-
this.host.showNext();
|
|
169
|
-
else
|
|
170
|
-
this.host.showPrevious();
|
|
171
|
-
};
|
|
172
|
-
this.onKeydown = (e) => {
|
|
173
|
-
if (this.host.imageCount <= 1)
|
|
174
|
-
return;
|
|
175
|
-
const target = e.target;
|
|
176
|
-
if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA')
|
|
177
|
-
return;
|
|
178
|
-
if (target.isContentEditable)
|
|
179
|
-
return;
|
|
180
|
-
if (e.key === 'ArrowLeft')
|
|
181
|
-
this.host.showPrevious();
|
|
182
|
-
else if (e.key === 'ArrowRight')
|
|
183
|
-
this.host.showNext();
|
|
184
|
-
};
|
|
185
|
-
this.host = host;
|
|
186
|
-
host.addController(this);
|
|
187
|
-
}
|
|
188
|
-
hostConnected() {
|
|
189
|
-
document.addEventListener('keydown', this.onKeydown);
|
|
190
|
-
// Reconnecting doesn't schedule an update, so the gesture listeners have
|
|
191
|
-
// to be put back here rather than waiting for one.
|
|
192
|
-
this.attachListeners();
|
|
193
|
-
}
|
|
194
|
-
hostUpdated() {
|
|
195
|
-
this.attachListeners();
|
|
196
|
-
}
|
|
197
|
-
hostDisconnected() {
|
|
198
|
-
document.removeEventListener('keydown', this.onKeydown);
|
|
199
|
-
this.detachListeners();
|
|
200
|
-
}
|
|
201
|
-
/**
|
|
202
|
-
* Whether a swipe just ended on this tap, meaning the click that follows it
|
|
203
|
-
* should be ignored rather than treated as opening the image.
|
|
204
|
-
*/
|
|
205
|
-
consumeSwipeTap() {
|
|
206
|
-
if (!this.swipeHandled)
|
|
207
|
-
return false;
|
|
208
|
-
this.swipeHandled = false;
|
|
209
|
-
return true;
|
|
210
|
-
}
|
|
211
|
-
/** Lets wheel navigation resume once a slide animation has finished. */
|
|
212
|
-
animationSettled() {
|
|
213
|
-
this.wheelAnimating = false;
|
|
214
|
-
this.wheelAnimationEndTime = performance.now();
|
|
215
|
-
this.wheelDeltaX = 0;
|
|
216
|
-
}
|
|
217
|
-
/**
|
|
218
|
-
* Points the gesture listeners at the current image area, moving them off
|
|
219
|
-
* the previous one. The area isn't rendered until there are images to show,
|
|
220
|
-
* and it's torn down and rebuilt whenever the list empties and refills, so
|
|
221
|
-
* this runs on every update and re-attaches whenever the element changes.
|
|
222
|
-
*/
|
|
223
|
-
attachListeners() {
|
|
224
|
-
const area = this.host.imageArea;
|
|
225
|
-
if (area === this.listeningTo)
|
|
226
|
-
return;
|
|
227
|
-
this.detachListeners();
|
|
228
|
-
if (!area)
|
|
229
|
-
return;
|
|
230
|
-
this.listeningTo = area;
|
|
231
|
-
area.addEventListener('touchstart', this.onTouchStart, { passive: true });
|
|
232
|
-
area.addEventListener('touchmove', this.onTouchMove, { passive: false });
|
|
233
|
-
area.addEventListener('touchend', this.onTouchEnd, { passive: true });
|
|
234
|
-
area.addEventListener('wheel', this.onWheel, { passive: false });
|
|
235
|
-
}
|
|
236
|
-
detachListeners() {
|
|
237
|
-
const area = this.listeningTo;
|
|
238
|
-
if (!area)
|
|
239
|
-
return;
|
|
240
|
-
area.removeEventListener('touchstart', this.onTouchStart);
|
|
241
|
-
area.removeEventListener('touchmove', this.onTouchMove);
|
|
242
|
-
area.removeEventListener('touchend', this.onTouchEnd);
|
|
243
|
-
area.removeEventListener('wheel', this.onWheel);
|
|
244
|
-
this.listeningTo = null;
|
|
245
|
-
}
|
|
246
|
-
/** Applies the drag offset to the track during touch gestures. */
|
|
247
|
-
applyDragTransform() {
|
|
248
|
-
const track = this.host.slideTrack;
|
|
249
|
-
if (!this.dragging || !track)
|
|
250
|
-
return;
|
|
251
|
-
track.style.transform = `translateX(calc(-100% + ${this.dragOffsetX}px))`;
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
//# sourceMappingURL=image-viewer-gestures.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"image-viewer-gestures.js","sourceRoot":"","sources":["../../../../src/elements/ia-image-viewer/image-viewer-gestures.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReactiveController, ReactiveControllerHost } from 'lit';\n\nimport { prefersReducedMotion } from '@src/util/prefers-reduced-motion';\nimport type { SlideDirection } from './models';\n\n/** What the gesture controller needs from the viewer it drives. */\nexport type ImageViewerGestureHost = ReactiveControllerHost & {\n readonly imageCount: number;\n\n readonly currentIndex: number;\n\n /** The element gestures are tracked against, once it has rendered. */\n readonly imageArea?: HTMLElement;\n\n /** The element a drag translates. */\n readonly slideTrack?: HTMLElement;\n\n /** Commits an in-flight slide animation so a new one starts from rest. */\n settleIfAnimating(): void;\n\n showNext(): void;\n\n showPrevious(): void;\n\n preloadAroundIndex(index: number): void;\n\n /** Adds the neighbouring slides a drag reveals on either side. */\n insertDragSlides(): void;\n\n removeDragSlides(): void;\n\n /** Advances to the neighbouring image a completed drag landed on. */\n commitDrag(direction: SlideDirection): void;\n};\n\n/** Minimum horizontal travel before a gesture counts as a swipe at all */\nconst SWIPE_THRESHOLD = 30;\n\n/** Minimum swipe distance (fraction of width) to commit navigation */\nconst SWIPE_COMMIT_FRACTION = 0.25;\n\n/** Minimum velocity (px/ms) for a flick to commit regardless of distance */\nconst SWIPE_FLICK_VELOCITY = 0.3;\n\n/** Longest the track takes to settle after the finger lifts */\nconst SETTLE_MAX_MS = 300;\n\n/** How long a snap-back takes when the swipe didn't go far enough */\nconst SNAP_BACK_MS = 200;\n\n/** Horizontal wheel travel that adds up to one navigation */\nconst WHEEL_THRESHOLD = 80;\n\n/** How long after an animation to keep ignoring wheel inertia */\nconst WHEEL_COOLDOWN_MS = 300;\n\n/** How far a finger travels before the gesture locks in as horizontal */\nconst SWIPE_LOCK_DISTANCE = 10;\n\n/**\n * Touch, wheel and keyboard navigation for the image viewer.\n *\n * A drag is driven imperatively: it translates the track directly and asks the\n * viewer to insert neighbouring slides by hand, because a re-render mid-gesture\n * would replace the element the touch started on and the browser would fire\n * touchcancel.\n */\nexport class ImageViewerGestures implements ReactiveController {\n /** Whether a drag is in progress. The viewer reads this while rendering. */\n dragging = false;\n\n private host: ImageViewerGestureHost;\n\n /**\n * The element the touch and wheel listeners are currently on, so they can\n * follow the image area when it's replaced. A boolean wouldn't: the area is\n * removed whenever the image list empties, and a later refill renders a\n * different element.\n */\n private listeningTo: HTMLElement | null = null;\n\n private touchStartX: number | null = null;\n\n private touchStartY: number | null = null;\n\n private touchStartTime = 0;\n\n /** Whether the current gesture has locked in as a horizontal swipe */\n private swiping = false;\n\n /** Set when a swipe completes, so the tap it ends on doesn't open the image */\n private swipeHandled = false;\n\n private dragOffsetX = 0;\n\n private wheelDeltaX = 0;\n\n private wheelAnimating = false;\n\n private wheelAnimationEndTime = 0;\n\n constructor(host: ImageViewerGestureHost) {\n this.host = host;\n host.addController(this);\n }\n\n hostConnected(): void {\n document.addEventListener('keydown', this.onKeydown);\n // Reconnecting doesn't schedule an update, so the gesture listeners have\n // to be put back here rather than waiting for one.\n this.attachListeners();\n }\n\n hostUpdated(): void {\n this.attachListeners();\n }\n\n hostDisconnected(): void {\n document.removeEventListener('keydown', this.onKeydown);\n this.detachListeners();\n }\n\n /**\n * Whether a swipe just ended on this tap, meaning the click that follows it\n * should be ignored rather than treated as opening the image.\n */\n consumeSwipeTap(): boolean {\n if (!this.swipeHandled) return false;\n this.swipeHandled = false;\n return true;\n }\n\n /** Lets wheel navigation resume once a slide animation has finished. */\n animationSettled(): void {\n this.wheelAnimating = false;\n this.wheelAnimationEndTime = performance.now();\n this.wheelDeltaX = 0;\n }\n\n /**\n * Points the gesture listeners at the current image area, moving them off\n * the previous one. The area isn't rendered until there are images to show,\n * and it's torn down and rebuilt whenever the list empties and refills, so\n * this runs on every update and re-attaches whenever the element changes.\n */\n private attachListeners(): void {\n const area = this.host.imageArea;\n if (area === this.listeningTo) return;\n this.detachListeners();\n if (!area) return;\n\n this.listeningTo = area;\n area.addEventListener('touchstart', this.onTouchStart, { passive: true });\n area.addEventListener('touchmove', this.onTouchMove, { passive: false });\n area.addEventListener('touchend', this.onTouchEnd, { passive: true });\n area.addEventListener('wheel', this.onWheel, { passive: false });\n }\n\n private detachListeners(): void {\n const area = this.listeningTo;\n if (!area) return;\n area.removeEventListener('touchstart', this.onTouchStart);\n area.removeEventListener('touchmove', this.onTouchMove);\n area.removeEventListener('touchend', this.onTouchEnd);\n area.removeEventListener('wheel', this.onWheel);\n this.listeningTo = null;\n }\n\n private onTouchStart = (e: TouchEvent): void => {\n if (this.host.imageCount <= 1) return;\n this.host.settleIfAnimating();\n const touch = e.touches[0];\n this.touchStartX = touch.clientX;\n this.touchStartY = touch.clientY;\n this.touchStartTime = e.timeStamp;\n this.swiping = false;\n this.dragOffsetX = 0;\n };\n\n private onTouchMove = (e: TouchEvent): void => {\n if (this.touchStartX === null || this.touchStartY === null) return;\n const dx = e.touches[0].clientX - this.touchStartX;\n const dy = e.touches[0].clientY - this.touchStartY;\n\n const locksHorizontal =\n Math.abs(dx) > Math.abs(dy) && Math.abs(dx) > SWIPE_LOCK_DISTANCE;\n if (!this.swiping && locksHorizontal) {\n this.swiping = true;\n this.dragging = true;\n this.host.preloadAroundIndex(this.host.currentIndex);\n this.host.insertDragSlides();\n }\n\n if (!this.swiping) return;\n e.preventDefault();\n\n this.dragOffsetX = dx;\n this.applyDragTransform();\n };\n\n private onTouchEnd = (e: TouchEvent): void => {\n if (this.touchStartX === null) return;\n const dx = e.changedTouches[0].clientX - this.touchStartX;\n const elapsed = e.timeStamp - this.touchStartTime;\n this.touchStartX = null;\n this.touchStartY = null;\n\n if (!this.swiping) return;\n this.swiping = false;\n\n const track = this.host.slideTrack;\n const area = this.host.imageArea;\n if (!track || !area) {\n this.dragging = false;\n return;\n }\n\n const width = area.offsetWidth;\n const velocity = Math.abs(dx) / Math.max(elapsed, 1);\n const pastThreshold = Math.abs(dx) > width * SWIPE_COMMIT_FRACTION;\n const flicked = velocity > SWIPE_FLICK_VELOCITY;\n const shouldCommit =\n (pastThreshold || flicked) && Math.abs(dx) >= SWIPE_THRESHOLD;\n const direction: SlideDirection = dx < 0 ? 'next' : 'prev';\n\n this.swipeHandled = true;\n\n // The rest of the way is proportional to how far the finger already got,\n // so a nearly complete swipe finishes almost instantly.\n const remainingFraction = (width - Math.abs(dx)) / width;\n const completionDuration = shouldCommit\n ? Math.round(\n Math.max(\n 100,\n Math.min(SETTLE_MAX_MS, remainingFraction * SETTLE_MAX_MS),\n ),\n )\n : SNAP_BACK_MS;\n\n const finalTransform = !shouldCommit\n ? 'translateX(-100%)'\n : direction === 'next'\n ? 'translateX(-200%)'\n : 'translateX(0%)';\n\n const finish = (): void => {\n track.style.transition = '';\n track.style.transform = '';\n\n if (shouldCommit) this.host.commitDrag(direction);\n\n this.dragging = false;\n this.dragOffsetX = 0;\n // Remove the hand-inserted slides before the viewer renders, since it\n // doesn't track them and would leave them in the track.\n this.host.removeDragSlides();\n this.host.preloadAroundIndex(this.host.currentIndex);\n this.host.requestUpdate();\n };\n\n // With reduced motion there's nothing to transition, and a zero-duration\n // transition doesn't fire transitionend, so settle straight away rather\n // than waiting on the timeout that would otherwise cover for it.\n if (prefersReducedMotion()) {\n track.style.transform = finalTransform;\n finish();\n return;\n }\n\n track.style.transition = `transform ${completionDuration}ms ease-out`;\n track.style.transform = finalTransform;\n\n let settled = false;\n const onTransitionDone = (): void => {\n if (settled) return;\n settled = true;\n track.removeEventListener('transitionend', onTransitionDone);\n finish();\n };\n\n track.addEventListener('transitionend', onTransitionDone);\n // Fallback in case transitionend doesn't fire\n setTimeout(onTransitionDone, completionDuration + 50);\n };\n\n /** Applies the drag offset to the track during touch gestures. */\n private applyDragTransform(): void {\n const track = this.host.slideTrack;\n if (!this.dragging || !track) return;\n track.style.transform = `translateX(calc(-100% + ${this.dragOffsetX}px))`;\n }\n\n private onWheel = (e: WheelEvent): void => {\n if (this.host.imageCount <= 1) return;\n\n // Ignore vertical-dominant scrolls\n if (Math.abs(e.deltaY) > Math.abs(e.deltaX)) return;\n if (e.deltaX === 0) return;\n\n e.preventDefault();\n\n // Block during animation and for a brief cooldown after to absorb inertia\n const inCooldown =\n performance.now() - this.wheelAnimationEndTime < WHEEL_COOLDOWN_MS;\n if (this.wheelAnimating || inCooldown) {\n this.wheelDeltaX = 0;\n return;\n }\n\n this.wheelDeltaX += e.deltaX;\n if (Math.abs(this.wheelDeltaX) < WHEEL_THRESHOLD) return;\n\n const forward = this.wheelDeltaX > 0;\n this.wheelDeltaX = 0;\n this.wheelAnimating = true;\n if (forward) this.host.showNext();\n else this.host.showPrevious();\n };\n\n private onKeydown = (e: KeyboardEvent): void => {\n if (this.host.imageCount <= 1) return;\n const target = e.target as HTMLElement;\n if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA') return;\n if (target.isContentEditable) return;\n if (e.key === 'ArrowLeft') this.host.showPrevious();\n else if (e.key === 'ArrowRight') this.host.showNext();\n };\n}\n"]}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* One image the viewer can show.
|
|
3
|
-
*
|
|
4
|
-
* Deliberately plain data. The viewer doesn't know where the images come from
|
|
5
|
-
* or how their URLs were built, so a host can feed it archive.org derivatives,
|
|
6
|
-
* a local directory listing, or anything else.
|
|
7
|
-
*/
|
|
8
|
-
export type ImageViewerImage = {
|
|
9
|
-
/** Identifies the image within the set. Used as the key in change events. */
|
|
10
|
-
name: string;
|
|
11
|
-
/** Where to load the image from, and where the link points. */
|
|
12
|
-
url: string;
|
|
13
|
-
/** Alt text. Falls back to `name` when absent. */
|
|
14
|
-
title?: string;
|
|
15
|
-
};
|
|
16
|
-
/** Which way the viewer is moving through the set. */
|
|
17
|
-
export type SlideDirection = 'next' | 'prev';
|
|
18
|
-
/** Which edge the viewer just wrapped around. */
|
|
19
|
-
export type WrapEdge = 'start' | 'end';
|
|
20
|
-
//# sourceMappingURL=models.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../../../src/elements/ia-image-viewer/models.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;IAEb,+DAA+D;IAC/D,GAAG,EAAE,MAAM,CAAC;IAEZ,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,sDAAsD;AACtD,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,CAAC;AAE7C,iDAAiD;AACjD,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,KAAK,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../../../src/elements/ia-image-viewer/models.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * One image the viewer can show.\n *\n * Deliberately plain data. The viewer doesn't know where the images come from\n * or how their URLs were built, so a host can feed it archive.org derivatives,\n * a local directory listing, or anything else.\n */\nexport type ImageViewerImage = {\n /** Identifies the image within the set. Used as the key in change events. */\n name: string;\n\n /** Where to load the image from, and where the link points. */\n url: string;\n\n /** Alt text. Falls back to `name` when absent. */\n title?: string;\n};\n\n/** Which way the viewer is moving through the set. */\nexport type SlideDirection = 'next' | 'prev';\n\n/** Which edge the viewer just wrapped around. */\nexport type WrapEdge = 'start' | 'end';\n"]}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Whether the user has asked the system for reduced motion.
|
|
3
|
-
*
|
|
4
|
-
* Read at the moment an animation would start rather than cached, so changing
|
|
5
|
-
* the system setting takes effect without a reload. CSS handles the purely
|
|
6
|
-
* decorative animations on its own; this is for the places where JavaScript
|
|
7
|
-
* schedules or waits on one.
|
|
8
|
-
*/
|
|
9
|
-
export declare function prefersReducedMotion(): boolean;
|
|
10
|
-
//# sourceMappingURL=prefers-reduced-motion.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prefers-reduced-motion.d.ts","sourceRoot":"","sources":["../../../src/util/prefers-reduced-motion.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAI9C"}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Whether the user has asked the system for reduced motion.
|
|
3
|
-
*
|
|
4
|
-
* Read at the moment an animation would start rather than cached, so changing
|
|
5
|
-
* the system setting takes effect without a reload. CSS handles the purely
|
|
6
|
-
* decorative animations on its own; this is for the places where JavaScript
|
|
7
|
-
* schedules or waits on one.
|
|
8
|
-
*/
|
|
9
|
-
export function prefersReducedMotion() {
|
|
10
|
-
return (window.matchMedia?.('(prefers-reduced-motion: reduce)').matches ?? false);
|
|
11
|
-
}
|
|
12
|
-
//# sourceMappingURL=prefers-reduced-motion.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prefers-reduced-motion.js","sourceRoot":"","sources":["../../../src/util/prefers-reduced-motion.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB;IAClC,OAAO,CACL,MAAM,CAAC,UAAU,EAAE,CAAC,kCAAkC,CAAC,CAAC,OAAO,IAAI,KAAK,CACzE,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Whether the user has asked the system for reduced motion.\n *\n * Read at the moment an animation would start rather than cached, so changing\n * the system setting takes effect without a reload. CSS handles the purely\n * decorative animations on its own; this is for the places where JavaScript\n * schedules or waits on one.\n */\nexport function prefersReducedMotion(): boolean {\n return (\n window.matchMedia?.('(prefers-reduced-motion: reduce)').matches ?? false\n );\n}\n"]}
|