ng-images-preview 1.0.0 → 1.0.2
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/README.md
CHANGED
|
@@ -16,7 +16,7 @@ A lightweight, modern, and accessible Image Preview library for Angular 18+, bui
|
|
|
16
16
|
[中文版](./README.zh-CN.md) | English
|
|
17
17
|
|
|
18
18
|
## 🔗 Live Demo
|
|
19
|
-
Check out the component in action: **[https://lanxuexing.github.io/ng-images-preview/](https://lanxuexing.github.io/ng-images-preview/)**
|
|
19
|
+
Check out the component in action: **[https://lanxuexing.github.io/ng-images-preview/](https://lanxuexing.github.io/ng-images-preview/)**
|
|
20
20
|
|
|
21
21
|
</div>
|
|
22
22
|
|
|
@@ -45,6 +45,29 @@ npm install ng-images-preview
|
|
|
45
45
|
|
|
46
46
|
## 🚀 Quick Start
|
|
47
47
|
|
|
48
|
+
### ⚠️ Prerequisite: Enable Animations
|
|
49
|
+
|
|
50
|
+
This library relies on Angular animations. You must enable them in your application.
|
|
51
|
+
|
|
52
|
+
**Standalone (app.config.ts):**
|
|
53
|
+
```typescript
|
|
54
|
+
import { provideAnimations } from '@angular/platform-browser/animations';
|
|
55
|
+
|
|
56
|
+
export const appConfig: ApplicationConfig = {
|
|
57
|
+
providers: [provideAnimations()]
|
|
58
|
+
};
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**NgModule (app.module.ts):**
|
|
62
|
+
```typescript
|
|
63
|
+
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
|
64
|
+
|
|
65
|
+
@NgModule({
|
|
66
|
+
imports: [BrowserAnimationsModule]
|
|
67
|
+
})
|
|
68
|
+
export class AppModule { }
|
|
69
|
+
```
|
|
70
|
+
|
|
48
71
|
### 1. Import Directive
|
|
49
72
|
|
|
50
73
|
Register `ImagesPreviewDirective` in your standalone component or module.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { input, viewChild, signal, computed, effect, HostListener, ChangeDetectionStrategy, Component,
|
|
2
|
+
import { input, viewChild, signal, computed, inject, PLATFORM_ID, effect, HostListener, ChangeDetectionStrategy, Component, ApplicationRef, EnvironmentInjector, ElementRef, createComponent, Input, Directive } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/common';
|
|
4
|
-
import { CommonModule } from '@angular/common';
|
|
4
|
+
import { isPlatformBrowser, CommonModule } from '@angular/common';
|
|
5
5
|
import { trigger, transition, style, animate } from '@angular/animations';
|
|
6
6
|
|
|
7
7
|
class ImagesPreviewComponent {
|
|
@@ -24,6 +24,7 @@ class ImagesPreviewComponent {
|
|
|
24
24
|
}
|
|
25
25
|
return this.src();
|
|
26
26
|
}, ...(ngDevMode ? [{ debugName: "activeSrc" }] : []));
|
|
27
|
+
platformId = inject(PLATFORM_ID);
|
|
27
28
|
constructor() {
|
|
28
29
|
// defined in class body usually, but here to show logical grouping
|
|
29
30
|
effect(() => {
|
|
@@ -37,6 +38,23 @@ class ImagesPreviewComponent {
|
|
|
37
38
|
this.hasError.set(false);
|
|
38
39
|
this.reset(); // Reset zoom/rotate
|
|
39
40
|
}, { allowSignalWrites: true });
|
|
41
|
+
// Preload next/prev images
|
|
42
|
+
effect(() => {
|
|
43
|
+
const index = this.currentIndex();
|
|
44
|
+
const images = this.images();
|
|
45
|
+
if (isPlatformBrowser(this.platformId) && images && images.length > 0) {
|
|
46
|
+
// Next
|
|
47
|
+
if (index < images.length - 1) {
|
|
48
|
+
const img = new Image();
|
|
49
|
+
img.src = images[index + 1];
|
|
50
|
+
}
|
|
51
|
+
// Prev
|
|
52
|
+
if (index > 0) {
|
|
53
|
+
const img = new Image();
|
|
54
|
+
img.src = images[index - 1];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
});
|
|
40
58
|
}
|
|
41
59
|
scale = signal(1, ...(ngDevMode ? [{ debugName: "scale" }] : []));
|
|
42
60
|
translateX = signal(0, ...(ngDevMode ? [{ debugName: "translateX" }] : []));
|
|
@@ -111,6 +129,11 @@ class ImagesPreviewComponent {
|
|
|
111
129
|
this.applyMoveConstraints(nextX, nextY);
|
|
112
130
|
}
|
|
113
131
|
applyMoveConstraints(nextX, nextY) {
|
|
132
|
+
if (!isPlatformBrowser(this.platformId)) {
|
|
133
|
+
this.translateX.set(nextX);
|
|
134
|
+
this.translateY.set(nextY);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
114
137
|
const img = this.imgRef()?.nativeElement;
|
|
115
138
|
if (!img) {
|
|
116
139
|
this.translateX.set(nextX);
|
|
@@ -201,6 +224,8 @@ class ImagesPreviewComponent {
|
|
|
201
224
|
// The instruction says: "So `getConstraints` stays as is (calculates fresh)."
|
|
202
225
|
// So, this method should always calculate fresh.
|
|
203
226
|
// The `cachedConstraints` property is used *outside* this method.
|
|
227
|
+
if (!isPlatformBrowser(this.platformId))
|
|
228
|
+
return { maxX: 0, maxY: 0 };
|
|
204
229
|
const img = this.imgRef()?.nativeElement;
|
|
205
230
|
if (!img)
|
|
206
231
|
return { maxX: 0, maxY: 0 };
|
|
@@ -219,6 +244,8 @@ class ImagesPreviewComponent {
|
|
|
219
244
|
};
|
|
220
245
|
}
|
|
221
246
|
clampPosition() {
|
|
247
|
+
if (!isPlatformBrowser(this.platformId))
|
|
248
|
+
return;
|
|
222
249
|
const img = this.imgRef()?.nativeElement;
|
|
223
250
|
if (!img)
|
|
224
251
|
return;
|
|
@@ -604,11 +631,7 @@ class ImagesPreviewComponent {
|
|
|
604
631
|
|
|
605
632
|
<!-- Close Button -->
|
|
606
633
|
<button class="close-btn" (click)="close()" aria-label="Close preview">
|
|
607
|
-
<svg viewBox="0 0 24 24">
|
|
608
|
-
<path
|
|
609
|
-
d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"
|
|
610
|
-
/>
|
|
611
|
-
</svg>
|
|
634
|
+
<svg viewBox="0 0 24 24"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
|
|
612
635
|
</button>
|
|
613
636
|
|
|
614
637
|
<!-- Navigation -->
|
|
@@ -621,9 +644,7 @@ class ImagesPreviewComponent {
|
|
|
621
644
|
(mousedown)="$event.stopPropagation()"
|
|
622
645
|
aria-label="Previous image"
|
|
623
646
|
>
|
|
624
|
-
<svg viewBox="0 0 24 24">
|
|
625
|
-
<path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z" />
|
|
626
|
-
</svg>
|
|
647
|
+
<svg viewBox="0 0 24 24"><path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/></svg>
|
|
627
648
|
</button>
|
|
628
649
|
}
|
|
629
650
|
<!-- Check if not last -->
|
|
@@ -634,9 +655,7 @@ class ImagesPreviewComponent {
|
|
|
634
655
|
(mousedown)="$event.stopPropagation()"
|
|
635
656
|
aria-label="Next image"
|
|
636
657
|
>
|
|
637
|
-
<svg viewBox="0 0 24 24">
|
|
638
|
-
<path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z" />
|
|
639
|
-
</svg>
|
|
658
|
+
<svg viewBox="0 0 24 24"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></svg>
|
|
640
659
|
</button>
|
|
641
660
|
}
|
|
642
661
|
|
|
@@ -653,43 +672,27 @@ class ImagesPreviewComponent {
|
|
|
653
672
|
>
|
|
654
673
|
<!-- Flip H -->
|
|
655
674
|
<button class="toolbar-btn" (click)="flipHorizontal()" aria-label="Flip Horizontal">
|
|
656
|
-
<svg viewBox="0 0 24 24">
|
|
657
|
-
<path
|
|
658
|
-
d="M15 21h2v-2h-2v2zm4-12h2V7h-2v2zM3 5v14c0 1.1.9 2 2 2h4v-2H5V5h4V3H5c-1.1 0-2 .9-2 2zm16-2v2h2c0-1.1-.9-2-2-2zm-8 20h2V1h-2v22zm8-6h2v-2h-2v2zM15 5h2V3h-2v2zm4 8h2v-2h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2z"
|
|
659
|
-
/>
|
|
660
|
-
</svg>
|
|
675
|
+
<svg viewBox="0 0 24 24"><path d="M15 21h2v-2h-2v2zm4-12h2V7h-2v2zM3 5v14c0 1.1.9 2 2 2h4v-2H5V5h4V3H5c-1.1 0-2 .9-2 2zm16-2v2h2c0-1.1-.9-2-2-2zm-8 20h2V1h-2v22zm8-6h2v-2h-2v2zM15 5h2V3h-2v2zm4 8h2v-2h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2z"/></svg>
|
|
661
676
|
</button>
|
|
662
677
|
<!-- Flip V -->
|
|
663
678
|
<button class="toolbar-btn" (click)="flipVertical()" aria-label="Flip Vertical">
|
|
664
|
-
<svg viewBox="0 0 24 24">
|
|
665
|
-
<path
|
|
666
|
-
d="M7 21h2v-2H7v2zM3 9h2V7H3v2zm12 12h2v-2h-2v2zm4-12h2V7h-2v2zm-4 4h2v-4h-2v4zm-8-8h2V3H7v2zm8 0h2V3h-2v2zm-4 8h4v-4h-4v4zM3 15h2v-2H3v2zm12-4h2v-4H3v4h2v-2h10v2zM7 3v2h2V3H7zm8 20h2v-2h-2v2zm-4 0h2v-2h-2v2zm4-12h2v-2h-2v2zM3 19c0 1.1.9 2 2 2h2v-2H5v-2H3v2zm16-6h2v-2h-2v2zm0 4v2c0 1.1-.9 2-2 2h-2v-2h2v-2h2zM5 3c-1.1 0-2 .9-2 2h2V3z"
|
|
667
|
-
/>
|
|
668
|
-
</svg>
|
|
679
|
+
<svg viewBox="0 0 24 24"><path d="M7 21h2v-2H7v2zM3 9h2V7H3v2zm12 12h2v-2h-2v2zm4-12h2V7h-2v2zm-4 4h2v-4h-2v4zm-8-8h2V3H7v2zm8 0h2V3h-2v2zm-4 8h4v-4h-4v4zM3 15h2v-2H3v2zm12-4h2v-4H3v4h2v-2h10v2zM7 3v2h2V3H7zm8 20h2v-2h-2v2zm-4 0h2v-2h-2v2zm4-12h2v-2h-2v2zM3 19c0 1.1.9 2 2 2h2v-2H5v-2H3v2zm16-6h2v-2h-2v2zm0 4v2c0 1.1-.9 2-2 2h-2v-2h2v-2h2zM5 3c-1.1 0-2 .9-2 2h2V3z"/></svg>
|
|
669
680
|
</button>
|
|
670
681
|
<!-- Rotate Left -->
|
|
671
682
|
<button class="toolbar-btn" (click)="rotateLeft()" aria-label="Rotate Left">
|
|
672
|
-
<svg viewBox="0 0 24 24">
|
|
673
|
-
<path
|
|
674
|
-
d="M7.11 8.53L5.7 7.11C4.8 8.27 4.24 9.61 4.07 11h2.02c.14-.87.49-1.72 1.02-2.47zM6.09 13H4.07c.17 1.39.72 2.73 1.62 3.89l1.41-1.42c-.52-.75-.87-1.59-1.01-2.47zm1.01 5.32c1.16.9 2.51 1.44 3.9 1.61V17.9c-.87-.15-1.71-.49-2.46-1.03L7.1 18.32zM13 4.07V1L8.45 5.55 13 10V6.09c2.84.48 5 2.94 5 5.91s-2.16 5.43-5 5.91v2.02c3.95-.49 7-3.85 7-7.93s-3.05-7.44-7-7.93z"
|
|
675
|
-
/>
|
|
676
|
-
</svg>
|
|
683
|
+
<svg viewBox="0 0 24 24"><path d="M7.11 8.53L5.7 7.11C4.8 8.27 4.24 9.61 4.07 11h2.02c.14-.87.49-1.72 1.02-2.47zM6.09 13H4.07c.17 1.39.72 2.73 1.62 3.89l1.41-1.42c-.52-.75-.87-1.59-1.01-2.47zm1.01 5.32c1.16.9 2.51 1.44 3.9 1.61V17.9c-.87-.15-1.71-.49-2.46-1.03L7.1 18.32zM13 4.07V1L8.45 5.55 13 10V6.09c2.84.48 5 2.94 5 5.91s-2.16 5.43-5 5.91v2.02c3.95-.49 7-3.85 7-7.93s-3.05-7.44-7-7.93z"/></svg>
|
|
677
684
|
</button>
|
|
678
685
|
<!-- Rotate Right -->
|
|
679
686
|
<button class="toolbar-btn" (click)="rotateRight()" aria-label="Rotate Right">
|
|
680
|
-
<svg viewBox="0 0 24 24">
|
|
681
|
-
<path
|
|
682
|
-
d="M15.55 5.55L11 1v3.07C7.06 4.56 4 7.92 4 12s3.05 7.44 7 7.93v-2.02c-2.84-.48-5-2.94-5-5.91s2.16-5.43 5-5.91V10l4.55-4.45zM19.93 11c-.17-1.39-.72-2.73-1.62-3.89l-1.42 1.42c.54.75.88 1.6 1.02 2.47h2.02zM13 17.9v2.02c1.39-.17 2.74-.71 3.9-1.61l-1.44-1.44c-.75.54-1.59.89-2.46 1.03zm3.89-2.42l1.42 1.41c.9-1.16 1.45-2.5 1.62-3.89h-2.02c-.14.87-.48 1.72-1.02 2.48z"
|
|
683
|
-
/>
|
|
684
|
-
</svg>
|
|
687
|
+
<svg viewBox="0 0 24 24"><path d="M15.55 5.55L11 1v3.07C7.06 4.56 4 7.92 4 12s3.05 7.44 7 7.93v-2.02c-2.84-.48-5-2.94-5-5.91s2.16-5.43 5-5.91V10l4.55-4.45zM19.93 11c-.17-1.39-.72-2.73-1.62-3.89l-1.42 1.42c.54.75.88 1.6 1.02 2.47h2.02zM13 17.9v2.02c1.39-.17 2.74-.71 3.9-1.61l-1.44-1.44c-.75.54-1.59.89-2.46 1.03zm3.89-2.42l1.42 1.41c.9-1.16 1.45-2.5 1.62-3.89h-2.02c-.14.87-.48 1.72-1.02 2.48z"/></svg>
|
|
685
688
|
</button>
|
|
686
689
|
<!-- Zoom Out -->
|
|
687
690
|
<button class="toolbar-btn" (click)="zoomOut()" aria-label="Zoom Out">
|
|
688
|
-
|
|
691
|
+
<svg viewBox="0 0 24 24"><path d="M19 13H5v-2h14v2z"/></svg>
|
|
689
692
|
</button>
|
|
690
693
|
<!-- Zoom In -->
|
|
691
694
|
<button class="toolbar-btn" (click)="zoomIn()" aria-label="Zoom In">
|
|
692
|
-
|
|
695
|
+
<svg viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>
|
|
693
696
|
</button>
|
|
694
697
|
</div>
|
|
695
698
|
}
|
|
@@ -759,11 +762,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.7", ngImpor
|
|
|
759
762
|
|
|
760
763
|
<!-- Close Button -->
|
|
761
764
|
<button class="close-btn" (click)="close()" aria-label="Close preview">
|
|
762
|
-
<svg viewBox="0 0 24 24">
|
|
763
|
-
<path
|
|
764
|
-
d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"
|
|
765
|
-
/>
|
|
766
|
-
</svg>
|
|
765
|
+
<svg viewBox="0 0 24 24"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
|
|
767
766
|
</button>
|
|
768
767
|
|
|
769
768
|
<!-- Navigation -->
|
|
@@ -776,9 +775,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.7", ngImpor
|
|
|
776
775
|
(mousedown)="$event.stopPropagation()"
|
|
777
776
|
aria-label="Previous image"
|
|
778
777
|
>
|
|
779
|
-
<svg viewBox="0 0 24 24">
|
|
780
|
-
<path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z" />
|
|
781
|
-
</svg>
|
|
778
|
+
<svg viewBox="0 0 24 24"><path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/></svg>
|
|
782
779
|
</button>
|
|
783
780
|
}
|
|
784
781
|
<!-- Check if not last -->
|
|
@@ -789,9 +786,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.7", ngImpor
|
|
|
789
786
|
(mousedown)="$event.stopPropagation()"
|
|
790
787
|
aria-label="Next image"
|
|
791
788
|
>
|
|
792
|
-
<svg viewBox="0 0 24 24">
|
|
793
|
-
<path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z" />
|
|
794
|
-
</svg>
|
|
789
|
+
<svg viewBox="0 0 24 24"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></svg>
|
|
795
790
|
</button>
|
|
796
791
|
}
|
|
797
792
|
|
|
@@ -808,43 +803,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.7", ngImpor
|
|
|
808
803
|
>
|
|
809
804
|
<!-- Flip H -->
|
|
810
805
|
<button class="toolbar-btn" (click)="flipHorizontal()" aria-label="Flip Horizontal">
|
|
811
|
-
<svg viewBox="0 0 24 24">
|
|
812
|
-
<path
|
|
813
|
-
d="M15 21h2v-2h-2v2zm4-12h2V7h-2v2zM3 5v14c0 1.1.9 2 2 2h4v-2H5V5h4V3H5c-1.1 0-2 .9-2 2zm16-2v2h2c0-1.1-.9-2-2-2zm-8 20h2V1h-2v22zm8-6h2v-2h-2v2zM15 5h2V3h-2v2zm4 8h2v-2h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2z"
|
|
814
|
-
/>
|
|
815
|
-
</svg>
|
|
806
|
+
<svg viewBox="0 0 24 24"><path d="M15 21h2v-2h-2v2zm4-12h2V7h-2v2zM3 5v14c0 1.1.9 2 2 2h4v-2H5V5h4V3H5c-1.1 0-2 .9-2 2zm16-2v2h2c0-1.1-.9-2-2-2zm-8 20h2V1h-2v22zm8-6h2v-2h-2v2zM15 5h2V3h-2v2zm4 8h2v-2h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2z"/></svg>
|
|
816
807
|
</button>
|
|
817
808
|
<!-- Flip V -->
|
|
818
809
|
<button class="toolbar-btn" (click)="flipVertical()" aria-label="Flip Vertical">
|
|
819
|
-
<svg viewBox="0 0 24 24">
|
|
820
|
-
<path
|
|
821
|
-
d="M7 21h2v-2H7v2zM3 9h2V7H3v2zm12 12h2v-2h-2v2zm4-12h2V7h-2v2zm-4 4h2v-4h-2v4zm-8-8h2V3H7v2zm8 0h2V3h-2v2zm-4 8h4v-4h-4v4zM3 15h2v-2H3v2zm12-4h2v-4H3v4h2v-2h10v2zM7 3v2h2V3H7zm8 20h2v-2h-2v2zm-4 0h2v-2h-2v2zm4-12h2v-2h-2v2zM3 19c0 1.1.9 2 2 2h2v-2H5v-2H3v2zm16-6h2v-2h-2v2zm0 4v2c0 1.1-.9 2-2 2h-2v-2h2v-2h2zM5 3c-1.1 0-2 .9-2 2h2V3z"
|
|
822
|
-
/>
|
|
823
|
-
</svg>
|
|
810
|
+
<svg viewBox="0 0 24 24"><path d="M7 21h2v-2H7v2zM3 9h2V7H3v2zm12 12h2v-2h-2v2zm4-12h2V7h-2v2zm-4 4h2v-4h-2v4zm-8-8h2V3H7v2zm8 0h2V3h-2v2zm-4 8h4v-4h-4v4zM3 15h2v-2H3v2zm12-4h2v-4H3v4h2v-2h10v2zM7 3v2h2V3H7zm8 20h2v-2h-2v2zm-4 0h2v-2h-2v2zm4-12h2v-2h-2v2zM3 19c0 1.1.9 2 2 2h2v-2H5v-2H3v2zm16-6h2v-2h-2v2zm0 4v2c0 1.1-.9 2-2 2h-2v-2h2v-2h2zM5 3c-1.1 0-2 .9-2 2h2V3z"/></svg>
|
|
824
811
|
</button>
|
|
825
812
|
<!-- Rotate Left -->
|
|
826
813
|
<button class="toolbar-btn" (click)="rotateLeft()" aria-label="Rotate Left">
|
|
827
|
-
<svg viewBox="0 0 24 24">
|
|
828
|
-
<path
|
|
829
|
-
d="M7.11 8.53L5.7 7.11C4.8 8.27 4.24 9.61 4.07 11h2.02c.14-.87.49-1.72 1.02-2.47zM6.09 13H4.07c.17 1.39.72 2.73 1.62 3.89l1.41-1.42c-.52-.75-.87-1.59-1.01-2.47zm1.01 5.32c1.16.9 2.51 1.44 3.9 1.61V17.9c-.87-.15-1.71-.49-2.46-1.03L7.1 18.32zM13 4.07V1L8.45 5.55 13 10V6.09c2.84.48 5 2.94 5 5.91s-2.16 5.43-5 5.91v2.02c3.95-.49 7-3.85 7-7.93s-3.05-7.44-7-7.93z"
|
|
830
|
-
/>
|
|
831
|
-
</svg>
|
|
814
|
+
<svg viewBox="0 0 24 24"><path d="M7.11 8.53L5.7 7.11C4.8 8.27 4.24 9.61 4.07 11h2.02c.14-.87.49-1.72 1.02-2.47zM6.09 13H4.07c.17 1.39.72 2.73 1.62 3.89l1.41-1.42c-.52-.75-.87-1.59-1.01-2.47zm1.01 5.32c1.16.9 2.51 1.44 3.9 1.61V17.9c-.87-.15-1.71-.49-2.46-1.03L7.1 18.32zM13 4.07V1L8.45 5.55 13 10V6.09c2.84.48 5 2.94 5 5.91s-2.16 5.43-5 5.91v2.02c3.95-.49 7-3.85 7-7.93s-3.05-7.44-7-7.93z"/></svg>
|
|
832
815
|
</button>
|
|
833
816
|
<!-- Rotate Right -->
|
|
834
817
|
<button class="toolbar-btn" (click)="rotateRight()" aria-label="Rotate Right">
|
|
835
|
-
<svg viewBox="0 0 24 24">
|
|
836
|
-
<path
|
|
837
|
-
d="M15.55 5.55L11 1v3.07C7.06 4.56 4 7.92 4 12s3.05 7.44 7 7.93v-2.02c-2.84-.48-5-2.94-5-5.91s2.16-5.43 5-5.91V10l4.55-4.45zM19.93 11c-.17-1.39-.72-2.73-1.62-3.89l-1.42 1.42c.54.75.88 1.6 1.02 2.47h2.02zM13 17.9v2.02c1.39-.17 2.74-.71 3.9-1.61l-1.44-1.44c-.75.54-1.59.89-2.46 1.03zm3.89-2.42l1.42 1.41c.9-1.16 1.45-2.5 1.62-3.89h-2.02c-.14.87-.48 1.72-1.02 2.48z"
|
|
838
|
-
/>
|
|
839
|
-
</svg>
|
|
818
|
+
<svg viewBox="0 0 24 24"><path d="M15.55 5.55L11 1v3.07C7.06 4.56 4 7.92 4 12s3.05 7.44 7 7.93v-2.02c-2.84-.48-5-2.94-5-5.91s2.16-5.43 5-5.91V10l4.55-4.45zM19.93 11c-.17-1.39-.72-2.73-1.62-3.89l-1.42 1.42c.54.75.88 1.6 1.02 2.47h2.02zM13 17.9v2.02c1.39-.17 2.74-.71 3.9-1.61l-1.44-1.44c-.75.54-1.59.89-2.46 1.03zm3.89-2.42l1.42 1.41c.9-1.16 1.45-2.5 1.62-3.89h-2.02c-.14.87-.48 1.72-1.02 2.48z"/></svg>
|
|
840
819
|
</button>
|
|
841
820
|
<!-- Zoom Out -->
|
|
842
821
|
<button class="toolbar-btn" (click)="zoomOut()" aria-label="Zoom Out">
|
|
843
|
-
|
|
822
|
+
<svg viewBox="0 0 24 24"><path d="M19 13H5v-2h14v2z"/></svg>
|
|
844
823
|
</button>
|
|
845
824
|
<!-- Zoom In -->
|
|
846
825
|
<button class="toolbar-btn" (click)="zoomIn()" aria-label="Zoom In">
|
|
847
|
-
|
|
826
|
+
<svg viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>
|
|
848
827
|
</button>
|
|
849
828
|
</div>
|
|
850
829
|
}
|
|
@@ -881,6 +860,7 @@ class ImagesPreviewDirective {
|
|
|
881
860
|
appRef = inject(ApplicationRef);
|
|
882
861
|
injector = inject(EnvironmentInjector);
|
|
883
862
|
el = inject((ElementRef));
|
|
863
|
+
platformId = inject(PLATFORM_ID);
|
|
884
864
|
onClick(event) {
|
|
885
865
|
event.stopPropagation();
|
|
886
866
|
// Prevent duplicate open
|
|
@@ -903,6 +883,8 @@ class ImagesPreviewDirective {
|
|
|
903
883
|
}
|
|
904
884
|
cursor = 'pointer';
|
|
905
885
|
openPreview(src) {
|
|
886
|
+
if (!isPlatformBrowser(this.platformId))
|
|
887
|
+
return;
|
|
906
888
|
// Create Component
|
|
907
889
|
this.componentRef = createComponent(ImagesPreviewComponent, {
|
|
908
890
|
environmentInjector: this.injector
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ng-images-preview.mjs","sources":["../../../projects/ng-images-preview/src/lib/images-preview.component.ts","../../../projects/ng-images-preview/src/lib/images-preview.directive.ts","../../../projects/ng-images-preview/src/public-api.ts","../../../projects/ng-images-preview/src/ng-images-preview.ts"],"sourcesContent":["import {\n Component,\n ElementRef,\n HostListener,\n computed,\n input,\n signal,\n viewChild,\n ChangeDetectionStrategy,\n TemplateRef,\n inject,\n effect,\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { animate, style, transition, trigger } from '@angular/animations';\n\nexport interface ImagesPreviewState {\n src: string;\n scale: number;\n rotate: number;\n flipH: boolean;\n flipV: boolean;\n isLoading: boolean;\n hasError: boolean;\n}\n\nexport interface ImagesPreviewActions {\n zoomIn: () => void;\n zoomOut: () => void;\n rotateLeft: () => void;\n rotateRight: () => void;\n flipHorizontal: () => void;\n flipVertical: () => void;\n reset: () => void;\n close: () => void;\n}\n\ninterface TrackingPoint {\n x: number;\n y: number;\n time: number;\n}\n\n@Component({\n selector: 'ng-images-preview',\n standalone: true,\n imports: [CommonModule],\n template: `\n <div\n class=\"overlay\"\n [@fadeInOut]\n (click)=\"close()\"\n (keydown)=\"onOverlayKey($event)\"\n tabindex=\"0\"\n role=\"button\"\n aria-label=\"Close preview overlay\"\n >\n <!-- Custom Template Support -->\n @if (customTemplate(); as template) {\n <ng-container\n *ngTemplateOutlet=\"template; context: { $implicit: state(), actions: actions }\"\n ></ng-container>\n } @else {\n <!-- Loading -->\n @if (isLoading()) {\n <div class=\"loader\">Loading...</div>\n }\n\n <!-- Error -->\n @if (hasError()) {\n <div class=\"error\">Failed to load image</div>\n }\n\n <!-- Image Container -->\n <div\n class=\"image-container\"\n (keydown)=\"onContainerKey($event)\"\n (touchstart)=\"onTouchStart($event)\"\n tabindex=\"-1\"\n >\n <img\n #imgRef\n [src]=\"activeSrc()\"\n [class.opacity-0]=\"isLoading() || hasError()\"\n class=\"preview-image\"\n [class.dragging]=\"isDragging()\"\n [class.zoom-in]=\"scale() === 1\"\n [class.zoom-out]=\"scale() > 1\"\n [style.transform]=\"transformStyle()\"\n (load)=\"onImageLoad()\"\n (error)=\"onImageError()\"\n (mousedown)=\"onMouseDown($event)\"\n (click)=\"$event.stopPropagation()\"\n draggable=\"false\"\n alt=\"Preview\"\n />\n </div>\n\n <!-- Close Button -->\n <button class=\"close-btn\" (click)=\"close()\" aria-label=\"Close preview\">\n <svg viewBox=\"0 0 24 24\">\n <path\n d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"\n />\n </svg>\n </button>\n\n <!-- Navigation -->\n @if (images() && images()!.length > 1) {\n <!-- Check if not first -->\n @if (currentIndex() > 0) {\n <button\n class=\"nav-btn prev\"\n (click)=\"prev(); $event.stopPropagation()\"\n (mousedown)=\"$event.stopPropagation()\"\n aria-label=\"Previous image\"\n >\n <svg viewBox=\"0 0 24 24\">\n <path d=\"M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z\" />\n </svg>\n </button>\n }\n <!-- Check if not last -->\n @if (currentIndex() < images()!.length - 1) {\n <button\n class=\"nav-btn next\"\n (click)=\"next(); $event.stopPropagation()\"\n (mousedown)=\"$event.stopPropagation()\"\n aria-label=\"Next image\"\n >\n <svg viewBox=\"0 0 24 24\">\n <path d=\"M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z\" />\n </svg>\n </button>\n }\n\n <!-- Counter -->\n <div class=\"counter\">{{ currentIndex() + 1 }} / {{ images()!.length }}</div>\n }\n\n <!-- Toolbar -->\n <div\n class=\"toolbar\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"onToolbarKey($event)\"\n tabindex=\"0\"\n >\n <!-- Flip H -->\n <button class=\"toolbar-btn\" (click)=\"flipHorizontal()\" aria-label=\"Flip Horizontal\">\n <svg viewBox=\"0 0 24 24\">\n <path\n d=\"M15 21h2v-2h-2v2zm4-12h2V7h-2v2zM3 5v14c0 1.1.9 2 2 2h4v-2H5V5h4V3H5c-1.1 0-2 .9-2 2zm16-2v2h2c0-1.1-.9-2-2-2zm-8 20h2V1h-2v22zm8-6h2v-2h-2v2zM15 5h2V3h-2v2zm4 8h2v-2h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2z\"\n />\n </svg>\n </button>\n <!-- Flip V -->\n <button class=\"toolbar-btn\" (click)=\"flipVertical()\" aria-label=\"Flip Vertical\">\n <svg viewBox=\"0 0 24 24\">\n <path\n d=\"M7 21h2v-2H7v2zM3 9h2V7H3v2zm12 12h2v-2h-2v2zm4-12h2V7h-2v2zm-4 4h2v-4h-2v4zm-8-8h2V3H7v2zm8 0h2V3h-2v2zm-4 8h4v-4h-4v4zM3 15h2v-2H3v2zm12-4h2v-4H3v4h2v-2h10v2zM7 3v2h2V3H7zm8 20h2v-2h-2v2zm-4 0h2v-2h-2v2zm4-12h2v-2h-2v2zM3 19c0 1.1.9 2 2 2h2v-2H5v-2H3v2zm16-6h2v-2h-2v2zm0 4v2c0 1.1-.9 2-2 2h-2v-2h2v-2h2zM5 3c-1.1 0-2 .9-2 2h2V3z\"\n />\n </svg>\n </button>\n <!-- Rotate Left -->\n <button class=\"toolbar-btn\" (click)=\"rotateLeft()\" aria-label=\"Rotate Left\">\n <svg viewBox=\"0 0 24 24\">\n <path\n d=\"M7.11 8.53L5.7 7.11C4.8 8.27 4.24 9.61 4.07 11h2.02c.14-.87.49-1.72 1.02-2.47zM6.09 13H4.07c.17 1.39.72 2.73 1.62 3.89l1.41-1.42c-.52-.75-.87-1.59-1.01-2.47zm1.01 5.32c1.16.9 2.51 1.44 3.9 1.61V17.9c-.87-.15-1.71-.49-2.46-1.03L7.1 18.32zM13 4.07V1L8.45 5.55 13 10V6.09c2.84.48 5 2.94 5 5.91s-2.16 5.43-5 5.91v2.02c3.95-.49 7-3.85 7-7.93s-3.05-7.44-7-7.93z\"\n />\n </svg>\n </button>\n <!-- Rotate Right -->\n <button class=\"toolbar-btn\" (click)=\"rotateRight()\" aria-label=\"Rotate Right\">\n <svg viewBox=\"0 0 24 24\">\n <path\n d=\"M15.55 5.55L11 1v3.07C7.06 4.56 4 7.92 4 12s3.05 7.44 7 7.93v-2.02c-2.84-.48-5-2.94-5-5.91s2.16-5.43 5-5.91V10l4.55-4.45zM19.93 11c-.17-1.39-.72-2.73-1.62-3.89l-1.42 1.42c.54.75.88 1.6 1.02 2.47h2.02zM13 17.9v2.02c1.39-.17 2.74-.71 3.9-1.61l-1.44-1.44c-.75.54-1.59.89-2.46 1.03zm3.89-2.42l1.42 1.41c.9-1.16 1.45-2.5 1.62-3.89h-2.02c-.14.87-.48 1.72-1.02 2.48z\"\n />\n </svg>\n </button>\n <!-- Zoom Out -->\n <button class=\"toolbar-btn\" (click)=\"zoomOut()\" aria-label=\"Zoom Out\">\n <svg viewBox=\"0 0 24 24\"><path d=\"M19 13H5v-2h14v2z\" /></svg>\n </button>\n <!-- Zoom In -->\n <button class=\"toolbar-btn\" (click)=\"zoomIn()\" aria-label=\"Zoom In\">\n <svg viewBox=\"0 0 24 24\"><path d=\"M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z\" /></svg>\n </button>\n </div>\n }\n </div>\n `,\n styleUrls: ['./images-preview.component.css'],\n animations: [\n trigger('fadeInOut', [\n transition(':enter', [\n style({ opacity: 0 }),\n animate('200ms ease-out', style({ opacity: 1 })),\n ]),\n transition(':leave', [animate('200ms ease-in', style({ opacity: 0 }))]),\n ]),\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '(document:mouseup)': 'onMouseUp()',\n '(document:touchmove)': 'onTouchMove($event)',\n '(document:touchend)': 'onTouchEnd($event)',\n '(document:keydown.arrowleft)': 'prev()',\n '(document:keydown.arrowright)': 'next()',\n '(document:keydown.escape)': 'close()',\n },\n})\nexport class ImagesPreviewComponent {\n src = input.required<string>();\n images = input<string[]>();\n initialIndex = input(0);\n customTemplate = input<TemplateRef<unknown>>();\n closeCallback: () => void = () => {\n /* noop */\n };\n\n imgRef = viewChild<ElementRef<HTMLImageElement>>('imgRef');\n\n // State signals\n currentIndex = signal(0);\n isLoading = signal(true);\n hasError = signal(false);\n\n activeSrc = computed(() => {\n const imgs = this.images();\n if (imgs && imgs.length > 0) {\n return imgs[this.currentIndex()];\n }\n return this.src();\n });\n\n constructor() {\n // defined in class body usually, but here to show logical grouping\n effect(\n () => {\n // Initialize index from input\n this.currentIndex.set(this.initialIndex());\n },\n { allowSignalWrites: true },\n );\n\n effect(\n () => {\n // Reset state when index changes\n this.currentIndex();\n this.isLoading.set(true);\n this.hasError.set(false);\n this.reset(); // Reset zoom/rotate\n },\n { allowSignalWrites: true },\n );\n }\n\n scale = signal(1);\n translateX = signal(0);\n translateY = signal(0);\n rotate = signal(0);\n flipH = signal(false);\n flipV = signal(false);\n\n isDragging = signal(false);\n\n // Touch state\n private initialPinchDistance = 0;\n private initialScale = 1;\n private isPinching = false;\n\n // Computed state object for template\n state = computed<ImagesPreviewState>(() => ({\n src: this.src(),\n scale: this.scale(),\n rotate: this.rotate(),\n flipH: this.flipH(),\n flipV: this.flipV(),\n isLoading: this.isLoading(),\n hasError: this.hasError(),\n }));\n\n // Actions object for template\n actions: ImagesPreviewActions = {\n zoomIn: () => this.zoomIn(),\n zoomOut: () => this.zoomOut(),\n rotateLeft: () => this.rotateLeft(),\n rotateRight: () => this.rotateRight(),\n flipHorizontal: () => this.flipHorizontal(),\n flipVertical: () => this.flipVertical(),\n reset: () => this.reset(),\n close: () => this.close(),\n };\n\n private readonly MIN_SCALE = 0.5;\n private readonly MAX_SCALE = 5;\n private readonly ZOOM_STEP = 0.5;\n\n private startX = 0;\n private startY = 0;\n private lastTranslateX = 0;\n private lastTranslateY = 0;\n\n // Physics state\n private velocityX = 0;\n private velocityY = 0;\n private touchHistory: TrackingPoint[] = [];\n private cachedConstraints: { maxX: number; maxY: number } | null = null;\n private lastTimestamp = 0;\n private rafId: number | null = null;\n private readonly FRICTION = 0.92; // Heavier feel\n private readonly VELOCITY_THRESHOLD = 0.01;\n private readonly MAX_VELOCITY = 3; // Cap speed to prevent teleporting\n\n transformStyle = computed(() => {\n const scale = this.scale();\n const x = this.translateX();\n const y = this.translateY();\n const rotate = this.rotate();\n const scaleX = this.flipH() ? -1 : 1;\n const scaleY = this.flipV() ? -1 : 1;\n\n return `translate3d(${x}px, ${y}px, 0) scale(${scale}) rotate(${rotate}deg) scaleX(${scaleX}) scaleY(${scaleY})`;\n });\n\n @HostListener('document:keydown.escape')\n onEscape() {\n this.close();\n }\n\n @HostListener('document:mousemove', ['$event'])\n onMouseMove(event: MouseEvent) {\n if (!this.isDragging()) return;\n event.preventDefault();\n\n const deltaX = event.clientX - this.startX;\n const deltaY = event.clientY - this.startY;\n\n let nextX = this.lastTranslateX + deltaX;\n let nextY = this.lastTranslateY + deltaY;\n\n // Apply strict clamping during move\n this.applyMoveConstraints(nextX, nextY);\n }\n\n private applyMoveConstraints(nextX: number, nextY: number) {\n const img = this.imgRef()?.nativeElement;\n if (!img) {\n this.translateX.set(nextX);\n this.translateY.set(nextY);\n return;\n }\n\n const scale = this.scale();\n const rotate = Math.abs(this.rotate() % 180);\n const isRotated = rotate === 90;\n\n const baseWidth = img.offsetWidth;\n const baseHeight = img.offsetHeight;\n\n const currentWidth = (isRotated ? baseHeight : baseWidth) * scale;\n const currentHeight = (isRotated ? baseWidth : baseHeight) * scale;\n\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n\n const maxTranslateX = Math.max(0, (currentWidth - viewportWidth) / 2);\n const maxTranslateY = Math.max(0, (currentHeight - viewportHeight) / 2);\n\n // Clamp\n const clampedX = Math.max(-maxTranslateX, Math.min(maxTranslateX, nextX));\n const clampedY = Math.max(-maxTranslateY, Math.min(maxTranslateY, nextY));\n\n this.translateX.set(clampedX);\n this.translateY.set(clampedY);\n }\n\n onTouchMove(event: TouchEvent) {\n if (!this.isDragging() && !this.isPinching) return;\n\n // Prevent default to stop page scrolling/zooming\n if (event.cancelable) {\n event.preventDefault();\n }\n\n const touches = event.touches;\n\n // One finger: Pan\n if (touches.length === 1 && this.isDragging() && !this.isPinching) {\n const now = Date.now();\n\n // Add point to history\n this.touchHistory.push({\n x: touches[0].clientX,\n y: touches[0].clientY,\n time: now,\n });\n\n // Prune history (keep last 100ms)\n const cutoff = now - 100;\n while (this.touchHistory.length > 0 && this.touchHistory[0].time < cutoff) {\n this.touchHistory.shift();\n }\n\n const deltaX = touches[0].clientX - this.lastTouchX;\n const deltaY = touches[0].clientY - this.lastTouchY;\n\n // Note: We do NOT calculate velocity here anymore to avoid noise.\n // We verify velocity at TouchEnd using history.\n\n const currentX = this.translateX();\n const currentY = this.translateY();\n\n let nextX = currentX + deltaX;\n let nextY = currentY + deltaY;\n\n // Apply rubber banding if out of bounds\n // Use cached constraints to avoid reflows\n const constraints = this.cachedConstraints || this.getConstraints();\n\n if (nextX > constraints.maxX) {\n nextX = constraints.maxX + (nextX - constraints.maxX) * 0.5;\n } else if (nextX < -constraints.maxX) {\n nextX = -constraints.maxX + (nextX + constraints.maxX) * 0.5;\n }\n\n if (nextY > constraints.maxY) {\n nextY = constraints.maxY + (nextY - constraints.maxY) * 0.5;\n } else if (nextY < -constraints.maxY) {\n nextY = -constraints.maxY + (nextY + constraints.maxY) * 0.5;\n }\n\n this.translateX.set(nextX);\n this.translateY.set(nextY);\n\n this.lastTouchX = touches[0].clientX;\n this.lastTouchY = touches[0].clientY;\n }\n\n // Two fingers: Pinch Zoom\n if (touches.length === 2) {\n const distance = this.getDistance(touches);\n if (this.initialPinchDistance > 0) {\n const scaleFactor = distance / this.initialPinchDistance;\n const newScale = Math.min(\n Math.max(this.initialScale * scaleFactor, this.MIN_SCALE),\n this.MAX_SCALE,\n );\n this.scale.set(newScale);\n\n // Re-clamp position after zoom\n this.clampPosition();\n }\n }\n }\n\n private getConstraints() {\n // If we have a valid cache during interaction, use it to avoid reflows\n // The instruction says: \"So `getConstraints` stays as is (calculates fresh).\"\n // So, this method should always calculate fresh.\n // The `cachedConstraints` property is used *outside* this method.\n\n const img = this.imgRef()?.nativeElement;\n if (!img) return { maxX: 0, maxY: 0 };\n\n const scale = this.scale();\n const rotate = Math.abs(this.rotate() % 180);\n const isRotated = rotate === 90;\n\n const baseWidth = img.offsetWidth;\n const baseHeight = img.offsetHeight;\n\n const currentWidth = (isRotated ? baseHeight : baseWidth) * scale;\n const currentHeight = (isRotated ? baseWidth : baseHeight) * scale;\n\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n\n return {\n maxX: Math.max(0, (currentWidth - viewportWidth) / 2),\n maxY: Math.max(0, (currentHeight - viewportHeight) / 2),\n };\n }\n\n private clampPosition() {\n const img = this.imgRef()?.nativeElement;\n if (!img) return;\n\n const scale = this.scale();\n const rotate = Math.abs(this.rotate() % 180);\n const isRotated = rotate === 90;\n\n const baseWidth = img.offsetWidth;\n const baseHeight = img.offsetHeight;\n\n // Effective dimensions after rotation\n const currentWidth = (isRotated ? baseHeight : baseWidth) * scale;\n const currentHeight = (isRotated ? baseWidth : baseHeight) * scale;\n\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n\n const maxTranslateX = Math.max(0, (currentWidth - viewportWidth) / 2);\n const maxTranslateY = Math.max(0, (currentHeight - viewportHeight) / 2);\n\n // Clamp logic\n const currentX = this.translateX();\n const currentY = this.translateY();\n\n let newX = currentX;\n let newY = currentY;\n\n if (Math.abs(currentX) > maxTranslateX) {\n newX = Math.sign(currentX) * maxTranslateX;\n }\n if (Math.abs(currentY) > maxTranslateY) {\n newY = Math.sign(currentY) * maxTranslateY;\n }\n\n // If image is smaller than viewport, force center (0)\n if (currentWidth <= viewportWidth) newX = 0;\n if (currentHeight <= viewportHeight) newY = 0;\n\n if (newX !== currentX) this.translateX.set(newX);\n if (newY !== currentY) this.translateY.set(newY);\n }\n\n private startInertia() {\n let lastTime = Date.now();\n\n const step = () => {\n if (\n !this.isDragging() &&\n (Math.abs(this.velocityX) > this.VELOCITY_THRESHOLD ||\n Math.abs(this.velocityY) > this.VELOCITY_THRESHOLD)\n ) {\n const now = Date.now();\n const dt = Math.min(now - lastTime, 64); // Cap dt to avoid huge jumps if lag\n lastTime = now;\n\n if (dt === 0) {\n // Skip if 0ms passed (can happen on fast screens)\n this.rafId = requestAnimationFrame(step);\n return;\n }\n\n // Clamp max velocity (just in case)\n this.velocityX = Math.max(-this.MAX_VELOCITY, Math.min(this.MAX_VELOCITY, this.velocityX));\n this.velocityY = Math.max(-this.MAX_VELOCITY, Math.min(this.MAX_VELOCITY, this.velocityY));\n\n // Time-based friction\n // Standard friction is 0.95 per 16ms frame\n const frictionFactor = Math.pow(this.FRICTION, dt / 16);\n\n this.velocityX *= frictionFactor;\n this.velocityY *= frictionFactor;\n\n let nextX = this.translateX() + this.velocityX * dt;\n let nextY = this.translateY() + this.velocityY * dt;\n\n // Check bounds during inertia\n // Hard stop/bounce logic can be improved here if needed\n const constraints = this.cachedConstraints || this.getConstraints();\n\n if (nextX > constraints.maxX) {\n nextX = constraints.maxX;\n this.velocityX = 0;\n } else if (nextX < -constraints.maxX) {\n nextX = -constraints.maxX;\n this.velocityX = 0;\n }\n\n if (nextY > constraints.maxY) {\n nextY = constraints.maxY;\n this.velocityY = 0;\n } else if (nextY < -constraints.maxY) {\n nextY = -constraints.maxY;\n this.velocityY = 0;\n }\n\n this.translateX.set(nextX);\n this.translateY.set(nextY);\n\n this.rafId = requestAnimationFrame(step);\n } else {\n this.stopInertia();\n // Clear cache when movement stops\n // The instruction says to clear it in onTouchEnd or reset/scale changes.\n // So, no need to clear it here.\n }\n };\n this.rafId = requestAnimationFrame(step);\n }\n\n private stopInertia() {\n if (this.rafId) {\n cancelAnimationFrame(this.rafId);\n this.rafId = null;\n }\n }\n\n private snapBack() {\n const constraints = this.cachedConstraints || this.getConstraints();\n const currentX = this.translateX();\n const currentY = this.translateY();\n\n let targetX = currentX;\n let targetY = currentY;\n\n if (currentX > constraints.maxX) targetX = constraints.maxX;\n if (currentX < -constraints.maxX) targetX = -constraints.maxX;\n if (currentY > constraints.maxY) targetY = constraints.maxY;\n if (currentY < -constraints.maxY) targetY = -constraints.maxY;\n\n if (targetX !== currentX || targetY !== currentY) {\n // Animate snap back? For now, we rely on CSS transition if not dragging\n // But we turned off transition for .dragging.\n // We need to ensure .dragging is removed (it is in onTouchEnd).\n // CSS transition handles the snap if we just set the value.\n this.translateX.set(targetX);\n this.translateY.set(targetY);\n }\n }\n\n onToolbarKey(event: KeyboardEvent) {\n event.stopPropagation();\n }\n\n onOverlayKey(event: KeyboardEvent) {\n if (event.key === 'Enter' || event.key === ' ') {\n this.close();\n }\n }\n\n onContainerKey(event: KeyboardEvent) {\n // Prevent closing when interacting with image container via keyboard if needed\n event.stopPropagation();\n }\n\n onMouseUp() {\n this.isDragging.set(false);\n }\n\n onTouchEnd(event: TouchEvent) {\n const touches = event.touches;\n if (touches.length === 0) {\n this.isDragging.set(false);\n\n // Calculate Release Velocity from History\n const now = Date.now();\n const lastPoint = this.touchHistory[this.touchHistory.length - 1];\n // We want a point from roughly 30-50ms ago to get \"launch\" direction,\n // but tracking last 100ms.\n // A simple approach: compare last point with oldest point in our (pruned) buffer.\n const oldestPoint = this.touchHistory[0];\n\n if (lastPoint && oldestPoint && lastPoint !== oldestPoint) {\n const dt = lastPoint.time - oldestPoint.time;\n if (dt > 0) {\n this.velocityX = (lastPoint.x - oldestPoint.x) / dt;\n this.velocityY = (lastPoint.y - oldestPoint.y) / dt;\n }\n } else {\n this.velocityX = 0;\n this.velocityY = 0;\n }\n\n this.isDragging.set(false);\n this.isPinching = false;\n this.initialPinchDistance = 0;\n\n // Swipe Navigation (at 1x scale)\n if (this.scale() === 1) {\n const x = this.translateX();\n const threshold = 50; // px\n if (x < -threshold) {\n this.next();\n return;\n } else if (x > threshold) {\n this.prev();\n return;\n }\n }\n\n // Check bounds\n const constraints = this.cachedConstraints || this.getConstraints();\n const x = this.translateX();\n const y = this.translateY();\n const outOfBounds =\n x > constraints.maxX ||\n x < -constraints.maxX ||\n y > constraints.maxY ||\n y < -constraints.maxY;\n\n if (outOfBounds) {\n this.snapBack();\n this.velocityX = 0;\n this.velocityY = 0;\n this.cachedConstraints = null;\n } else {\n this.startInertia();\n }\n } else if (touches.length === 1 && this.isPinching) {\n // Transition from pinch to pan\n this.isPinching = false;\n this.isDragging.set(true);\n this.lastTouchX = touches[0].clientX;\n this.lastTouchY = touches[0].clientY;\n // Reset velocity on transition\n this.velocityX = 0;\n this.velocityY = 0;\n this.lastTimestamp = Date.now();\n // Re-cache constraints for new pan interaction\n this.cachedConstraints = this.getConstraints();\n }\n }\n\n private lastTouchX = 0;\n private lastTouchY = 0;\n\n private getDistance(touches: TouchList): number {\n return Math.hypot(\n touches[0].clientX - touches[1].clientX,\n touches[0].clientY - touches[1].clientY,\n );\n }\n\n close() {\n this.closeCallback();\n }\n\n onImageLoad() {\n this.isLoading.set(false);\n this.hasError.set(false);\n }\n\n onImageError() {\n this.isLoading.set(false);\n this.hasError.set(true);\n }\n\n // Zoom\n zoomIn() {\n this.scale.update((s) => Math.min(s + this.ZOOM_STEP, this.MAX_SCALE));\n setTimeout(() => this.clampPosition());\n this.cachedConstraints = null; // Invalidate cache on zoom\n }\n\n zoomOut() {\n this.scale.update((s) => Math.max(s - this.ZOOM_STEP, this.MIN_SCALE));\n setTimeout(() => this.clampPosition());\n this.cachedConstraints = null; // Invalidate cache on zoom\n }\n\n // Rotate\n rotateLeft() {\n this.rotate.update((r) => r - 90);\n setTimeout(() => this.clampPosition());\n this.cachedConstraints = null; // Invalidate cache on rotate\n }\n\n rotateRight() {\n this.rotate.update((r) => r + 90);\n setTimeout(() => this.clampPosition());\n this.cachedConstraints = null; // Invalidate cache on rotate\n }\n\n // Flip\n flipHorizontal() {\n this.flipH.update((f) => !f);\n this.cachedConstraints = null; // Invalidate cache on flip\n }\n\n flipVertical() {\n this.flipV.update((f) => !f);\n this.cachedConstraints = null; // Invalidate cache on flip\n }\n\n reset() {\n this.scale.set(1);\n this.translateX.set(0);\n this.translateY.set(0);\n this.rotate.set(0);\n this.flipH.set(false);\n this.flipV.set(false);\n this.cachedConstraints = null; // Invalidate cache on reset\n }\n\n next() {\n const imgs = this.images();\n if (!imgs) return;\n if (this.currentIndex() < imgs.length - 1) {\n this.currentIndex.update((i) => i + 1);\n }\n }\n\n prev() {\n if (this.currentIndex() > 0) {\n this.currentIndex.update((i) => i - 1);\n }\n }\n\n // Mouse Interaction\n onMouseDown(event: MouseEvent) {\n if (this.scale() <= 1 && !this.isDragging()) return; // Can drag only if zoomed? Or always? Default: only zoomed?\n // User expectation for preview: maybe panning always allowed? or only when zoomed?\n // Best practice: if image fits, no pan. If zoomed, pan.\n // I'll allow pan if scale > 1\n if (this.scale() <= 1) return;\n\n this.isDragging.set(true);\n this.startX = event.clientX;\n this.startY = event.clientY;\n this.lastTranslateX = this.translateX();\n this.lastTranslateY = this.translateY();\n event.preventDefault();\n }\n\n // Touch Interaction (bound in template)\n onTouchStart(event: TouchEvent) {\n this.stopInertia(); // Cancel any ongoing movement\n\n const touches = event.touches;\n\n if (touches.length === 1) {\n // Single touch: Pan. Only if touching the image directly.\n // We need to check if the target is the image element.\n const imgElement = this.imgRef()?.nativeElement;\n if (imgElement && event.target === imgElement) {\n this.isDragging.set(true);\n this.lastTouchX = touches[0].clientX;\n this.lastTouchY = touches[0].clientY;\n this.lastTimestamp = Date.now(); // Keep for scroll decay reference if needed\n\n // Initialize physics state\n this.velocityX = 0;\n this.velocityY = 0;\n this.touchHistory = [\n {\n x: touches[0].clientX,\n y: touches[0].clientY,\n time: Date.now(),\n },\n ];\n // Cache layout to prevent thrashing\n this.cachedConstraints = this.getConstraints();\n }\n } else if (touches.length === 2) {\n // Two fingers: Pinch\n this.isPinching = true;\n this.isDragging.set(false); // Stop panning\n this.initialPinchDistance = this.getDistance(touches);\n this.initialScale = this.scale();\n\n // Clear caching on pinch (scale changes will invalidate limits)\n this.cachedConstraints = null;\n\n // Prevent default to avoid browser zoom\n if (event.cancelable) event.preventDefault();\n }\n }\n}\n","\nimport {\n Directive,\n ElementRef,\n HostListener,\n Input,\n TemplateRef,\n ApplicationRef,\n EnvironmentInjector,\n createComponent,\n ComponentRef,\n inject,\n OnDestroy\n} from '@angular/core';\nimport { ImagesPreviewComponent } from './images-preview.component';\n\n@Directive({\n selector: '[ngImagesPreview]',\n standalone: true\n})\nexport class ImagesPreviewDirective implements OnDestroy {\n @Input('ngImagesPreview') highResSrc = '';\n @Input() previewImages: string[] = [];\n @Input() previewTemplate?: TemplateRef<unknown>;\n\n private componentRef: ComponentRef<ImagesPreviewComponent> | null = null;\n\n private appRef = inject(ApplicationRef);\n private injector = inject(EnvironmentInjector);\n private el = inject(ElementRef<HTMLElement>);\n\n @HostListener('click', ['$event'])\n onClick(event: Event): void {\n event.stopPropagation();\n\n // Prevent duplicate open\n if (this.componentRef) return;\n\n // Determine Source\n const hostEl = this.el.nativeElement;\n let src = this.highResSrc || hostEl.getAttribute('src') || (hostEl as HTMLImageElement).src;\n\n // If no src found on host, try to find an img child\n if (!src) {\n const imgChild = hostEl.querySelector('img');\n if (imgChild) {\n src = imgChild.getAttribute('src') || imgChild.src;\n }\n }\n\n src = src || '';\n\n if (src) {\n this.openPreview(src);\n }\n }\n\n @HostListener('style.cursor')\n readonly cursor = 'pointer';\n\n private openPreview(src: string): void {\n // Create Component\n this.componentRef = createComponent(ImagesPreviewComponent, {\n environmentInjector: this.injector\n });\n\n // Set Inputs\n this.componentRef.setInput('src', src);\n\n if (this.previewImages.length > 0) {\n this.componentRef.setInput('images', this.previewImages);\n const index = this.previewImages.indexOf(src);\n this.componentRef.setInput('initialIndex', index >= 0 ? index : 0);\n }\n\n if (this.previewTemplate) {\n this.componentRef.setInput('customTemplate', this.previewTemplate);\n }\n\n // Set Callbacks\n this.componentRef.instance.closeCallback = () => this.destroyPreview();\n\n // Attach to App\n this.appRef.attachView(this.componentRef.hostView);\n\n // Append to Body\n const domElem = (this.componentRef.hostView as unknown as { rootNodes: HTMLElement[] }).rootNodes[0];\n document.body.appendChild(domElem);\n }\n\n private destroyPreview(): void {\n if (this.componentRef) {\n this.appRef.detachView(this.componentRef.hostView);\n this.componentRef.destroy();\n this.componentRef = null;\n }\n }\n\n ngOnDestroy(): void {\n this.destroyPreview();\n }\n}\n","\n/*\n * Public API Surface of ng-images-preview\n */\n\nexport * from './lib/images-preview.component';\nexport * from './lib/images-preview.directive';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ng-images-preview.mjs","sources":["../../../projects/ng-images-preview/src/lib/images-preview.component.ts","../../../projects/ng-images-preview/src/lib/images-preview.directive.ts","../../../projects/ng-images-preview/src/public-api.ts","../../../projects/ng-images-preview/src/ng-images-preview.ts"],"sourcesContent":["import {\n Component,\n ElementRef,\n HostListener,\n computed,\n input,\n signal,\n viewChild,\n ChangeDetectionStrategy,\n TemplateRef,\n inject,\n effect,\n PLATFORM_ID,\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { animate, style, transition, trigger } from '@angular/animations';\nimport { isPlatformBrowser } from '@angular/common';\n\nexport interface ImagesPreviewState {\n src: string;\n scale: number;\n rotate: number;\n flipH: boolean;\n flipV: boolean;\n isLoading: boolean;\n hasError: boolean;\n}\n\nexport interface ImagesPreviewActions {\n zoomIn: () => void;\n zoomOut: () => void;\n rotateLeft: () => void;\n rotateRight: () => void;\n flipHorizontal: () => void;\n flipVertical: () => void;\n reset: () => void;\n close: () => void;\n}\n\ninterface TrackingPoint {\n x: number;\n y: number;\n time: number;\n}\n\n@Component({\n selector: 'ng-images-preview',\n standalone: true,\n imports: [CommonModule],\n template: `\n <div\n class=\"overlay\"\n [@fadeInOut]\n (click)=\"close()\"\n (keydown)=\"onOverlayKey($event)\"\n tabindex=\"0\"\n role=\"button\"\n aria-label=\"Close preview overlay\"\n >\n <!-- Custom Template Support -->\n @if (customTemplate(); as template) {\n <ng-container\n *ngTemplateOutlet=\"template; context: { $implicit: state(), actions: actions }\"\n ></ng-container>\n } @else {\n <!-- Loading -->\n @if (isLoading()) {\n <div class=\"loader\">Loading...</div>\n }\n\n <!-- Error -->\n @if (hasError()) {\n <div class=\"error\">Failed to load image</div>\n }\n\n <!-- Image Container -->\n <div\n class=\"image-container\"\n (keydown)=\"onContainerKey($event)\"\n (touchstart)=\"onTouchStart($event)\"\n tabindex=\"-1\"\n >\n <img\n #imgRef\n [src]=\"activeSrc()\"\n [class.opacity-0]=\"isLoading() || hasError()\"\n class=\"preview-image\"\n [class.dragging]=\"isDragging()\"\n [class.zoom-in]=\"scale() === 1\"\n [class.zoom-out]=\"scale() > 1\"\n [style.transform]=\"transformStyle()\"\n (load)=\"onImageLoad()\"\n (error)=\"onImageError()\"\n (mousedown)=\"onMouseDown($event)\"\n (click)=\"$event.stopPropagation()\"\n draggable=\"false\"\n alt=\"Preview\"\n />\n </div>\n\n <!-- Close Button -->\n <button class=\"close-btn\" (click)=\"close()\" aria-label=\"Close preview\">\n <svg viewBox=\"0 0 24 24\"><path d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"/></svg>\n </button>\n\n <!-- Navigation -->\n @if (images() && images()!.length > 1) {\n <!-- Check if not first -->\n @if (currentIndex() > 0) {\n <button\n class=\"nav-btn prev\"\n (click)=\"prev(); $event.stopPropagation()\"\n (mousedown)=\"$event.stopPropagation()\"\n aria-label=\"Previous image\"\n >\n <svg viewBox=\"0 0 24 24\"><path d=\"M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z\"/></svg>\n </button>\n }\n <!-- Check if not last -->\n @if (currentIndex() < images()!.length - 1) {\n <button\n class=\"nav-btn next\"\n (click)=\"next(); $event.stopPropagation()\"\n (mousedown)=\"$event.stopPropagation()\"\n aria-label=\"Next image\"\n >\n <svg viewBox=\"0 0 24 24\"><path d=\"M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z\"/></svg>\n </button>\n }\n\n <!-- Counter -->\n <div class=\"counter\">{{ currentIndex() + 1 }} / {{ images()!.length }}</div>\n }\n\n <!-- Toolbar -->\n <div\n class=\"toolbar\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"onToolbarKey($event)\"\n tabindex=\"0\"\n >\n <!-- Flip H -->\n <button class=\"toolbar-btn\" (click)=\"flipHorizontal()\" aria-label=\"Flip Horizontal\">\n <svg viewBox=\"0 0 24 24\"><path d=\"M15 21h2v-2h-2v2zm4-12h2V7h-2v2zM3 5v14c0 1.1.9 2 2 2h4v-2H5V5h4V3H5c-1.1 0-2 .9-2 2zm16-2v2h2c0-1.1-.9-2-2-2zm-8 20h2V1h-2v22zm8-6h2v-2h-2v2zM15 5h2V3h-2v2zm4 8h2v-2h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2z\"/></svg>\n </button>\n <!-- Flip V -->\n <button class=\"toolbar-btn\" (click)=\"flipVertical()\" aria-label=\"Flip Vertical\">\n <svg viewBox=\"0 0 24 24\"><path d=\"M7 21h2v-2H7v2zM3 9h2V7H3v2zm12 12h2v-2h-2v2zm4-12h2V7h-2v2zm-4 4h2v-4h-2v4zm-8-8h2V3H7v2zm8 0h2V3h-2v2zm-4 8h4v-4h-4v4zM3 15h2v-2H3v2zm12-4h2v-4H3v4h2v-2h10v2zM7 3v2h2V3H7zm8 20h2v-2h-2v2zm-4 0h2v-2h-2v2zm4-12h2v-2h-2v2zM3 19c0 1.1.9 2 2 2h2v-2H5v-2H3v2zm16-6h2v-2h-2v2zm0 4v2c0 1.1-.9 2-2 2h-2v-2h2v-2h2zM5 3c-1.1 0-2 .9-2 2h2V3z\"/></svg>\n </button>\n <!-- Rotate Left -->\n <button class=\"toolbar-btn\" (click)=\"rotateLeft()\" aria-label=\"Rotate Left\">\n <svg viewBox=\"0 0 24 24\"><path d=\"M7.11 8.53L5.7 7.11C4.8 8.27 4.24 9.61 4.07 11h2.02c.14-.87.49-1.72 1.02-2.47zM6.09 13H4.07c.17 1.39.72 2.73 1.62 3.89l1.41-1.42c-.52-.75-.87-1.59-1.01-2.47zm1.01 5.32c1.16.9 2.51 1.44 3.9 1.61V17.9c-.87-.15-1.71-.49-2.46-1.03L7.1 18.32zM13 4.07V1L8.45 5.55 13 10V6.09c2.84.48 5 2.94 5 5.91s-2.16 5.43-5 5.91v2.02c3.95-.49 7-3.85 7-7.93s-3.05-7.44-7-7.93z\"/></svg>\n </button>\n <!-- Rotate Right -->\n <button class=\"toolbar-btn\" (click)=\"rotateRight()\" aria-label=\"Rotate Right\">\n <svg viewBox=\"0 0 24 24\"><path d=\"M15.55 5.55L11 1v3.07C7.06 4.56 4 7.92 4 12s3.05 7.44 7 7.93v-2.02c-2.84-.48-5-2.94-5-5.91s2.16-5.43 5-5.91V10l4.55-4.45zM19.93 11c-.17-1.39-.72-2.73-1.62-3.89l-1.42 1.42c.54.75.88 1.6 1.02 2.47h2.02zM13 17.9v2.02c1.39-.17 2.74-.71 3.9-1.61l-1.44-1.44c-.75.54-1.59.89-2.46 1.03zm3.89-2.42l1.42 1.41c.9-1.16 1.45-2.5 1.62-3.89h-2.02c-.14.87-.48 1.72-1.02 2.48z\"/></svg>\n </button>\n <!-- Zoom Out -->\n <button class=\"toolbar-btn\" (click)=\"zoomOut()\" aria-label=\"Zoom Out\">\n <svg viewBox=\"0 0 24 24\"><path d=\"M19 13H5v-2h14v2z\"/></svg>\n </button>\n <!-- Zoom In -->\n <button class=\"toolbar-btn\" (click)=\"zoomIn()\" aria-label=\"Zoom In\">\n <svg viewBox=\"0 0 24 24\"><path d=\"M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z\"/></svg>\n </button>\n </div>\n }\n </div>\n `,\n styleUrls: ['./images-preview.component.css'],\n animations: [\n trigger('fadeInOut', [\n transition(':enter', [\n style({ opacity: 0 }),\n animate('200ms ease-out', style({ opacity: 1 })),\n ]),\n transition(':leave', [animate('200ms ease-in', style({ opacity: 0 }))]),\n ]),\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '(document:mouseup)': 'onMouseUp()',\n '(document:touchmove)': 'onTouchMove($event)',\n '(document:touchend)': 'onTouchEnd($event)',\n '(document:keydown.arrowleft)': 'prev()',\n '(document:keydown.arrowright)': 'next()',\n '(document:keydown.escape)': 'close()',\n },\n})\nexport class ImagesPreviewComponent {\n src = input.required<string>();\n images = input<string[]>();\n initialIndex = input(0);\n customTemplate = input<TemplateRef<unknown>>();\n closeCallback: () => void = () => {\n /* noop */\n };\n\n imgRef = viewChild<ElementRef<HTMLImageElement>>('imgRef');\n\n // State signals\n currentIndex = signal(0);\n isLoading = signal(true);\n hasError = signal(false);\n\n activeSrc = computed(() => {\n const imgs = this.images();\n if (imgs && imgs.length > 0) {\n return imgs[this.currentIndex()];\n }\n return this.src();\n });\n\n private platformId = inject(PLATFORM_ID);\n\n constructor() {\n // defined in class body usually, but here to show logical grouping\n effect(\n () => {\n // Initialize index from input\n this.currentIndex.set(this.initialIndex());\n },\n { allowSignalWrites: true },\n );\n\n effect(\n () => {\n // Reset state when index changes\n this.currentIndex();\n this.isLoading.set(true);\n this.hasError.set(false);\n this.reset(); // Reset zoom/rotate\n },\n { allowSignalWrites: true },\n );\n\n // Preload next/prev images\n effect(() => {\n const index = this.currentIndex();\n const images = this.images();\n\n if (isPlatformBrowser(this.platformId) && images && images.length > 0) {\n // Next\n if (index < images.length - 1) {\n const img = new Image();\n img.src = images[index + 1];\n }\n // Prev\n if (index > 0) {\n const img = new Image();\n img.src = images[index - 1];\n }\n }\n });\n }\n\n scale = signal(1);\n translateX = signal(0);\n translateY = signal(0);\n rotate = signal(0);\n flipH = signal(false);\n flipV = signal(false);\n\n isDragging = signal(false);\n\n // Touch state\n private initialPinchDistance = 0;\n private initialScale = 1;\n private isPinching = false;\n\n // Computed state object for template\n state = computed<ImagesPreviewState>(() => ({\n src: this.src(),\n scale: this.scale(),\n rotate: this.rotate(),\n flipH: this.flipH(),\n flipV: this.flipV(),\n isLoading: this.isLoading(),\n hasError: this.hasError(),\n }));\n\n // Actions object for template\n actions: ImagesPreviewActions = {\n zoomIn: () => this.zoomIn(),\n zoomOut: () => this.zoomOut(),\n rotateLeft: () => this.rotateLeft(),\n rotateRight: () => this.rotateRight(),\n flipHorizontal: () => this.flipHorizontal(),\n flipVertical: () => this.flipVertical(),\n reset: () => this.reset(),\n close: () => this.close(),\n };\n\n private readonly MIN_SCALE = 0.5;\n private readonly MAX_SCALE = 5;\n private readonly ZOOM_STEP = 0.5;\n\n private startX = 0;\n private startY = 0;\n private lastTranslateX = 0;\n private lastTranslateY = 0;\n\n // Physics state\n private velocityX = 0;\n private velocityY = 0;\n private touchHistory: TrackingPoint[] = [];\n private cachedConstraints: { maxX: number; maxY: number } | null = null;\n private lastTimestamp = 0;\n private rafId: number | null = null;\n private readonly FRICTION = 0.92; // Heavier feel\n private readonly VELOCITY_THRESHOLD = 0.01;\n private readonly MAX_VELOCITY = 3; // Cap speed to prevent teleporting\n\n transformStyle = computed(() => {\n const scale = this.scale();\n const x = this.translateX();\n const y = this.translateY();\n const rotate = this.rotate();\n const scaleX = this.flipH() ? -1 : 1;\n const scaleY = this.flipV() ? -1 : 1;\n\n return `translate3d(${x}px, ${y}px, 0) scale(${scale}) rotate(${rotate}deg) scaleX(${scaleX}) scaleY(${scaleY})`;\n });\n\n @HostListener('document:keydown.escape')\n onEscape() {\n this.close();\n }\n\n @HostListener('document:mousemove', ['$event'])\n onMouseMove(event: MouseEvent) {\n if (!this.isDragging()) return;\n event.preventDefault();\n\n const deltaX = event.clientX - this.startX;\n const deltaY = event.clientY - this.startY;\n\n let nextX = this.lastTranslateX + deltaX;\n let nextY = this.lastTranslateY + deltaY;\n\n // Apply strict clamping during move\n this.applyMoveConstraints(nextX, nextY);\n }\n\n private applyMoveConstraints(nextX: number, nextY: number) {\n if (!isPlatformBrowser(this.platformId)) {\n this.translateX.set(nextX);\n this.translateY.set(nextY);\n return;\n }\n\n const img = this.imgRef()?.nativeElement;\n if (!img) {\n this.translateX.set(nextX);\n this.translateY.set(nextY);\n return;\n }\n\n const scale = this.scale();\n const rotate = Math.abs(this.rotate() % 180);\n const isRotated = rotate === 90;\n\n const baseWidth = img.offsetWidth;\n const baseHeight = img.offsetHeight;\n\n const currentWidth = (isRotated ? baseHeight : baseWidth) * scale;\n const currentHeight = (isRotated ? baseWidth : baseHeight) * scale;\n\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n\n const maxTranslateX = Math.max(0, (currentWidth - viewportWidth) / 2);\n const maxTranslateY = Math.max(0, (currentHeight - viewportHeight) / 2);\n\n // Clamp\n const clampedX = Math.max(-maxTranslateX, Math.min(maxTranslateX, nextX));\n const clampedY = Math.max(-maxTranslateY, Math.min(maxTranslateY, nextY));\n\n this.translateX.set(clampedX);\n this.translateY.set(clampedY);\n }\n\n onTouchMove(event: TouchEvent) {\n if (!this.isDragging() && !this.isPinching) return;\n\n // Prevent default to stop page scrolling/zooming\n if (event.cancelable) {\n event.preventDefault();\n }\n\n const touches = event.touches;\n\n // One finger: Pan\n if (touches.length === 1 && this.isDragging() && !this.isPinching) {\n const now = Date.now();\n\n // Add point to history\n this.touchHistory.push({\n x: touches[0].clientX,\n y: touches[0].clientY,\n time: now,\n });\n\n // Prune history (keep last 100ms)\n const cutoff = now - 100;\n while (this.touchHistory.length > 0 && this.touchHistory[0].time < cutoff) {\n this.touchHistory.shift();\n }\n\n const deltaX = touches[0].clientX - this.lastTouchX;\n const deltaY = touches[0].clientY - this.lastTouchY;\n\n // Note: We do NOT calculate velocity here anymore to avoid noise.\n // We verify velocity at TouchEnd using history.\n\n const currentX = this.translateX();\n const currentY = this.translateY();\n\n let nextX = currentX + deltaX;\n let nextY = currentY + deltaY;\n\n // Apply rubber banding if out of bounds\n // Use cached constraints to avoid reflows\n const constraints = this.cachedConstraints || this.getConstraints();\n\n if (nextX > constraints.maxX) {\n nextX = constraints.maxX + (nextX - constraints.maxX) * 0.5;\n } else if (nextX < -constraints.maxX) {\n nextX = -constraints.maxX + (nextX + constraints.maxX) * 0.5;\n }\n\n if (nextY > constraints.maxY) {\n nextY = constraints.maxY + (nextY - constraints.maxY) * 0.5;\n } else if (nextY < -constraints.maxY) {\n nextY = -constraints.maxY + (nextY + constraints.maxY) * 0.5;\n }\n\n this.translateX.set(nextX);\n this.translateY.set(nextY);\n\n this.lastTouchX = touches[0].clientX;\n this.lastTouchY = touches[0].clientY;\n }\n\n // Two fingers: Pinch Zoom\n if (touches.length === 2) {\n const distance = this.getDistance(touches);\n if (this.initialPinchDistance > 0) {\n const scaleFactor = distance / this.initialPinchDistance;\n const newScale = Math.min(\n Math.max(this.initialScale * scaleFactor, this.MIN_SCALE),\n this.MAX_SCALE,\n );\n this.scale.set(newScale);\n\n // Re-clamp position after zoom\n this.clampPosition();\n }\n }\n }\n\n private getConstraints() {\n // If we have a valid cache during interaction, use it to avoid reflows\n // The instruction says: \"So `getConstraints` stays as is (calculates fresh).\"\n // So, this method should always calculate fresh.\n // The `cachedConstraints` property is used *outside* this method.\n\n if (!isPlatformBrowser(this.platformId)) return { maxX: 0, maxY: 0 };\n\n const img = this.imgRef()?.nativeElement;\n if (!img) return { maxX: 0, maxY: 0 };\n\n const scale = this.scale();\n const rotate = Math.abs(this.rotate() % 180);\n const isRotated = rotate === 90;\n\n const baseWidth = img.offsetWidth;\n const baseHeight = img.offsetHeight;\n\n const currentWidth = (isRotated ? baseHeight : baseWidth) * scale;\n const currentHeight = (isRotated ? baseWidth : baseHeight) * scale;\n\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n\n return {\n maxX: Math.max(0, (currentWidth - viewportWidth) / 2),\n maxY: Math.max(0, (currentHeight - viewportHeight) / 2),\n };\n }\n\n private clampPosition() {\n if (!isPlatformBrowser(this.platformId)) return;\n\n const img = this.imgRef()?.nativeElement;\n if (!img) return;\n\n const scale = this.scale();\n const rotate = Math.abs(this.rotate() % 180);\n const isRotated = rotate === 90;\n\n const baseWidth = img.offsetWidth;\n const baseHeight = img.offsetHeight;\n\n // Effective dimensions after rotation\n const currentWidth = (isRotated ? baseHeight : baseWidth) * scale;\n const currentHeight = (isRotated ? baseWidth : baseHeight) * scale;\n\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n\n const maxTranslateX = Math.max(0, (currentWidth - viewportWidth) / 2);\n const maxTranslateY = Math.max(0, (currentHeight - viewportHeight) / 2);\n\n // Clamp logic\n const currentX = this.translateX();\n const currentY = this.translateY();\n\n let newX = currentX;\n let newY = currentY;\n\n if (Math.abs(currentX) > maxTranslateX) {\n newX = Math.sign(currentX) * maxTranslateX;\n }\n if (Math.abs(currentY) > maxTranslateY) {\n newY = Math.sign(currentY) * maxTranslateY;\n }\n\n // If image is smaller than viewport, force center (0)\n if (currentWidth <= viewportWidth) newX = 0;\n if (currentHeight <= viewportHeight) newY = 0;\n\n if (newX !== currentX) this.translateX.set(newX);\n if (newY !== currentY) this.translateY.set(newY);\n }\n\n private startInertia() {\n let lastTime = Date.now();\n\n const step = () => {\n if (\n !this.isDragging() &&\n (Math.abs(this.velocityX) > this.VELOCITY_THRESHOLD ||\n Math.abs(this.velocityY) > this.VELOCITY_THRESHOLD)\n ) {\n const now = Date.now();\n const dt = Math.min(now - lastTime, 64); // Cap dt to avoid huge jumps if lag\n lastTime = now;\n\n if (dt === 0) {\n // Skip if 0ms passed (can happen on fast screens)\n this.rafId = requestAnimationFrame(step);\n return;\n }\n\n // Clamp max velocity (just in case)\n this.velocityX = Math.max(-this.MAX_VELOCITY, Math.min(this.MAX_VELOCITY, this.velocityX));\n this.velocityY = Math.max(-this.MAX_VELOCITY, Math.min(this.MAX_VELOCITY, this.velocityY));\n\n // Time-based friction\n // Standard friction is 0.95 per 16ms frame\n const frictionFactor = Math.pow(this.FRICTION, dt / 16);\n\n this.velocityX *= frictionFactor;\n this.velocityY *= frictionFactor;\n\n let nextX = this.translateX() + this.velocityX * dt;\n let nextY = this.translateY() + this.velocityY * dt;\n\n // Check bounds during inertia\n // Hard stop/bounce logic can be improved here if needed\n const constraints = this.cachedConstraints || this.getConstraints();\n\n if (nextX > constraints.maxX) {\n nextX = constraints.maxX;\n this.velocityX = 0;\n } else if (nextX < -constraints.maxX) {\n nextX = -constraints.maxX;\n this.velocityX = 0;\n }\n\n if (nextY > constraints.maxY) {\n nextY = constraints.maxY;\n this.velocityY = 0;\n } else if (nextY < -constraints.maxY) {\n nextY = -constraints.maxY;\n this.velocityY = 0;\n }\n\n this.translateX.set(nextX);\n this.translateY.set(nextY);\n\n this.rafId = requestAnimationFrame(step);\n } else {\n this.stopInertia();\n // Clear cache when movement stops\n // The instruction says to clear it in onTouchEnd or reset/scale changes.\n // So, no need to clear it here.\n }\n };\n this.rafId = requestAnimationFrame(step);\n }\n\n private stopInertia() {\n if (this.rafId) {\n cancelAnimationFrame(this.rafId);\n this.rafId = null;\n }\n }\n\n private snapBack() {\n const constraints = this.cachedConstraints || this.getConstraints();\n const currentX = this.translateX();\n const currentY = this.translateY();\n\n let targetX = currentX;\n let targetY = currentY;\n\n if (currentX > constraints.maxX) targetX = constraints.maxX;\n if (currentX < -constraints.maxX) targetX = -constraints.maxX;\n if (currentY > constraints.maxY) targetY = constraints.maxY;\n if (currentY < -constraints.maxY) targetY = -constraints.maxY;\n\n if (targetX !== currentX || targetY !== currentY) {\n // Animate snap back? For now, we rely on CSS transition if not dragging\n // But we turned off transition for .dragging.\n // We need to ensure .dragging is removed (it is in onTouchEnd).\n // CSS transition handles the snap if we just set the value.\n this.translateX.set(targetX);\n this.translateY.set(targetY);\n }\n }\n\n onToolbarKey(event: KeyboardEvent) {\n event.stopPropagation();\n }\n\n onOverlayKey(event: KeyboardEvent) {\n if (event.key === 'Enter' || event.key === ' ') {\n this.close();\n }\n }\n\n onContainerKey(event: KeyboardEvent) {\n // Prevent closing when interacting with image container via keyboard if needed\n event.stopPropagation();\n }\n\n onMouseUp() {\n this.isDragging.set(false);\n }\n\n onTouchEnd(event: TouchEvent) {\n const touches = event.touches;\n if (touches.length === 0) {\n this.isDragging.set(false);\n\n // Calculate Release Velocity from History\n const now = Date.now();\n const lastPoint = this.touchHistory[this.touchHistory.length - 1];\n // We want a point from roughly 30-50ms ago to get \"launch\" direction,\n // but tracking last 100ms.\n // A simple approach: compare last point with oldest point in our (pruned) buffer.\n const oldestPoint = this.touchHistory[0];\n\n if (lastPoint && oldestPoint && lastPoint !== oldestPoint) {\n const dt = lastPoint.time - oldestPoint.time;\n if (dt > 0) {\n this.velocityX = (lastPoint.x - oldestPoint.x) / dt;\n this.velocityY = (lastPoint.y - oldestPoint.y) / dt;\n }\n } else {\n this.velocityX = 0;\n this.velocityY = 0;\n }\n\n this.isDragging.set(false);\n this.isPinching = false;\n this.initialPinchDistance = 0;\n\n // Swipe Navigation (at 1x scale)\n if (this.scale() === 1) {\n const x = this.translateX();\n const threshold = 50; // px\n if (x < -threshold) {\n this.next();\n return;\n } else if (x > threshold) {\n this.prev();\n return;\n }\n }\n\n // Check bounds\n const constraints = this.cachedConstraints || this.getConstraints();\n const x = this.translateX();\n const y = this.translateY();\n const outOfBounds =\n x > constraints.maxX ||\n x < -constraints.maxX ||\n y > constraints.maxY ||\n y < -constraints.maxY;\n\n if (outOfBounds) {\n this.snapBack();\n this.velocityX = 0;\n this.velocityY = 0;\n this.cachedConstraints = null;\n } else {\n this.startInertia();\n }\n } else if (touches.length === 1 && this.isPinching) {\n // Transition from pinch to pan\n this.isPinching = false;\n this.isDragging.set(true);\n this.lastTouchX = touches[0].clientX;\n this.lastTouchY = touches[0].clientY;\n // Reset velocity on transition\n this.velocityX = 0;\n this.velocityY = 0;\n this.lastTimestamp = Date.now();\n // Re-cache constraints for new pan interaction\n this.cachedConstraints = this.getConstraints();\n }\n }\n\n private lastTouchX = 0;\n private lastTouchY = 0;\n\n private getDistance(touches: TouchList): number {\n return Math.hypot(\n touches[0].clientX - touches[1].clientX,\n touches[0].clientY - touches[1].clientY,\n );\n }\n\n close() {\n this.closeCallback();\n }\n\n onImageLoad() {\n this.isLoading.set(false);\n this.hasError.set(false);\n }\n\n onImageError() {\n this.isLoading.set(false);\n this.hasError.set(true);\n }\n\n // Zoom\n zoomIn() {\n this.scale.update((s) => Math.min(s + this.ZOOM_STEP, this.MAX_SCALE));\n setTimeout(() => this.clampPosition());\n this.cachedConstraints = null; // Invalidate cache on zoom\n }\n\n zoomOut() {\n this.scale.update((s) => Math.max(s - this.ZOOM_STEP, this.MIN_SCALE));\n setTimeout(() => this.clampPosition());\n this.cachedConstraints = null; // Invalidate cache on zoom\n }\n\n // Rotate\n rotateLeft() {\n this.rotate.update((r) => r - 90);\n setTimeout(() => this.clampPosition());\n this.cachedConstraints = null; // Invalidate cache on rotate\n }\n\n rotateRight() {\n this.rotate.update((r) => r + 90);\n setTimeout(() => this.clampPosition());\n this.cachedConstraints = null; // Invalidate cache on rotate\n }\n\n // Flip\n flipHorizontal() {\n this.flipH.update((f) => !f);\n this.cachedConstraints = null; // Invalidate cache on flip\n }\n\n flipVertical() {\n this.flipV.update((f) => !f);\n this.cachedConstraints = null; // Invalidate cache on flip\n }\n\n reset() {\n this.scale.set(1);\n this.translateX.set(0);\n this.translateY.set(0);\n this.rotate.set(0);\n this.flipH.set(false);\n this.flipV.set(false);\n this.cachedConstraints = null; // Invalidate cache on reset\n }\n\n next() {\n const imgs = this.images();\n if (!imgs) return;\n if (this.currentIndex() < imgs.length - 1) {\n this.currentIndex.update((i) => i + 1);\n }\n }\n\n prev() {\n if (this.currentIndex() > 0) {\n this.currentIndex.update((i) => i - 1);\n }\n }\n\n // Mouse Interaction\n onMouseDown(event: MouseEvent) {\n if (this.scale() <= 1 && !this.isDragging()) return; // Can drag only if zoomed? Or always? Default: only zoomed?\n // User expectation for preview: maybe panning always allowed? or only when zoomed?\n // Best practice: if image fits, no pan. If zoomed, pan.\n // I'll allow pan if scale > 1\n if (this.scale() <= 1) return;\n\n this.isDragging.set(true);\n this.startX = event.clientX;\n this.startY = event.clientY;\n this.lastTranslateX = this.translateX();\n this.lastTranslateY = this.translateY();\n event.preventDefault();\n }\n\n // Touch Interaction (bound in template)\n onTouchStart(event: TouchEvent) {\n this.stopInertia(); // Cancel any ongoing movement\n\n const touches = event.touches;\n\n if (touches.length === 1) {\n // Single touch: Pan. Only if touching the image directly.\n // We need to check if the target is the image element.\n const imgElement = this.imgRef()?.nativeElement;\n if (imgElement && event.target === imgElement) {\n this.isDragging.set(true);\n this.lastTouchX = touches[0].clientX;\n this.lastTouchY = touches[0].clientY;\n this.lastTimestamp = Date.now(); // Keep for scroll decay reference if needed\n\n // Initialize physics state\n this.velocityX = 0;\n this.velocityY = 0;\n this.touchHistory = [\n {\n x: touches[0].clientX,\n y: touches[0].clientY,\n time: Date.now(),\n },\n ];\n // Cache layout to prevent thrashing\n this.cachedConstraints = this.getConstraints();\n }\n } else if (touches.length === 2) {\n // Two fingers: Pinch\n this.isPinching = true;\n this.isDragging.set(false); // Stop panning\n this.initialPinchDistance = this.getDistance(touches);\n this.initialScale = this.scale();\n\n // Clear caching on pinch (scale changes will invalidate limits)\n this.cachedConstraints = null;\n\n // Prevent default to avoid browser zoom\n if (event.cancelable) event.preventDefault();\n }\n }\n}\n","\nimport {\n Directive,\n ElementRef,\n HostListener,\n Input,\n TemplateRef,\n ApplicationRef,\n EnvironmentInjector,\n createComponent,\n ComponentRef,\n inject,\n OnDestroy,\n PLATFORM_ID\n} from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\nimport { ImagesPreviewComponent } from './images-preview.component';\n\n@Directive({\n selector: '[ngImagesPreview]',\n standalone: true\n})\nexport class ImagesPreviewDirective implements OnDestroy {\n @Input('ngImagesPreview') highResSrc = '';\n @Input() previewImages: string[] = [];\n @Input() previewTemplate?: TemplateRef<unknown>;\n\n private componentRef: ComponentRef<ImagesPreviewComponent> | null = null;\n\n private appRef = inject(ApplicationRef);\n private injector = inject(EnvironmentInjector);\n private el = inject(ElementRef<HTMLElement>);\n private platformId = inject(PLATFORM_ID);\n\n @HostListener('click', ['$event'])\n onClick(event: Event): void {\n event.stopPropagation();\n\n // Prevent duplicate open\n if (this.componentRef) return;\n\n // Determine Source\n const hostEl = this.el.nativeElement;\n let src = this.highResSrc || hostEl.getAttribute('src') || (hostEl as HTMLImageElement).src;\n\n // If no src found on host, try to find an img child\n if (!src) {\n const imgChild = hostEl.querySelector('img');\n if (imgChild) {\n src = imgChild.getAttribute('src') || imgChild.src;\n }\n }\n\n src = src || '';\n\n if (src) {\n this.openPreview(src);\n }\n }\n\n @HostListener('style.cursor')\n readonly cursor = 'pointer';\n\n private openPreview(src: string): void {\n if (!isPlatformBrowser(this.platformId)) return;\n\n // Create Component\n this.componentRef = createComponent(ImagesPreviewComponent, {\n environmentInjector: this.injector\n });\n\n // Set Inputs\n this.componentRef.setInput('src', src);\n\n if (this.previewImages.length > 0) {\n this.componentRef.setInput('images', this.previewImages);\n const index = this.previewImages.indexOf(src);\n this.componentRef.setInput('initialIndex', index >= 0 ? index : 0);\n }\n\n if (this.previewTemplate) {\n this.componentRef.setInput('customTemplate', this.previewTemplate);\n }\n\n // Set Callbacks\n this.componentRef.instance.closeCallback = () => this.destroyPreview();\n\n // Attach to App\n this.appRef.attachView(this.componentRef.hostView);\n\n // Append to Body\n const domElem = (this.componentRef.hostView as unknown as { rootNodes: HTMLElement[] }).rootNodes[0];\n document.body.appendChild(domElem);\n }\n\n private destroyPreview(): void {\n if (this.componentRef) {\n this.appRef.detachView(this.componentRef.hostView);\n this.componentRef.destroy();\n this.componentRef = null;\n }\n }\n\n ngOnDestroy(): void {\n this.destroyPreview();\n }\n}\n","\n/*\n * Public API Surface of ng-images-preview\n */\n\nexport * from './lib/images-preview.component';\nexport * from './lib/images-preview.directive';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ng-images-preview",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"peerDependencies": {
|
|
5
5
|
"@angular/common": ">=17.3.0",
|
|
6
6
|
"@angular/core": ">=17.3.0"
|
|
@@ -8,6 +8,31 @@
|
|
|
8
8
|
"dependencies": {
|
|
9
9
|
"tslib": "^2.3.0"
|
|
10
10
|
},
|
|
11
|
+
"description": "A lightweight, mobile-ready Angular 18+ image preview library with zoom, rotate, flip, and custom template support. Built with Signals and Vanilla CSS.",
|
|
12
|
+
"keywords": [
|
|
13
|
+
"angular",
|
|
14
|
+
"image-preview",
|
|
15
|
+
"images-preview",
|
|
16
|
+
"image-viewer",
|
|
17
|
+
"lightbox",
|
|
18
|
+
"gallery",
|
|
19
|
+
"zoom",
|
|
20
|
+
"rotate",
|
|
21
|
+
"mobile-ready",
|
|
22
|
+
"touch-support",
|
|
23
|
+
"signals",
|
|
24
|
+
"standalone",
|
|
25
|
+
"vanilla-css"
|
|
26
|
+
],
|
|
27
|
+
"author": "lanxuexing <lanxuexing313wsr@163.com>",
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "https://github.com/lanxuexing/ng-images-preview.git"
|
|
32
|
+
},
|
|
33
|
+
"bugs": {
|
|
34
|
+
"url": "https://github.com/lanxuexing/ng-images-preview/issues"
|
|
35
|
+
},
|
|
11
36
|
"sideEffects": false,
|
|
12
37
|
"module": "fesm2022/ng-images-preview.mjs",
|
|
13
38
|
"typings": "types/ng-images-preview.d.ts",
|
|
@@ -31,6 +31,7 @@ declare class ImagesPreviewComponent {
|
|
|
31
31
|
isLoading: _angular_core.WritableSignal<boolean>;
|
|
32
32
|
hasError: _angular_core.WritableSignal<boolean>;
|
|
33
33
|
activeSrc: _angular_core.Signal<string>;
|
|
34
|
+
private platformId;
|
|
34
35
|
constructor();
|
|
35
36
|
scale: _angular_core.WritableSignal<number>;
|
|
36
37
|
translateX: _angular_core.WritableSignal<number>;
|
|
@@ -104,6 +105,7 @@ declare class ImagesPreviewDirective implements OnDestroy {
|
|
|
104
105
|
private appRef;
|
|
105
106
|
private injector;
|
|
106
107
|
private el;
|
|
108
|
+
private platformId;
|
|
107
109
|
onClick(event: Event): void;
|
|
108
110
|
readonly cursor = "pointer";
|
|
109
111
|
private openPreview;
|