aboutsummaryrefslogtreecommitdiff
path: root/viewer
diff options
context:
space:
mode:
Diffstat (limited to 'viewer')
-rw-r--r--viewer/package-lock.json15
-rw-r--r--viewer/package.json3
-rw-r--r--viewer/src/@types/gallery.d.ts10
-rw-r--r--viewer/src/components/LdPicture.vue56
-rw-r--r--viewer/src/services/ldzoom.ts134
-rw-r--r--viewer/src/views/MainLayout.vue1
6 files changed, 186 insertions, 33 deletions
diff --git a/viewer/package-lock.json b/viewer/package-lock.json
index 228788d..d4a5fb0 100644
--- a/viewer/package-lock.json
+++ b/viewer/package-lock.json
@@ -1232,6 +1232,11 @@
1232 "@types/node": "*" 1232 "@types/node": "*"
1233 } 1233 }
1234 }, 1234 },
1235 "@types/hammerjs": {
1236 "version": "2.0.36",
1237 "resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.36.tgz",
1238 "integrity": "sha512-7TUK/k2/QGpEAv/BCwSHlYu3NXZhQ9ZwBYpzr9tjlPIL2C5BeGhH3DmVavRx3ZNyELX5TLC91JTz/cen6AAtIQ=="
1239 },
1235 "@types/json-schema": { 1240 "@types/json-schema": {
1236 "version": "7.0.4", 1241 "version": "7.0.4",
1237 "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz", 1242 "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz",
@@ -6487,6 +6492,11 @@
6487 "pify": "^4.0.1" 6492 "pify": "^4.0.1"
6488 } 6493 }
6489 }, 6494 },
6495 "hammerjs": {
6496 "version": "2.0.8",
6497 "resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz",
6498 "integrity": "sha1-BO93hiz/K7edMPdpIJWTAiK/YPE="
6499 },
6490 "handle-thing": { 6500 "handle-thing": {
6491 "version": "2.0.1", 6501 "version": "2.0.1",
6492 "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", 6502 "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz",
@@ -10464,6 +10474,11 @@
10464 "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", 10474 "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
10465 "dev": true 10475 "dev": true
10466 }, 10476 },
10477 "resize-observer-polyfill": {
10478 "version": "1.5.1",
10479 "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
10480 "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
10481 },
10467 "resolve": { 10482 "resolve": {
10468 "version": "1.14.1", 10483 "version": "1.14.1",
10469 "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.14.1.tgz", 10484 "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.14.1.tgz",
diff --git a/viewer/package.json b/viewer/package.json
index 40a91ba..bc63dfd 100644
--- a/viewer/package.json
+++ b/viewer/package.json
@@ -13,8 +13,11 @@
13 "@fortawesome/fontawesome-svg-core": "^1.2.28", 13 "@fortawesome/fontawesome-svg-core": "^1.2.28",
14 "@fortawesome/free-solid-svg-icons": "^5.13.0", 14 "@fortawesome/free-solid-svg-icons": "^5.13.0",
15 "@fortawesome/vue-fontawesome": "^0.1.9", 15 "@fortawesome/vue-fontawesome": "^0.1.9",
16 "@types/hammerjs": "^2.0.36",
16 "buefy": "^0.8.15", 17 "buefy": "^0.8.15",
17 "core-js": "^3.6.4", 18 "core-js": "^3.6.4",
19 "hammerjs": "^2.0.8",
20 "resize-observer-polyfill": "^1.5.1",
18 "v-lazy-image": "^1.4.0", 21 "v-lazy-image": "^1.4.0",
19 "vue": "^2.6.11", 22 "vue": "^2.6.11",
20 "vue-class-component": "^7.2.3", 23 "vue-class-component": "^7.2.3",
diff --git a/viewer/src/@types/gallery.d.ts b/viewer/src/@types/gallery.d.ts
index de1c0dd..956ab6b 100644
--- a/viewer/src/@types/gallery.d.ts
+++ b/viewer/src/@types/gallery.d.ts
@@ -49,12 +49,17 @@ declare namespace Gallery {
49 thumbnail?: Thumbnail 49 thumbnail?: Thumbnail
50 properties: OtherProperties | PictureProperties | DirectoryProperties, 50 properties: OtherProperties | PictureProperties | DirectoryProperties,
51 } 51 }
52 interface Resolution {
53 width: number,
54 height: number,
55 }
52 interface OtherProperties { 56 interface OtherProperties {
53 type: "other", 57 type: "other",
54 } 58 }
55 interface PictureProperties { 59 interface PictureProperties {
56 type: "picture", 60 type: "picture",
57 resource: string, 61 resource: string,
62 resolution: Resolution
58 } 63 }
59 interface DirectoryProperties { 64 interface DirectoryProperties {
60 type: "directory", 65 type: "directory",
@@ -62,10 +67,7 @@ declare namespace Gallery {
62 } 67 }
63 interface Thumbnail { 68 interface Thumbnail {
64 resource: string, 69 resource: string,
65 resolution: { 70 resolution: Resolution
66 width: number,
67 height: number,
68 }
69 } 71 }
70 type RawTag = string; 72 type RawTag = string;
71 type ItemType = "other" | "picture" | "directory"; 73 type ItemType = "other" | "picture" | "directory";
diff --git a/viewer/src/components/LdPicture.vue b/viewer/src/components/LdPicture.vue
index 3170c81..de46bcb 100644
--- a/viewer/src/components/LdPicture.vue
+++ b/viewer/src/components/LdPicture.vue
@@ -18,17 +18,21 @@
18--> 18-->
19 19
20<template> 20<template>
21 <!-- FIXME: v-dragscroll interferes with pinch-to-zoom -->
21 <div 22 <div
23 ref="containerElement"
22 v-dragscroll 24 v-dragscroll
23 class="scrollbar" 25 class="scrollbar ld-picture-container"
24 :class="{'fit-to-screen': !$uiStore.fullscreen, 'original-size': $uiStore.fullscreen}"
25 @click.capture="e => dragScrollClickFix.onClickCapture(e)" 26 @click.capture="e => dragScrollClickFix.onClickCapture(e)"
26 @click="$uiStore.toggleFullscreen()" 27 @dblclick="$uiStore.toggleFullscreen()"
28 @dragstart.prevent
27 @dragscrollstart="dragScrollClickFix.onDragScrollStart()" 29 @dragscrollstart="dragScrollClickFix.onDragScrollStart()"
28 @dragscrollend="dragScrollClickFix.onDragScrollEnd()" 30 @dragscrollend="dragScrollClickFix.onDragScrollEnd()"
29 > 31 >
30 <v-lazy-image 32 <v-lazy-image
33 ref="imageElement"
31 :src="pictureSrc(picture.properties.resource)" 34 :src="pictureSrc(picture.properties.resource)"
35 class="ld-picture-element"
32 :class="{'slow-loading': Boolean(slowLoadingStyle)}" 36 :class="{'slow-loading': Boolean(slowLoadingStyle)}"
33 :style="slowLoadingStyle" 37 :style="slowLoadingStyle"
34 @load="clearSlowLoading" 38 @load="clearSlowLoading"
@@ -38,12 +42,15 @@
38</template> 42</template>
39 43
40<script lang="ts"> 44<script lang="ts">
41import { Component, Vue, Prop } from "vue-property-decorator"; 45import { Component, Vue, Prop, Ref } from "vue-property-decorator";
46import LdZoom from "@/services/ldzoom";
42import DragScrollClickFix from "@/services/dragscrollclickfix"; 47import DragScrollClickFix from "@/services/dragscrollclickfix";
43 48
44@Component 49@Component
45export default class LdPicture extends Vue { 50export default class LdPicture extends Vue {
46 @Prop({ required: true }) readonly picture!: Gallery.Picture; 51 @Prop({ required: true }) readonly picture!: Gallery.Picture;
52 @Ref() readonly containerElement!: HTMLDivElement;
53 @Ref() readonly imageElement!: Vue;
47 54
48 readonly SLOW_LOADING_TIMEOUT_MS: number = 1500; 55 readonly SLOW_LOADING_TIMEOUT_MS: number = 1500;
49 readonly dragScrollClickFix = new DragScrollClickFix(); 56 readonly dragScrollClickFix = new DragScrollClickFix();
@@ -54,6 +61,7 @@ export default class LdPicture extends Vue {
54 61
55 mounted() { 62 mounted() {
56 this.timer = setTimeout(this.generateSlowLoadingStyle, this.SLOW_LOADING_TIMEOUT_MS); 63 this.timer = setTimeout(this.generateSlowLoadingStyle, this.SLOW_LOADING_TIMEOUT_MS);
64 new LdZoom(this.containerElement, this.imageElement.$el as HTMLImageElement, this.picture.properties, 10, 1 / 5).install();
57 } 65 }
58 66
59 destroyed() { 67 destroyed() {
@@ -85,13 +93,17 @@ export default class LdPicture extends Vue {
85<style lang="scss"> 93<style lang="scss">
86@import "~@/assets/scss/theme.scss"; 94@import "~@/assets/scss/theme.scss";
87 95
88.ld-picture-loader { 96.ld-picture-container {
89 position: relative; 97 height: 100%;
90 & .loading-background {
91 background: none !important;
92 }
93} 98}
94img.slow-loading { 99
100.ld-picture-element {
101 max-width: unset;
102 max-height: unset;
103 cursor: grab;
104}
105
106.slow-loading {
95 background-repeat: no-repeat; 107 background-repeat: no-repeat;
96 background-position: center; 108 background-position: center;
97 background-size: contain; 109 background-size: contain;
@@ -99,25 +111,11 @@ img.slow-loading {
99 background-blend-mode: soft-light; 111 background-blend-mode: soft-light;
100 opacity: 1 !important; 112 opacity: 1 !important;
101} 113}
102.fit-to-screen { 114
103 display: flex; 115.ld-picture-loader {
104 justify-content: space-around; 116 position: relative;
105 height: 100%; 117 & .loading-background {
106 & > img { 118 background: none !important;
107 object-fit: contain;
108 cursor: zoom-in;
109 }
110}
111.original-size {
112 display: block;
113 text-align: center;
114 cursor: grab;
115 height: 100%;
116 & > img {
117 max-width: unset;
118 max-height: unset;
119 object-fit: none;
120 cursor: zoom-out;
121 } 119 }
122} 120}
123</style> 121</style>
diff --git a/viewer/src/services/ldzoom.ts b/viewer/src/services/ldzoom.ts
new file mode 100644
index 0000000..c28c2c8
--- /dev/null
+++ b/viewer/src/services/ldzoom.ts
@@ -0,0 +1,134 @@
1/* ldgallery - A static generator which turns a collection of tagged
2-- pictures into a searchable web gallery.
3--
4-- Copyright (C) 2020 Pacien TRAN-GIRARD
5--
6-- This program is free software: you can redistribute it and/or modify