@getflip/swirl-components 0.8.3 → 0.8.5
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/cjs/flip-file-viewer_7.cjs.entry.js +155 -1
- package/dist/cjs/flip-lightbox.cjs.entry.js +21 -2
- package/dist/cjs/flip-modal.cjs.entry.js +1 -1
- package/dist/cjs/flip-tree-navigation-item.cjs.entry.js +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/swirl-components.cjs.js +1 -1
- package/dist/collection/components/flip-file-viewer/viewers/flip-file-viewer-image/flip-file-viewer-image.js +215 -3
- package/dist/collection/components/flip-lightbox/flip-lightbox.js +21 -2
- package/dist/collection/components/flip-modal/flip-modal.css +2 -2
- package/dist/collection/components/flip-tree-navigation-item/flip-tree-navigation-item.css +8 -2
- package/dist/components/flip-file-viewer-image2.js +159 -2
- package/dist/components/flip-lightbox.js +21 -2
- package/dist/components/flip-modal.js +1 -1
- package/dist/components/flip-tree-navigation-item.js +1 -1
- package/dist/esm/flip-file-viewer_7.entry.js +155 -1
- package/dist/esm/flip-lightbox.entry.js +21 -2
- package/dist/esm/flip-modal.entry.js +1 -1
- package/dist/esm/flip-tree-navigation-item.entry.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/swirl-components.js +1 -1
- package/dist/swirl-components/{p-08f3a8ab.entry.js → p-3a421e82.entry.js} +1 -1
- package/dist/swirl-components/{p-de892e4e.entry.js → p-5ba8364a.entry.js} +1 -1
- package/dist/swirl-components/p-9483fed0.entry.js +1 -0
- package/dist/swirl-components/p-9ce51761.entry.js +1 -0
- package/dist/swirl-components/swirl-components.esm.js +1 -1
- package/dist/types/components/flip-file-viewer/viewers/flip-file-viewer-image/flip-file-viewer-image.d.ts +40 -0
- package/dist/types/components/flip-lightbox/flip-lightbox.d.ts +1 -0
- package/dist/types/components.d.ts +12 -0
- package/package.json +1 -1
- package/vscode-data.json +4 -0
- package/dist/swirl-components/p-38cf01d0.entry.js +0 -1
- package/dist/swirl-components/p-5bc6cc3e.entry.js +0 -1
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import { Component, Element, Event, h, Host, Prop, State, Watch, } from "@stencil/core";
|
|
1
|
+
import { Component, Element, Event, h, Host, Method, Prop, State, Watch, } from "@stencil/core";
|
|
2
2
|
export class FlipFileViewerImage {
|
|
3
3
|
constructor() {
|
|
4
4
|
this.description = "";
|
|
5
5
|
this.errorMessage = "File could not be loaded.";
|
|
6
|
+
this.maxZoom = 3;
|
|
6
7
|
this.loading = true;
|
|
8
|
+
this.panX = 0;
|
|
9
|
+
this.panY = 0;
|
|
10
|
+
this.zoom = 1;
|
|
7
11
|
this.onError = () => {
|
|
8
12
|
this.error = true;
|
|
9
13
|
this.loading = false;
|
|
@@ -12,6 +16,142 @@ export class FlipFileViewerImage {
|
|
|
12
16
|
this.error = false;
|
|
13
17
|
this.loading = false;
|
|
14
18
|
};
|
|
19
|
+
this.onDblClick = (event) => {
|
|
20
|
+
this.clickToZoom(event);
|
|
21
|
+
};
|
|
22
|
+
this.onWheel = (event) => {
|
|
23
|
+
event.preventDefault();
|
|
24
|
+
const zoom = Math.min(Math.max(1, this.zoom + (-1 * event.deltaY) / 100), this.maxZoom);
|
|
25
|
+
if (zoom === this.zoom) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const centerX = event.offsetX;
|
|
29
|
+
const centerY = event.offsetY;
|
|
30
|
+
this.updateTransformOrigin(centerX, centerY);
|
|
31
|
+
this.updateZoomAndPan(zoom, 0, 0);
|
|
32
|
+
};
|
|
33
|
+
this.onPointerDown = (event) => {
|
|
34
|
+
this.startPan(event);
|
|
35
|
+
};
|
|
36
|
+
this.onPointerMove = (event) => {
|
|
37
|
+
this.pan(event);
|
|
38
|
+
};
|
|
39
|
+
this.onPointerUp = () => {
|
|
40
|
+
this.endPan();
|
|
41
|
+
};
|
|
42
|
+
this.onTouchStart = (event) => {
|
|
43
|
+
event.preventDefault();
|
|
44
|
+
if (event.touches.length === 2) {
|
|
45
|
+
this.startPinchToZoom(event);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
this.onTouchMove = (event) => {
|
|
49
|
+
event.preventDefault();
|
|
50
|
+
if (this.pinching) {
|
|
51
|
+
this.pinchToZoom(event);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
this.onTouchEnd = (event) => {
|
|
55
|
+
event.preventDefault();
|
|
56
|
+
if (this.pinching) {
|
|
57
|
+
this.endPinchToZoom();
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
this.startPinchToZoom = (event) => {
|
|
61
|
+
if (!Boolean(this.imageEl)) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
this.pinchDistance = this.getPinchDistance(event);
|
|
65
|
+
this.pinching = true;
|
|
66
|
+
};
|
|
67
|
+
this.pinchToZoom = (event) => {
|
|
68
|
+
const distance = this.getPinchDistance(event) - this.pinchDistance;
|
|
69
|
+
const zoom = Math.min(Math.max(1, this.zoom + distance / 100), this.maxZoom);
|
|
70
|
+
if (this.zoom === zoom) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
this.pinchDistance = this.getPinchDistance(event);
|
|
74
|
+
this.updateZoomAndPan(zoom);
|
|
75
|
+
};
|
|
76
|
+
this.endPinchToZoom = () => {
|
|
77
|
+
this.pinching = false;
|
|
78
|
+
if (Math.abs(this.zoom - 1) < 0.2) {
|
|
79
|
+
this.zoom = 1;
|
|
80
|
+
this.imageEl.style.transform = "";
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
this.getPinchDistance = (event) => {
|
|
84
|
+
return Math.hypot(event.touches[0].pageX - event.touches[1].pageX, event.touches[0].pageY - event.touches[1].pageY);
|
|
85
|
+
};
|
|
86
|
+
this.clickToZoom = (event) => {
|
|
87
|
+
const supportsMultiTouch = navigator.maxTouchPoints > 1;
|
|
88
|
+
if (supportsMultiTouch) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (this.zoom === 1) {
|
|
92
|
+
const centerX = event.pageX - this.el.getBoundingClientRect().x;
|
|
93
|
+
const centerY = event.pageY - this.el.getBoundingClientRect().y;
|
|
94
|
+
this.updateTransformOrigin(centerX, centerY);
|
|
95
|
+
this.updateZoomAndPan(2);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
this.updateZoomAndPan(1);
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
this.updateZoomAndPan = (zoom, panX, panY) => {
|
|
102
|
+
const newZoom = zoom === undefined ? this.zoom : zoom;
|
|
103
|
+
const zoomDiff = newZoom - this.zoom;
|
|
104
|
+
const newPanX = panX === undefined ? this.panX + this.panX * zoomDiff : panX;
|
|
105
|
+
const newPanY = panX === undefined ? this.panY + this.panY * zoomDiff : panY;
|
|
106
|
+
const previousPanX = this.panX;
|
|
107
|
+
const previousPanY = this.panY;
|
|
108
|
+
this.zoom = newZoom;
|
|
109
|
+
this.panX = newPanX;
|
|
110
|
+
this.panY = newPanY;
|
|
111
|
+
const parentRect = (this.el.parentElement || this.el).getBoundingClientRect();
|
|
112
|
+
const imageRect = this.imageEl.getBoundingClientRect();
|
|
113
|
+
const outOfBoundsX = (imageRect.right < parentRect.right && newPanX < previousPanX) ||
|
|
114
|
+
(imageRect.left > parentRect.left && newPanX > previousPanX);
|
|
115
|
+
const outOfBoundsY = (imageRect.bottom < parentRect.bottom && newPanY < previousPanY) ||
|
|
116
|
+
(imageRect.top > parentRect.top && newPanY > previousPanY);
|
|
117
|
+
if (outOfBoundsX) {
|
|
118
|
+
this.panX = previousPanX;
|
|
119
|
+
}
|
|
120
|
+
if (outOfBoundsY) {
|
|
121
|
+
this.panY = previousPanY;
|
|
122
|
+
}
|
|
123
|
+
if (this.zoom === 1) {
|
|
124
|
+
this.panX = 0;
|
|
125
|
+
this.panY = 0;
|
|
126
|
+
}
|
|
127
|
+
this.imageEl.style.transform = `matrix(${this.zoom}, 0, 0, ${this.zoom}, ${this.panX}, ${this.panY})`;
|
|
128
|
+
};
|
|
129
|
+
this.updateTransformOrigin = (x, y) => {
|
|
130
|
+
this.transformOriginX = x;
|
|
131
|
+
this.transformOriginY = y;
|
|
132
|
+
this.imageEl.style.transformOrigin = `${this.transformOriginX}px ${this.transformOriginY}px`;
|
|
133
|
+
};
|
|
134
|
+
this.startPan = (event) => {
|
|
135
|
+
this.panning = true;
|
|
136
|
+
this.previousScreenX = event.screenX;
|
|
137
|
+
this.previousScreenY = event.screenY;
|
|
138
|
+
};
|
|
139
|
+
this.pan = (event) => {
|
|
140
|
+
const previousScreenX = this.previousScreenX || 0;
|
|
141
|
+
const previousScreenY = this.previousScreenY || 0;
|
|
142
|
+
this.previousScreenX = event.screenX;
|
|
143
|
+
this.previousScreenY = event.screenY;
|
|
144
|
+
if (!this.panning || this.pinching) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
event.preventDefault();
|
|
148
|
+
const panX = this.panX + event.screenX - previousScreenX;
|
|
149
|
+
const panY = this.panY + event.screenY - previousScreenY;
|
|
150
|
+
this.updateZoomAndPan(this.zoom, panX, panY);
|
|
151
|
+
};
|
|
152
|
+
this.endPan = () => {
|
|
153
|
+
this.panning = false;
|
|
154
|
+
};
|
|
15
155
|
}
|
|
16
156
|
componentDidLoad() {
|
|
17
157
|
this.activate.emit(this.el);
|
|
@@ -20,10 +160,24 @@ export class FlipFileViewerImage {
|
|
|
20
160
|
this.error = false;
|
|
21
161
|
this.loading = true;
|
|
22
162
|
}
|
|
163
|
+
/**
|
|
164
|
+
* Get the current zoom.
|
|
165
|
+
* @returns
|
|
166
|
+
*/
|
|
167
|
+
async getZoom() {
|
|
168
|
+
return this.zoom;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Resets the zoom.
|
|
172
|
+
* @returns
|
|
173
|
+
*/
|
|
174
|
+
async resetZoom() {
|
|
175
|
+
return this.updateZoomAndPan(1);
|
|
176
|
+
}
|
|
23
177
|
render() {
|
|
24
|
-
return (h(Host, { class: "file-viewer-image" },
|
|
178
|
+
return (h(Host, { class: "file-viewer-image", onDblClick: this.onDblClick, onWheel: this.onWheel, onPointerDown: this.onPointerDown, onPointerMove: this.onPointerMove, onPointerUp: this.onPointerUp, onTouchStart: this.onTouchStart, onTouchMove: this.onTouchMove, onTouchEnd: this.onTouchEnd },
|
|
25
179
|
this.error && (h("flip-inline-error", { class: "file-viewer-image__error", message: this.errorMessage })),
|
|
26
|
-
h("img", { alt: this.description, class: "file-viewer-image__image", onError: this.onError, onLoad: this.onLoad, src: this.file }),
|
|
180
|
+
h("img", { alt: this.description, class: "file-viewer-image__image", onError: this.onError, onLoad: this.onLoad, ref: (el) => (this.imageEl = el), src: this.file }),
|
|
27
181
|
this.loading && (h("div", { class: "file-viewer-image__spinner" },
|
|
28
182
|
h("flip-spinner", null)))));
|
|
29
183
|
}
|
|
@@ -88,6 +242,24 @@ export class FlipFileViewerImage {
|
|
|
88
242
|
},
|
|
89
243
|
"attribute": "file",
|
|
90
244
|
"reflect": false
|
|
245
|
+
},
|
|
246
|
+
"maxZoom": {
|
|
247
|
+
"type": "number",
|
|
248
|
+
"mutable": false,
|
|
249
|
+
"complexType": {
|
|
250
|
+
"original": "number",
|
|
251
|
+
"resolved": "number",
|
|
252
|
+
"references": {}
|
|
253
|
+
},
|
|
254
|
+
"required": false,
|
|
255
|
+
"optional": true,
|
|
256
|
+
"docs": {
|
|
257
|
+
"tags": [],
|
|
258
|
+
"text": ""
|
|
259
|
+
},
|
|
260
|
+
"attribute": "max-zoom",
|
|
261
|
+
"reflect": false,
|
|
262
|
+
"defaultValue": "3"
|
|
91
263
|
}
|
|
92
264
|
}; }
|
|
93
265
|
static get states() { return {
|
|
@@ -114,6 +286,46 @@ export class FlipFileViewerImage {
|
|
|
114
286
|
}
|
|
115
287
|
}
|
|
116
288
|
}]; }
|
|
289
|
+
static get methods() { return {
|
|
290
|
+
"getZoom": {
|
|
291
|
+
"complexType": {
|
|
292
|
+
"signature": "() => Promise<number>",
|
|
293
|
+
"parameters": [],
|
|
294
|
+
"references": {
|
|
295
|
+
"Promise": {
|
|
296
|
+
"location": "global"
|
|
297
|
+
}
|
|
298
|
+
},
|
|
299
|
+
"return": "Promise<number>"
|
|
300
|
+
},
|
|
301
|
+
"docs": {
|
|
302
|
+
"text": "Get the current zoom.",
|
|
303
|
+
"tags": [{
|
|
304
|
+
"name": "returns",
|
|
305
|
+
"text": undefined
|
|
306
|
+
}]
|
|
307
|
+
}
|
|
308
|
+
},
|
|
309
|
+
"resetZoom": {
|
|
310
|
+
"complexType": {
|
|
311
|
+
"signature": "() => Promise<void>",
|
|
312
|
+
"parameters": [],
|
|
313
|
+
"references": {
|
|
314
|
+
"Promise": {
|
|
315
|
+
"location": "global"
|
|
316
|
+
}
|
|
317
|
+
},
|
|
318
|
+
"return": "Promise<void>"
|
|
319
|
+
},
|
|
320
|
+
"docs": {
|
|
321
|
+
"text": "Resets the zoom.",
|
|
322
|
+
"tags": [{
|
|
323
|
+
"name": "returns",
|
|
324
|
+
"text": undefined
|
|
325
|
+
}]
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}; }
|
|
117
329
|
static get elementRef() { return "el"; }
|
|
118
330
|
static get watchers() { return [{
|
|
119
331
|
"propName": "file",
|
|
@@ -43,7 +43,6 @@ export class FlipLightbox {
|
|
|
43
43
|
this.updateMediaPlayers();
|
|
44
44
|
};
|
|
45
45
|
this.onPointerDown = (event) => {
|
|
46
|
-
event.preventDefault();
|
|
47
46
|
this.dragging = true;
|
|
48
47
|
this.dragStartPosition =
|
|
49
48
|
event instanceof MouseEvent ? event.clientX : event.touches[0].clientX;
|
|
@@ -51,7 +50,16 @@ export class FlipLightbox {
|
|
|
51
50
|
slide.style.transition = "none";
|
|
52
51
|
});
|
|
53
52
|
};
|
|
54
|
-
this.onPointerMove = (event) => {
|
|
53
|
+
this.onPointerMove = async (event) => {
|
|
54
|
+
var _a, _b;
|
|
55
|
+
const isMultiTouch = !(event instanceof MouseEvent) && event.touches.length > 1;
|
|
56
|
+
const imageViewer = (_b = (_a = this.slides[this.activeSlideIndex]) === null || _a === void 0 ? void 0 : _a.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector("flip-file-viewer-image");
|
|
57
|
+
const showsZoomedImage = Boolean(imageViewer)
|
|
58
|
+
? (await imageViewer.getZoom()) > 1
|
|
59
|
+
: false;
|
|
60
|
+
if (isMultiTouch || showsZoomedImage) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
55
63
|
if (this.dragging) {
|
|
56
64
|
event.preventDefault();
|
|
57
65
|
const deltaX = event instanceof MouseEvent
|
|
@@ -116,6 +124,7 @@ export class FlipLightbox {
|
|
|
116
124
|
this.unlockBodyScroll();
|
|
117
125
|
setTimeout(() => {
|
|
118
126
|
this.modal.hide();
|
|
127
|
+
this.resetImageZoom();
|
|
119
128
|
this.closing = false;
|
|
120
129
|
}, 150);
|
|
121
130
|
}
|
|
@@ -153,6 +162,7 @@ export class FlipLightbox {
|
|
|
153
162
|
}, 300);
|
|
154
163
|
this.stopAllMediaPlayers();
|
|
155
164
|
this.updateMediaPlayers();
|
|
165
|
+
this.resetImageZoom();
|
|
156
166
|
}
|
|
157
167
|
setSlideAttributes() {
|
|
158
168
|
this.slides.forEach((slide) => {
|
|
@@ -180,6 +190,15 @@ export class FlipLightbox {
|
|
|
180
190
|
stopAllMediaPlayers() {
|
|
181
191
|
this.mediaPlayers.forEach((mediaPlayer) => mediaPlayer.pause());
|
|
182
192
|
}
|
|
193
|
+
resetImageZoom() {
|
|
194
|
+
this.slides.forEach((slide) => {
|
|
195
|
+
var _a;
|
|
196
|
+
const imageViewer = (_a = slide === null || slide === void 0 ? void 0 : slide.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector("flip-file-viewer-image");
|
|
197
|
+
if (Boolean(imageViewer)) {
|
|
198
|
+
imageViewer.resetZoom();
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
}
|
|
183
202
|
render() {
|
|
184
203
|
const showPagination = this.slides.length > 1;
|
|
185
204
|
const className = classnames("lightbox", {
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
|
|
78
78
|
@media (min-width: 768px) {
|
|
79
79
|
.modal--scrolled .modal__header {
|
|
80
|
-
border-bottom: var(--s-border-
|
|
80
|
+
border-bottom-color: var(--s-border-default);
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
|
|
@@ -145,7 +145,7 @@
|
|
|
145
145
|
padding-right: calc(var(--s-space-16) + 2.5rem + var(--s-space-8));
|
|
146
146
|
padding-bottom: var(--s-space-16);
|
|
147
147
|
padding-left: var(--s-space-24);
|
|
148
|
-
border-bottom:
|
|
148
|
+
border-bottom: var(--s-border-width-default) solid transparent
|
|
149
149
|
}
|
|
150
150
|
}
|
|
151
151
|
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
font-size: var(--s-font-size-sm);
|
|
13
13
|
line-height: var(--s-line-height-sm);
|
|
14
14
|
cursor: pointer;
|
|
15
|
-
gap: var(--s-space-8);
|
|
15
|
+
gap: calc(var(--s-space-8) - var(--s-space-2));
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
:host(:hover) {
|
|
@@ -24,10 +24,14 @@
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
:host(:focus) {
|
|
27
|
-
background-color: var(--s-surface-hovered);
|
|
28
27
|
outline: none;
|
|
29
28
|
}
|
|
30
29
|
|
|
30
|
+
:host(:focus) .tree-navigation-item__label {
|
|
31
|
+
border-radius: var(--s-border-radius-xs);
|
|
32
|
+
box-shadow: 0 0 0 0.125rem var(--s-focus-default);
|
|
33
|
+
}
|
|
34
|
+
|
|
31
35
|
:host(.tree-navigation-item--active) {
|
|
32
36
|
background-color: var(--s-surface-raised-default);
|
|
33
37
|
box-shadow: inset 0.25rem 0 0 0 var(--s-surface-highlight-default);
|
|
@@ -58,4 +62,6 @@
|
|
|
58
62
|
min-width: 0;
|
|
59
63
|
white-space: nowrap;
|
|
60
64
|
text-overflow: ellipsis;
|
|
65
|
+
padding-right: var(--s-space-2);
|
|
66
|
+
padding-left: var(--s-space-2);
|
|
61
67
|
}
|
|
@@ -14,7 +14,11 @@ const FlipFileViewerImage = /*@__PURE__*/ proxyCustomElement(class extends HTMLE
|
|
|
14
14
|
this.activate = createEvent(this, "activate", 7);
|
|
15
15
|
this.description = "";
|
|
16
16
|
this.errorMessage = "File could not be loaded.";
|
|
17
|
+
this.maxZoom = 3;
|
|
17
18
|
this.loading = true;
|
|
19
|
+
this.panX = 0;
|
|
20
|
+
this.panY = 0;
|
|
21
|
+
this.zoom = 1;
|
|
18
22
|
this.onError = () => {
|
|
19
23
|
this.error = true;
|
|
20
24
|
this.loading = false;
|
|
@@ -23,6 +27,142 @@ const FlipFileViewerImage = /*@__PURE__*/ proxyCustomElement(class extends HTMLE
|
|
|
23
27
|
this.error = false;
|
|
24
28
|
this.loading = false;
|
|
25
29
|
};
|
|
30
|
+
this.onDblClick = (event) => {
|
|
31
|
+
this.clickToZoom(event);
|
|
32
|
+
};
|
|
33
|
+
this.onWheel = (event) => {
|
|
34
|
+
event.preventDefault();
|
|
35
|
+
const zoom = Math.min(Math.max(1, this.zoom + (-1 * event.deltaY) / 100), this.maxZoom);
|
|
36
|
+
if (zoom === this.zoom) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const centerX = event.offsetX;
|
|
40
|
+
const centerY = event.offsetY;
|
|
41
|
+
this.updateTransformOrigin(centerX, centerY);
|
|
42
|
+
this.updateZoomAndPan(zoom, 0, 0);
|
|
43
|
+
};
|
|
44
|
+
this.onPointerDown = (event) => {
|
|
45
|
+
this.startPan(event);
|
|
46
|
+
};
|
|
47
|
+
this.onPointerMove = (event) => {
|
|
48
|
+
this.pan(event);
|
|
49
|
+
};
|
|
50
|
+
this.onPointerUp = () => {
|
|
51
|
+
this.endPan();
|
|
52
|
+
};
|
|
53
|
+
this.onTouchStart = (event) => {
|
|
54
|
+
event.preventDefault();
|
|
55
|
+
if (event.touches.length === 2) {
|
|
56
|
+
this.startPinchToZoom(event);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
this.onTouchMove = (event) => {
|
|
60
|
+
event.preventDefault();
|
|
61
|
+
if (this.pinching) {
|
|
62
|
+
this.pinchToZoom(event);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
this.onTouchEnd = (event) => {
|
|
66
|
+
event.preventDefault();
|
|
67
|
+
if (this.pinching) {
|
|
68
|
+
this.endPinchToZoom();
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
this.startPinchToZoom = (event) => {
|
|
72
|
+
if (!Boolean(this.imageEl)) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
this.pinchDistance = this.getPinchDistance(event);
|
|
76
|
+
this.pinching = true;
|
|
77
|
+
};
|
|
78
|
+
this.pinchToZoom = (event) => {
|
|
79
|
+
const distance = this.getPinchDistance(event) - this.pinchDistance;
|
|
80
|
+
const zoom = Math.min(Math.max(1, this.zoom + distance / 100), this.maxZoom);
|
|
81
|
+
if (this.zoom === zoom) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
this.pinchDistance = this.getPinchDistance(event);
|
|
85
|
+
this.updateZoomAndPan(zoom);
|
|
86
|
+
};
|
|
87
|
+
this.endPinchToZoom = () => {
|
|
88
|
+
this.pinching = false;
|
|
89
|
+
if (Math.abs(this.zoom - 1) < 0.2) {
|
|
90
|
+
this.zoom = 1;
|
|
91
|
+
this.imageEl.style.transform = "";
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
this.getPinchDistance = (event) => {
|
|
95
|
+
return Math.hypot(event.touches[0].pageX - event.touches[1].pageX, event.touches[0].pageY - event.touches[1].pageY);
|
|
96
|
+
};
|
|
97
|
+
this.clickToZoom = (event) => {
|
|
98
|
+
const supportsMultiTouch = navigator.maxTouchPoints > 1;
|
|
99
|
+
if (supportsMultiTouch) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (this.zoom === 1) {
|
|
103
|
+
const centerX = event.pageX - this.el.getBoundingClientRect().x;
|
|
104
|
+
const centerY = event.pageY - this.el.getBoundingClientRect().y;
|
|
105
|
+
this.updateTransformOrigin(centerX, centerY);
|
|
106
|
+
this.updateZoomAndPan(2);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
this.updateZoomAndPan(1);
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
this.updateZoomAndPan = (zoom, panX, panY) => {
|
|
113
|
+
const newZoom = zoom === undefined ? this.zoom : zoom;
|
|
114
|
+
const zoomDiff = newZoom - this.zoom;
|
|
115
|
+
const newPanX = panX === undefined ? this.panX + this.panX * zoomDiff : panX;
|
|
116
|
+
const newPanY = panX === undefined ? this.panY + this.panY * zoomDiff : panY;
|
|
117
|
+
const previousPanX = this.panX;
|
|
118
|
+
const previousPanY = this.panY;
|
|
119
|
+
this.zoom = newZoom;
|
|
120
|
+
this.panX = newPanX;
|
|
121
|
+
this.panY = newPanY;
|
|
122
|
+
const parentRect = (this.el.parentElement || this.el).getBoundingClientRect();
|
|
123
|
+
const imageRect = this.imageEl.getBoundingClientRect();
|
|
124
|
+
const outOfBoundsX = (imageRect.right < parentRect.right && newPanX < previousPanX) ||
|
|
125
|
+
(imageRect.left > parentRect.left && newPanX > previousPanX);
|
|
126
|
+
const outOfBoundsY = (imageRect.bottom < parentRect.bottom && newPanY < previousPanY) ||
|
|
127
|
+
(imageRect.top > parentRect.top && newPanY > previousPanY);
|
|
128
|
+
if (outOfBoundsX) {
|
|
129
|
+
this.panX = previousPanX;
|
|
130
|
+
}
|
|
131
|
+
if (outOfBoundsY) {
|
|
132
|
+
this.panY = previousPanY;
|
|
133
|
+
}
|
|
134
|
+
if (this.zoom === 1) {
|
|
135
|
+
this.panX = 0;
|
|
136
|
+
this.panY = 0;
|
|
137
|
+
}
|
|
138
|
+
this.imageEl.style.transform = `matrix(${this.zoom}, 0, 0, ${this.zoom}, ${this.panX}, ${this.panY})`;
|
|
139
|
+
};
|
|
140
|
+
this.updateTransformOrigin = (x, y) => {
|
|
141
|
+
this.transformOriginX = x;
|
|
142
|
+
this.transformOriginY = y;
|
|
143
|
+
this.imageEl.style.transformOrigin = `${this.transformOriginX}px ${this.transformOriginY}px`;
|
|
144
|
+
};
|
|
145
|
+
this.startPan = (event) => {
|
|
146
|
+
this.panning = true;
|
|
147
|
+
this.previousScreenX = event.screenX;
|
|
148
|
+
this.previousScreenY = event.screenY;
|
|
149
|
+
};
|
|
150
|
+
this.pan = (event) => {
|
|
151
|
+
const previousScreenX = this.previousScreenX || 0;
|
|
152
|
+
const previousScreenY = this.previousScreenY || 0;
|
|
153
|
+
this.previousScreenX = event.screenX;
|
|
154
|
+
this.previousScreenY = event.screenY;
|
|
155
|
+
if (!this.panning || this.pinching) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
event.preventDefault();
|
|
159
|
+
const panX = this.panX + event.screenX - previousScreenX;
|
|
160
|
+
const panY = this.panY + event.screenY - previousScreenY;
|
|
161
|
+
this.updateZoomAndPan(this.zoom, panX, panY);
|
|
162
|
+
};
|
|
163
|
+
this.endPan = () => {
|
|
164
|
+
this.panning = false;
|
|
165
|
+
};
|
|
26
166
|
}
|
|
27
167
|
componentDidLoad() {
|
|
28
168
|
this.activate.emit(this.el);
|
|
@@ -31,8 +171,22 @@ const FlipFileViewerImage = /*@__PURE__*/ proxyCustomElement(class extends HTMLE
|
|
|
31
171
|
this.error = false;
|
|
32
172
|
this.loading = true;
|
|
33
173
|
}
|
|
174
|
+
/**
|
|
175
|
+
* Get the current zoom.
|
|
176
|
+
* @returns
|
|
177
|
+
*/
|
|
178
|
+
async getZoom() {
|
|
179
|
+
return this.zoom;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Resets the zoom.
|
|
183
|
+
* @returns
|
|
184
|
+
*/
|
|
185
|
+
async resetZoom() {
|
|
186
|
+
return this.updateZoomAndPan(1);
|
|
187
|
+
}
|
|
34
188
|
render() {
|
|
35
|
-
return (h(Host, { class: "file-viewer-image" }, this.error && (h("flip-inline-error", { class: "file-viewer-image__error", message: this.errorMessage })), h("img", { alt: this.description, class: "file-viewer-image__image", onError: this.onError, onLoad: this.onLoad, src: this.file }), this.loading && (h("div", { class: "file-viewer-image__spinner" }, h("flip-spinner", null)))));
|
|
189
|
+
return (h(Host, { class: "file-viewer-image", onDblClick: this.onDblClick, onWheel: this.onWheel, onPointerDown: this.onPointerDown, onPointerMove: this.onPointerMove, onPointerUp: this.onPointerUp, onTouchStart: this.onTouchStart, onTouchMove: this.onTouchMove, onTouchEnd: this.onTouchEnd }, this.error && (h("flip-inline-error", { class: "file-viewer-image__error", message: this.errorMessage })), h("img", { alt: this.description, class: "file-viewer-image__image", onError: this.onError, onLoad: this.onLoad, ref: (el) => (this.imageEl = el), src: this.file }), this.loading && (h("div", { class: "file-viewer-image__spinner" }, h("flip-spinner", null)))));
|
|
36
190
|
}
|
|
37
191
|
get el() { return this; }
|
|
38
192
|
static get watchers() { return {
|
|
@@ -43,8 +197,11 @@ const FlipFileViewerImage = /*@__PURE__*/ proxyCustomElement(class extends HTMLE
|
|
|
43
197
|
"description": [1],
|
|
44
198
|
"errorMessage": [1, "error-message"],
|
|
45
199
|
"file": [1],
|
|
200
|
+
"maxZoom": [2, "max-zoom"],
|
|
46
201
|
"error": [32],
|
|
47
|
-
"loading": [32]
|
|
202
|
+
"loading": [32],
|
|
203
|
+
"getZoom": [64],
|
|
204
|
+
"resetZoom": [64]
|
|
48
205
|
}]);
|
|
49
206
|
function defineCustomElement() {
|
|
50
207
|
if (typeof customElements === "undefined") {
|
|
@@ -53,7 +53,6 @@ const FlipLightbox$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElemen
|
|
|
53
53
|
this.updateMediaPlayers();
|
|
54
54
|
};
|
|
55
55
|
this.onPointerDown = (event) => {
|
|
56
|
-
event.preventDefault();
|
|
57
56
|
this.dragging = true;
|
|
58
57
|
this.dragStartPosition =
|
|
59
58
|
event instanceof MouseEvent ? event.clientX : event.touches[0].clientX;
|
|
@@ -61,7 +60,16 @@ const FlipLightbox$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElemen
|
|
|
61
60
|
slide.style.transition = "none";
|
|
62
61
|
});
|
|
63
62
|
};
|
|
64
|
-
this.onPointerMove = (event) => {
|
|
63
|
+
this.onPointerMove = async (event) => {
|
|
64
|
+
var _a, _b;
|
|
65
|
+
const isMultiTouch = !(event instanceof MouseEvent) && event.touches.length > 1;
|
|
66
|
+
const imageViewer = (_b = (_a = this.slides[this.activeSlideIndex]) === null || _a === void 0 ? void 0 : _a.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector("flip-file-viewer-image");
|
|
67
|
+
const showsZoomedImage = Boolean(imageViewer)
|
|
68
|
+
? (await imageViewer.getZoom()) > 1
|
|
69
|
+
: false;
|
|
70
|
+
if (isMultiTouch || showsZoomedImage) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
65
73
|
if (this.dragging) {
|
|
66
74
|
event.preventDefault();
|
|
67
75
|
const deltaX = event instanceof MouseEvent
|
|
@@ -126,6 +134,7 @@ const FlipLightbox$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElemen
|
|
|
126
134
|
this.unlockBodyScroll();
|
|
127
135
|
setTimeout(() => {
|
|
128
136
|
this.modal.hide();
|
|
137
|
+
this.resetImageZoom();
|
|
129
138
|
this.closing = false;
|
|
130
139
|
}, 150);
|
|
131
140
|
}
|
|
@@ -163,6 +172,7 @@ const FlipLightbox$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElemen
|
|
|
163
172
|
}, 300);
|
|
164
173
|
this.stopAllMediaPlayers();
|
|
165
174
|
this.updateMediaPlayers();
|
|
175
|
+
this.resetImageZoom();
|
|
166
176
|
}
|
|
167
177
|
setSlideAttributes() {
|
|
168
178
|
this.slides.forEach((slide) => {
|
|
@@ -190,6 +200,15 @@ const FlipLightbox$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElemen
|
|
|
190
200
|
stopAllMediaPlayers() {
|
|
191
201
|
this.mediaPlayers.forEach((mediaPlayer) => mediaPlayer.pause());
|
|
192
202
|
}
|
|
203
|
+
resetImageZoom() {
|
|
204
|
+
this.slides.forEach((slide) => {
|
|
205
|
+
var _a;
|
|
206
|
+
const imageViewer = (_a = slide === null || slide === void 0 ? void 0 : slide.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector("flip-file-viewer-image");
|
|
207
|
+
if (Boolean(imageViewer)) {
|
|
208
|
+
imageViewer.resetZoom();
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
}
|
|
193
212
|
render() {
|
|
194
213
|
const showPagination = this.slides.length > 1;
|
|
195
214
|
const className = classnames("lightbox", {
|
|
@@ -7,7 +7,7 @@ import { d as defineCustomElement$4 } from './flip-button-group2.js';
|
|
|
7
7
|
import { d as defineCustomElement$3 } from './flip-heading2.js';
|
|
8
8
|
import { d as defineCustomElement$2 } from './flip-stack2.js';
|
|
9
9
|
|
|
10
|
-
const flipModalCss = ":host{--flip-ghost-button-background-default:var(--s-surface-overlay-default);--flip-ghost-button-background-hovered:var(--s-surface-overlay-hovered);--flip-ghost-button-background-pressed:var(--s-surface-overlay-pressed);display:block}:host *{box-sizing:border-box}.modal{position:fixed;z-index:var(--s-z-40);display:flex;justify-content:center;align-items:center;inset:0}.modal[aria-hidden=\"true\"]{display:none}.modal:not(.modal--closing) .modal__backdrop{-webkit-animation:0.15s modal-backdrop-fade-in;animation:0.15s modal-backdrop-fade-in}@media (prefers-reduced-motion){.modal:not(.modal--closing) .modal__backdrop{-webkit-animation:none;animation:none}}.modal:not(.modal--closing) .modal__body{-webkit-animation:0.15s modal-scale-in;animation:0.15s modal-scale-in}@media (prefers-reduced-motion){.modal:not(.modal--closing) .modal__body{-webkit-animation:none;animation:none}}.modal--closing{-webkit-animation:0.15s modal-fade-out;animation:0.15s modal-fade-out;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}@media (prefers-reduced-motion){.modal--closing{-webkit-animation:none;animation:none}}@media (min-width: 768px){.modal--scrollable .modal__content{padding-bottom:0}}.modal--scrollable:not(.modal--scrolled-down) .modal__controls{border-top:var(--s-border-width-default) solid var(--s-border-default)}@media (min-width: 768px){.modal--scrolled .modal__header{border-bottom:var(--s-border-
|
|
10
|
+
const flipModalCss = ":host{--flip-ghost-button-background-default:var(--s-surface-overlay-default);--flip-ghost-button-background-hovered:var(--s-surface-overlay-hovered);--flip-ghost-button-background-pressed:var(--s-surface-overlay-pressed);display:block}:host *{box-sizing:border-box}.modal{position:fixed;z-index:var(--s-z-40);display:flex;justify-content:center;align-items:center;inset:0}.modal[aria-hidden=\"true\"]{display:none}.modal:not(.modal--closing) .modal__backdrop{-webkit-animation:0.15s modal-backdrop-fade-in;animation:0.15s modal-backdrop-fade-in}@media (prefers-reduced-motion){.modal:not(.modal--closing) .modal__backdrop{-webkit-animation:none;animation:none}}.modal:not(.modal--closing) .modal__body{-webkit-animation:0.15s modal-scale-in;animation:0.15s modal-scale-in}@media (prefers-reduced-motion){.modal:not(.modal--closing) .modal__body{-webkit-animation:none;animation:none}}.modal--closing{-webkit-animation:0.15s modal-fade-out;animation:0.15s modal-fade-out;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}@media (prefers-reduced-motion){.modal--closing{-webkit-animation:none;animation:none}}@media (min-width: 768px){.modal--scrollable .modal__content{padding-bottom:0}}.modal--scrollable:not(.modal--scrolled-down) .modal__controls{border-top:var(--s-border-width-default) solid var(--s-border-default)}@media (min-width: 768px){.modal--scrolled .modal__header{border-bottom-color:var(--s-border-default)}}.modal__backdrop{position:fixed;background-color:rgba(0, 0, 0, 0.2);inset:0}.modal__body{position:relative;z-index:var(--s-z-40);display:flex;width:100vw;height:100vh;background-color:var(--s-surface-overlay-default);flex-direction:column}@media (min-width: 768px){.modal__body{width:90vw;max-width:33.75rem;height:auto;max-height:90vh;border-radius:var(--s-border-radius-base);box-shadow:0.125rem 0.25rem 1rem rgba(0, 0, 0, 0.14)}}.modal__close-button{position:absolute;top:var(--s-space-8);left:var(--s-space-8)}@media (min-width: 768px){.modal__close-button{top:var(--s-space-16);right:var(--s-space-16);left:auto}}.modal__header{display:flex;height:3.5rem;padding-top:var(--s-space-8);padding-right:var(--s-space-16);padding-bottom:var(--s-space-8);padding-left:calc(var(--s-space-8) + 2.5rem + var(--s-space-8));flex-shrink:0;align-items:center;border-bottom:var(--s-border-width-default) solid var(--s-border-default);gap:var(--s-space-16)}@media (min-width: 768px){.modal__header{height:4.125rem;padding-top:var(--s-space-24);padding-right:calc(var(--s-space-16) + 2.5rem + var(--s-space-8));padding-bottom:var(--s-space-16);padding-left:var(--s-space-24);border-bottom:var(--s-border-width-default) solid transparent}}.modal__heading{overflow:hidden}.modal__heading .heading{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.modal__content{overflow-x:hidden;overflow-y:auto;padding-top:var(--s-space-24);padding-right:var(--s-space-16);padding-bottom:var(--s-space-24);padding-left:var(--s-space-16);flex-grow:1;line-height:var(--s-line-height-base)}.modal__content ::slotted(*){margin:0}@media (min-width: 768px){.modal__content{padding-top:0;padding-right:var(--s-space-24);padding-bottom:var(--s-space-16);padding-left:var(--s-space-24)}}.modal__controls{display:flex;padding-top:var(--s-space-16);padding-right:var(--s-space-24);padding-bottom:var(--s-space-16);padding-left:var(--s-space-24);flex-shrink:0;justify-content:flex-end}@-webkit-keyframes modal-scale-in{from{transform:scale(0)}to{transform:scale(1)}}@keyframes modal-scale-in{from{transform:scale(0)}to{transform:scale(1)}}@-webkit-keyframes modal-backdrop-fade-in{from{opacity:0}to{opacity:1}}@keyframes modal-backdrop-fade-in{from{opacity:0}to{opacity:1}}@-webkit-keyframes modal-fade-out{from{opacity:1}to{opacity:0}}@keyframes modal-fade-out{from{opacity:1}to{opacity:0}}";
|
|
11
11
|
|
|
12
12
|
const FlipModal$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
|
|
13
13
|
constructor() {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { proxyCustomElement, HTMLElement, h, Host } from '@stencil/core/internal/client';
|
|
2
2
|
import { c as classnames } from './index2.js';
|
|
3
3
|
|
|
4
|
-
const flipTreeNavigationItemCss = ":host{display:inline-flex;width:100%;height:2.5rem;padding-right:var(--s-space-16);padding-left:calc(var(--s-space-16) + 1.5rem + var(--s-space-8));flex-shrink:0;justify-content:flex-start;align-items:center;color:var(--s-text-default);background-color:var(--s-surface-default);font-size:var(--s-font-size-sm);line-height:var(--s-line-height-sm);cursor:pointer;gap:var(--s-space-8)}:host(:hover){background-color:var(--s-surface-hovered)}:host(:active){background-color:var(--s-surface-pressed)}:host(:focus){
|
|
4
|
+
const flipTreeNavigationItemCss = ":host{display:inline-flex;width:100%;height:2.5rem;padding-right:var(--s-space-16);padding-left:calc(var(--s-space-16) + 1.5rem + var(--s-space-8));flex-shrink:0;justify-content:flex-start;align-items:center;color:var(--s-text-default);background-color:var(--s-surface-default);font-size:var(--s-font-size-sm);line-height:var(--s-line-height-sm);cursor:pointer;gap:calc(var(--s-space-8) - var(--s-space-2))}:host(:hover){background-color:var(--s-surface-hovered)}:host(:active){background-color:var(--s-surface-pressed)}:host(:focus){outline:none}:host(:focus) .tree-navigation-item__label{border-radius:var(--s-border-radius-xs);box-shadow:0 0 0 0.125rem var(--s-focus-default)}:host(.tree-navigation-item--active){background-color:var(--s-surface-raised-default);box-shadow:inset 0.25rem 0 0 0 var(--s-surface-highlight-default)}:host(.tree-navigation-item--active:hover){background-color:var(--s-surface-raised-hovered)}:host(.tree-navigation-item--active:active){background-color:var(--s-surface-raised-pressed)}:host(.tree-navigation-item--has-icon){padding-left:var(--s-space-16)}:host *{box-sizing:border-box}.tree-navigation-item__icon{display:inline-flex}.tree-navigation-item__label{overflow:hidden;min-width:0;white-space:nowrap;text-overflow:ellipsis;padding-right:var(--s-space-2);padding-left:var(--s-space-2)}";
|
|
5
5
|
|
|
6
6
|
const FlipTreeNavigationItem$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
|
|
7
7
|
constructor() {
|