@bikariya/image-viewer 0.0.5 → 0.0.7
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/module.json
CHANGED
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
type
|
|
1
|
+
import type { ModalProps } from "#modals";
|
|
2
|
+
type __VLS_Props = ModalProps & {
|
|
2
3
|
/**
|
|
3
4
|
* 目标 `<img>` 元素
|
|
4
5
|
*/
|
|
5
6
|
target: HTMLImageElement;
|
|
6
|
-
/**
|
|
7
|
-
* 过渡动画时长 (ms)
|
|
8
|
-
* @default 400
|
|
9
|
-
*/
|
|
10
|
-
duration?: number;
|
|
11
7
|
/**
|
|
12
8
|
* 放大后占窗口比率
|
|
13
9
|
* @default 0.9
|
|
@@ -18,7 +14,6 @@ type __VLS_Props = {
|
|
|
18
14
|
* @default false
|
|
19
15
|
*/
|
|
20
16
|
clamp?: boolean;
|
|
21
|
-
open?: boolean;
|
|
22
17
|
};
|
|
23
18
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
24
19
|
close: () => any;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { computed, ref, useEventListener, usePointer, useTemplateRef } from "#imports";
|
|
3
|
-
const { target, duration
|
|
4
|
-
target: { type: null, required: true },
|
|
3
|
+
const { target, duration, rate = 0.9, clamp } = defineProps({
|
|
5
4
|
duration: { type: Number, required: false },
|
|
5
|
+
open: { type: Boolean, required: false },
|
|
6
|
+
target: { type: null, required: true },
|
|
6
7
|
rate: { type: Number, required: false },
|
|
7
|
-
clamp: { type: Boolean, required: false }
|
|
8
|
-
open: { type: Boolean, required: false }
|
|
8
|
+
clamp: { type: Boolean, required: false }
|
|
9
9
|
});
|
|
10
10
|
const emit = defineEmits(["close"]);
|
|
11
11
|
const rootEl = useTemplateRef("root");
|
|
@@ -74,7 +74,7 @@ const { isHolding } = usePointer(rootEl, {
|
|
|
74
74
|
const finalTop = top - (center.value.y - top) * (rate2 - 1);
|
|
75
75
|
const finalWidth = startRect.width * rate2;
|
|
76
76
|
const finalHeight = startRect.height * rate2;
|
|
77
|
-
if (
|
|
77
|
+
if (isSizeOutOfBounds(finalWidth, finalHeight, rate2)) {
|
|
78
78
|
return;
|
|
79
79
|
}
|
|
80
80
|
rootEl.value.animate({
|
|
@@ -108,7 +108,7 @@ function onWheel(event) {
|
|
|
108
108
|
const finalTop = top - (event.clientY - top) * (rate2 - 1);
|
|
109
109
|
const finalWidth = width * rate2;
|
|
110
110
|
const finalHeight = height * rate2;
|
|
111
|
-
if (
|
|
111
|
+
if (isSizeOutOfBounds(finalWidth, finalHeight, rate2)) {
|
|
112
112
|
return;
|
|
113
113
|
}
|
|
114
114
|
rootEl.value.animate({
|
|
@@ -120,58 +120,67 @@ function onWheel(event) {
|
|
|
120
120
|
}
|
|
121
121
|
function onDoubleClick(event) {
|
|
122
122
|
const { left, top, width, height } = rootEl.value.getBoundingClientRect();
|
|
123
|
-
const {
|
|
124
|
-
if (width <
|
|
125
|
-
const
|
|
126
|
-
`calc(50% - ${Math.round(
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
123
|
+
const { containSize, coverSize, advantageSide } = getFitSize();
|
|
124
|
+
if (width < coverSize.width && height < coverSize.height) {
|
|
125
|
+
const centerLoc = {
|
|
126
|
+
left: `calc(50% - ${Math.round(coverSize.width / 2)}px)`,
|
|
127
|
+
top: `calc(50% - ${Math.round(coverSize.height / 2)}px)`
|
|
128
|
+
};
|
|
129
|
+
const pointerLoc = {
|
|
130
|
+
left: `${left - (event.clientX - left) * (coverSize.width / width - 1)}px`,
|
|
131
|
+
top: `${top - (event.clientY - top) * (coverSize.height / height - 1)}px`
|
|
132
|
+
};
|
|
132
133
|
rootEl.value.animate({
|
|
133
|
-
left:
|
|
134
|
-
top:
|
|
135
|
-
width: Math.ceil(
|
|
136
|
-
height: Math.ceil(
|
|
134
|
+
left: advantageSide === "height" ? centerLoc.left : pointerLoc.left,
|
|
135
|
+
top: advantageSide === "height" ? pointerLoc.top : centerLoc.top,
|
|
136
|
+
width: Math.ceil(coverSize.width) + "px",
|
|
137
|
+
height: Math.ceil(coverSize.height) + "px"
|
|
137
138
|
}, options.value);
|
|
138
139
|
} else {
|
|
139
|
-
const { size: [containWidth, containHeight] } = getFitSize("contain");
|
|
140
140
|
rootEl.value.animate({
|
|
141
|
-
left: `calc(50% - ${Math.round(
|
|
142
|
-
top: `calc(50% - ${Math.round(
|
|
143
|
-
width: Math.floor(
|
|
144
|
-
height: Math.floor(
|
|
141
|
+
left: `calc(50% - ${Math.round(containSize.width / 2)}px)`,
|
|
142
|
+
top: `calc(50% - ${Math.round(containSize.height / 2)}px)`,
|
|
143
|
+
width: Math.floor(containSize.width) + "px",
|
|
144
|
+
height: Math.floor(containSize.height) + "px"
|
|
145
145
|
}, options.value);
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
148
|
const onEnter = (el) => {
|
|
149
|
-
const {
|
|
149
|
+
const { containSize } = getFitSize();
|
|
150
150
|
el.animate([getOriginalKeyframe(), {
|
|
151
|
-
top: `calc(50% - ${Math.round(
|
|
152
|
-
left: `calc(50% - ${Math.round(
|
|
153
|
-
width: Math.floor(
|
|
154
|
-
height: Math.floor(
|
|
151
|
+
top: `calc(50% - ${Math.round(containSize.height / 2)}px)`,
|
|
152
|
+
left: `calc(50% - ${Math.round(containSize.width / 2)}px)`,
|
|
153
|
+
width: Math.floor(containSize.width) + "px",
|
|
154
|
+
height: Math.floor(containSize.height) + "px",
|
|
155
155
|
clipPath: "inset(0)"
|
|
156
156
|
}], options.value);
|
|
157
157
|
};
|
|
158
158
|
const onLeave = (el, done) => {
|
|
159
|
-
const { left
|
|
160
|
-
const { scrollX
|
|
159
|
+
const { left, top } = el.getBoundingClientRect();
|
|
160
|
+
const { scrollX, scrollY } = window;
|
|
161
161
|
const animation = el.animate([{
|
|
162
|
-
top: 2 *
|
|
163
|
-
left: 2 *
|
|
162
|
+
top: `calc(${2 * scrollY + top}px + 50dvh - 50svh)`,
|
|
163
|
+
left: `calc(${2 * scrollX + left}px + 50dvw - 50svw)`,
|
|
164
164
|
clipPath: "inset(0)"
|
|
165
|
-
}, getOriginalKeyframe(
|
|
165
|
+
}, getOriginalKeyframe(scrollX, scrollY)], options.value);
|
|
166
166
|
animation.addEventListener("finish", done);
|
|
167
167
|
};
|
|
168
|
-
function getFitSize(
|
|
168
|
+
function getFitSize() {
|
|
169
169
|
const fixedWidth = window.innerWidth * rate;
|
|
170
170
|
const fixedHeight = window.innerHeight * rate;
|
|
171
171
|
const naturalRatio = target.naturalWidth / target.naturalHeight;
|
|
172
172
|
const advantageSide = fixedWidth / fixedHeight > naturalRatio ? "height" : "width";
|
|
173
|
+
const widthSize = {
|
|
174
|
+
width: fixedWidth,
|
|
175
|
+
height: fixedWidth / naturalRatio
|
|
176
|
+
};
|
|
177
|
+
const heightSize = {
|
|
178
|
+
width: fixedHeight * naturalRatio,
|
|
179
|
+
height: fixedHeight
|
|
180
|
+
};
|
|
173
181
|
return {
|
|
174
|
-
|
|
182
|
+
containSize: advantageSide === "height" ? heightSize : widthSize,
|
|
183
|
+
coverSize: advantageSide === "height" ? widthSize : heightSize,
|
|
175
184
|
advantageSide
|
|
176
185
|
};
|
|
177
186
|
}
|
|
@@ -187,13 +196,13 @@ function getOriginalKeyframe(x = 0, y = 0) {
|
|
|
187
196
|
let clipLeft = 0;
|
|
188
197
|
let clipRight = 0;
|
|
189
198
|
if (ratio > naturalRatio) {
|
|
190
|
-
const
|
|
191
|
-
clipTop =
|
|
192
|
-
clipBottom =
|
|
199
|
+
const rest = width / naturalRatio - height;
|
|
200
|
+
clipTop = rest * vertical;
|
|
201
|
+
clipBottom = rest - clipTop;
|
|
193
202
|
} else {
|
|
194
|
-
const
|
|
195
|
-
clipLeft =
|
|
196
|
-
clipRight =
|
|
203
|
+
const rest = height * naturalRatio - width;
|
|
204
|
+
clipLeft = rest * horizontal;
|
|
205
|
+
clipRight = rest - clipLeft;
|
|
197
206
|
}
|
|
198
207
|
return {
|
|
199
208
|
top: y + top - clipTop + "px",
|
|
@@ -203,7 +212,7 @@ function getOriginalKeyframe(x = 0, y = 0) {
|
|
|
203
212
|
clipPath: `inset(${clipTop}px ${clipRight}px ${clipBottom}px ${clipLeft}px)`
|
|
204
213
|
};
|
|
205
214
|
}
|
|
206
|
-
function
|
|
215
|
+
function isSizeOutOfBounds(width, height, rate2) {
|
|
207
216
|
if (!clamp) {
|
|
208
217
|
return false;
|
|
209
218
|
}
|
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
type
|
|
1
|
+
import type { ModalProps } from "#modals";
|
|
2
|
+
type __VLS_Props = ModalProps & {
|
|
2
3
|
/**
|
|
3
4
|
* 目标 `<img>` 元素
|
|
4
5
|
*/
|
|
5
6
|
target: HTMLImageElement;
|
|
6
|
-
/**
|
|
7
|
-
* 过渡动画时长 (ms)
|
|
8
|
-
* @default 400
|
|
9
|
-
*/
|
|
10
|
-
duration?: number;
|
|
11
7
|
/**
|
|
12
8
|
* 放大后占窗口比率
|
|
13
9
|
* @default 0.9
|
|
@@ -18,7 +14,6 @@ type __VLS_Props = {
|
|
|
18
14
|
* @default false
|
|
19
15
|
*/
|
|
20
16
|
clamp?: boolean;
|
|
21
|
-
open?: boolean;
|
|
22
17
|
};
|
|
23
18
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
24
19
|
close: () => any;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bikariya/image-viewer",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.7",
|
|
5
5
|
"description": "Bikariya image viewer for Nuxt",
|
|
6
6
|
"author": "KazariEX",
|
|
7
7
|
"license": "MIT",
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
"dist"
|
|
16
16
|
],
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@
|
|
19
|
-
"@
|
|
18
|
+
"@nuxt/kit": "^4.3.1",
|
|
19
|
+
"@bikariya/modals": "0.0.7"
|
|
20
20
|
},
|
|
21
21
|
"scripts": {
|
|
22
22
|
"build": "nuxt-module-build build",
|