From 86fa3520e826ce7d5c96d2d5b6f9f1c3494c8419 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=8F=9C=E5=BE=97=E8=AE=A9=E4=BA=BA=E5=8F=91=E6=AF=9B?=
<2328204591@qq.com>
Date: Tue, 25 Nov 2025 14:41:17 +0800
Subject: [PATCH 1/3] =?UTF-8?q?feat(image-viewer):=20=E6=96=B0=E5=A2=9EOIm?=
=?UTF-8?q?ageViewer=EF=BC=88=E5=9B=BE=E7=89=87=E6=8B=96=E6=8B=BD=E7=BC=A9?=
=?UTF-8?q?=E6=94=BE=EF=BC=89=E7=BB=84=E4=BB=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
packages/opendesign/src/figure/provide.ts | 5 +
.../src/image-viewer/OImageViewer.vue | 293 ++++++++++++++++++
packages/opendesign/src/image-viewer/index.ts | 11 +
.../src/image-viewer/style/index.scss | 2 +
.../src/image-viewer/style/index.ts | 2 +
.../src/image-viewer/style/style.scss | 80 +++++
.../image-viewer/style/theme-ascend.index.ts | 3 +
.../src/image-viewer/style/theme-ascend.scss | 1 +
.../image-viewer/style/theme-kunpeng.index.ts | 3 +
.../src/image-viewer/style/theme-kunpeng.scss | 1 +
.../style/theme-openeuler.index.ts | 3 +
.../image-viewer/style/theme-openeuler.scss | 1 +
.../src/image-viewer/style/var.scss | 13 +
packages/opendesign/src/image-viewer/types.ts | 71 +++++
14 files changed, 489 insertions(+)
create mode 100644 packages/opendesign/src/figure/provide.ts
create mode 100644 packages/opendesign/src/image-viewer/OImageViewer.vue
create mode 100644 packages/opendesign/src/image-viewer/index.ts
create mode 100644 packages/opendesign/src/image-viewer/style/index.scss
create mode 100644 packages/opendesign/src/image-viewer/style/index.ts
create mode 100644 packages/opendesign/src/image-viewer/style/style.scss
create mode 100644 packages/opendesign/src/image-viewer/style/theme-ascend.index.ts
create mode 100644 packages/opendesign/src/image-viewer/style/theme-ascend.scss
create mode 100644 packages/opendesign/src/image-viewer/style/theme-kunpeng.index.ts
create mode 100644 packages/opendesign/src/image-viewer/style/theme-kunpeng.scss
create mode 100644 packages/opendesign/src/image-viewer/style/theme-openeuler.index.ts
create mode 100644 packages/opendesign/src/image-viewer/style/theme-openeuler.scss
create mode 100644 packages/opendesign/src/image-viewer/style/var.scss
create mode 100644 packages/opendesign/src/image-viewer/types.ts
diff --git a/packages/opendesign/src/figure/provide.ts b/packages/opendesign/src/figure/provide.ts
new file mode 100644
index 000000000..e8a4e759b
--- /dev/null
+++ b/packages/opendesign/src/figure/provide.ts
@@ -0,0 +1,5 @@
+import { InjectionKey } from 'vue';
+
+export const figureInjectKey: InjectionKey<{
+ updateDraggingStatus: (isDragging: boolean) => void;
+}> = Symbol('provide-figure');
diff --git a/packages/opendesign/src/image-viewer/OImageViewer.vue b/packages/opendesign/src/image-viewer/OImageViewer.vue
new file mode 100644
index 000000000..6ca0e7446
--- /dev/null
+++ b/packages/opendesign/src/image-viewer/OImageViewer.vue
@@ -0,0 +1,293 @@
+
+
+
+
+
![]()
+
+
+
+
{{ zoomRatio }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/opendesign/src/image-viewer/index.ts b/packages/opendesign/src/image-viewer/index.ts
new file mode 100644
index 000000000..f1f767c91
--- /dev/null
+++ b/packages/opendesign/src/image-viewer/index.ts
@@ -0,0 +1,11 @@
+import _OImageViewer from './OImageViewer.vue';
+import type { App } from 'vue';
+
+const OImageViewer = Object.assign(_OImageViewer, {
+ install(app: App) {
+ app.component('OImageViewer', _OImageViewer);
+ },
+});
+
+export { OImageViewer };
+export * from './types';
diff --git a/packages/opendesign/src/image-viewer/style/index.scss b/packages/opendesign/src/image-viewer/style/index.scss
new file mode 100644
index 000000000..b32f7e737
--- /dev/null
+++ b/packages/opendesign/src/image-viewer/style/index.scss
@@ -0,0 +1,2 @@
+@use './var.scss' as *;
+@use './style.scss' as *;
\ No newline at end of file
diff --git a/packages/opendesign/src/image-viewer/style/index.ts b/packages/opendesign/src/image-viewer/style/index.ts
new file mode 100644
index 000000000..786fce9c5
--- /dev/null
+++ b/packages/opendesign/src/image-viewer/style/index.ts
@@ -0,0 +1,2 @@
+import '../../_styles';
+import './index.scss';
diff --git a/packages/opendesign/src/image-viewer/style/style.scss b/packages/opendesign/src/image-viewer/style/style.scss
new file mode 100644
index 000000000..24f0d3351
--- /dev/null
+++ b/packages/opendesign/src/image-viewer/style/style.scss
@@ -0,0 +1,80 @@
+@use '../../_styles/mixin.scss' as *;
+
+.o-image-viewer {
+ position: relative;
+ display: flex;
+ align-items: center;
+}
+
+.o-image-viewer-container {
+ position: relative;
+ user-select: none;
+ will-change: transform;
+}
+
+.o-image-viewer-dragging {
+ cursor: var(--image-viewer-cursor-type);
+}
+
+.o-image-viewer-img {
+ display: block;
+ max-width: 100vw;
+ max-height: 100vh;
+}
+
+.o-image-zoom-ratio {
+ position: absolute;
+ left: 50%;
+ top: 50%;
+ transform: translate3d(-50%, -50%, 0);
+ width: var(--image-viewer-ratio-width);
+ height: var(--image-viewer-ratio-height);
+ line-height: var(--image-viewer-ratio-height);
+ text-align: center;
+ font-weight: 500;
+ color: var(--image-viewer-ratio-color);
+ background-color: var(--image-viewer-ratio-bgc);
+ border-radius: var(--image-viewer-ratio-radius);
+ backdrop-filter: blur(var(--image-viewer-ratio-backdrop-filter));
+ user-select: none;
+}
+
+.o-image-viewer-action {
+ position: absolute;
+ left: 50%;
+ bottom: var(--image-viewer-action-bottom);
+ transform: translate3d(-50%, 0, 0);
+ display: flex;
+ align-items: center;
+ width: fit-content;
+ padding: var(--image-viewer-action-padding);
+ background-color: var(--o-color-white);
+ border-radius: var(--o-radius-m);
+}
+
+.o-image-action-item {
+ cursor: pointer;
+
+ &:not(:first-child) {
+ margin-left: var(--image-viewer-action-item-gap);
+ }
+
+ &:last-child {
+ opacity: 0.8;
+ }
+
+ @include hover {
+ opacity: 1;
+
+ .o-image-action-icon {
+ color: var(--o-color-info1)
+ }
+ }
+}
+
+.o-image-action-icon {
+ display: block;
+ width: var(--o-control_size-s);
+ height: var(--o-control_size-s);
+ color: var(--o-color-info2)
+}
\ No newline at end of file
diff --git a/packages/opendesign/src/image-viewer/style/theme-ascend.index.ts b/packages/opendesign/src/image-viewer/style/theme-ascend.index.ts
new file mode 100644
index 000000000..5bdacd9c6
--- /dev/null
+++ b/packages/opendesign/src/image-viewer/style/theme-ascend.index.ts
@@ -0,0 +1,3 @@
+import '../../_styles';
+import './index.scss';
+import './theme-ascend.scss';
diff --git a/packages/opendesign/src/image-viewer/style/theme-ascend.scss b/packages/opendesign/src/image-viewer/style/theme-ascend.scss
new file mode 100644
index 000000000..e604f805c
--- /dev/null
+++ b/packages/opendesign/src/image-viewer/style/theme-ascend.scss
@@ -0,0 +1 @@
+@use '../../_styles/mixin.scss' as *;
\ No newline at end of file
diff --git a/packages/opendesign/src/image-viewer/style/theme-kunpeng.index.ts b/packages/opendesign/src/image-viewer/style/theme-kunpeng.index.ts
new file mode 100644
index 000000000..c2b4508ff
--- /dev/null
+++ b/packages/opendesign/src/image-viewer/style/theme-kunpeng.index.ts
@@ -0,0 +1,3 @@
+import '../../_styles';
+import './index.scss';
+import './theme-kunpeng.scss';
diff --git a/packages/opendesign/src/image-viewer/style/theme-kunpeng.scss b/packages/opendesign/src/image-viewer/style/theme-kunpeng.scss
new file mode 100644
index 000000000..e604f805c
--- /dev/null
+++ b/packages/opendesign/src/image-viewer/style/theme-kunpeng.scss
@@ -0,0 +1 @@
+@use '../../_styles/mixin.scss' as *;
\ No newline at end of file
diff --git a/packages/opendesign/src/image-viewer/style/theme-openeuler.index.ts b/packages/opendesign/src/image-viewer/style/theme-openeuler.index.ts
new file mode 100644
index 000000000..5a4690a05
--- /dev/null
+++ b/packages/opendesign/src/image-viewer/style/theme-openeuler.index.ts
@@ -0,0 +1,3 @@
+import '../../_styles';
+import './index.scss';
+import './theme-openeuler.scss';
diff --git a/packages/opendesign/src/image-viewer/style/theme-openeuler.scss b/packages/opendesign/src/image-viewer/style/theme-openeuler.scss
new file mode 100644
index 000000000..e604f805c
--- /dev/null
+++ b/packages/opendesign/src/image-viewer/style/theme-openeuler.scss
@@ -0,0 +1 @@
+@use '../../_styles/mixin.scss' as *;
\ No newline at end of file
diff --git a/packages/opendesign/src/image-viewer/style/var.scss b/packages/opendesign/src/image-viewer/style/var.scss
new file mode 100644
index 000000000..57418865e
--- /dev/null
+++ b/packages/opendesign/src/image-viewer/style/var.scss
@@ -0,0 +1,13 @@
+.o-image-viewer {
+ --image-viewer-ratio-width: 82px;
+ --image-viewer-ratio-height: 24px;
+ --image-viewer-ratio-bgc: var(--o-color-mask2);
+ --image-viewer-ratio-color: var(--o-color-white);
+ --image-viewer-ratio-radius: var(--o-radius-xs);
+ --image-viewer-ratio-backdrop-filter: 4px;
+
+ --image-viewer-action-bottom: 72px;
+ --image-viewer-action-padding: 16px 24px;
+ --image-viewer-action-item-gap: 40px;
+ --image-viewer-cursor-type: move;
+}
\ No newline at end of file
diff --git a/packages/opendesign/src/image-viewer/types.ts b/packages/opendesign/src/image-viewer/types.ts
new file mode 100644
index 000000000..c1ee41e63
--- /dev/null
+++ b/packages/opendesign/src/image-viewer/types.ts
@@ -0,0 +1,71 @@
+import { ExtractPropTypes, PropType } from 'vue';
+
+export type ImageViewerAction = 'zoomIn' | 'zoomOut';
+
+export const imageViewerProps = {
+ /**
+ * @zh-CN 预览资源组
+ * @en-US Preview Resource Group.
+ */
+ previewList: {
+ type: Array as PropType>,
+ default: () => [],
+ },
+ /**
+ * @zh-CN 预览图片缩放的速率
+ * @en-US Preview the rate of image zooming.
+ */
+ zoomRate: {
+ type: Number,
+ default: 1.2,
+ },
+ /**
+ * @zh-CN 预览图片最小缩放比例
+ * @en-US Minimum zoom ratio for preview images.
+ */
+ minScale: {
+ type: Number,
+ default: 0.1,
+ },
+ /**
+ * @zh-CN 预览图片最大缩放比例
+ * @en-US Maximum zoom ratio for preview images.
+ */
+ maxScale: {
+ type: Number,
+ default: 8,
+ },
+ /**
+ * @zh-CN 展示预览图片实际缩放百分比
+ * @en-US Show the actual zoom percentage of the preview image.
+ */
+ showZoomRatio: {
+ type: Boolean,
+ default: true,
+ },
+ /**
+ * @zh-CN 展示预览图片实际缩放百分比的持续时间
+ * @en-US Show the duration of the actual zoom percentage of the preview image.
+ */
+ duration: {
+ type: Number,
+ default: 500,
+ },
+ /**
+ * @zh-CN 展示预览操作区域
+ * @en-US Display the preview operation area.
+ */
+ showActionArea: {
+ type: Boolean,
+ default: true,
+ },
+ /**
+ * @zh-CN 预览组起始预览图片的下标
+ * @en-US The index of the preview group's initial preview image.
+ */
+ initialIndex: {
+ type: Number,
+ default: 0,
+ },
+};
+export type ImageViewerPropsT = ExtractPropTypes;
--
Gitee
From d32a6b7ed52ccdff33784b461f697d39879b4c9a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=8F=9C=E5=BE=97=E8=AE=A9=E4=BA=BA=E5=8F=91=E6=AF=9B?=
<2328204591@qq.com>
Date: Tue, 25 Nov 2025 14:46:34 +0800
Subject: [PATCH 2/3] =?UTF-8?q?feat(figure):=20figure=E7=BB=84=E4=BB=B6?=
=?UTF-8?q?=E9=80=82=E9=85=8DOImageViewer=E7=BB=84=E4=BB=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
packages/opendesign/src/figure/OFigure.vue | 49 +++++++++++++++++--
packages/opendesign/src/figure/style/index.ts | 1 +
.../opendesign/src/figure/style/media.scss | 6 +++
.../opendesign/src/figure/style/style.scss | 4 ++
packages/opendesign/src/figure/types.ts | 2 +
5 files changed, 58 insertions(+), 4 deletions(-)
diff --git a/packages/opendesign/src/figure/OFigure.vue b/packages/opendesign/src/figure/OFigure.vue
index 5ef23e773..2479886c9 100644
--- a/packages/opendesign/src/figure/OFigure.vue
+++ b/packages/opendesign/src/figure/OFigure.vue
@@ -1,13 +1,15 @@
+
+ 基本
+
+
+
diff --git a/packages/opendesign/src/image-viewer/__demo__/ImageViewerInFigure.vue b/packages/opendesign/src/image-viewer/__demo__/ImageViewerInFigure.vue
new file mode 100644
index 000000000..8ee782857
--- /dev/null
+++ b/packages/opendesign/src/image-viewer/__demo__/ImageViewerInFigure.vue
@@ -0,0 +1,33 @@
+
+
+ 搭配figure使用
+
+
+
diff --git a/packages/opendesign/src/image-viewer/__demo__/ImageViewerInLayer.vue b/packages/opendesign/src/image-viewer/__demo__/ImageViewerInLayer.vue
new file mode 100644
index 000000000..240df07d8
--- /dev/null
+++ b/packages/opendesign/src/image-viewer/__demo__/ImageViewerInLayer.vue
@@ -0,0 +1,42 @@
+
+
+ 搭配layer使用
+
+
+
diff --git a/packages/opendesign/src/image-viewer/__demo__/TheIndex.vue b/packages/opendesign/src/image-viewer/__demo__/TheIndex.vue
new file mode 100644
index 000000000..e7eb23268
--- /dev/null
+++ b/packages/opendesign/src/image-viewer/__demo__/TheIndex.vue
@@ -0,0 +1,29 @@
+
+
+
+
+
切换demo
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/portal/src/router.ts b/packages/portal/src/router.ts
index 657cae2a4..1e94e1067 100644
--- a/packages/portal/src/router.ts
+++ b/packages/portal/src/router.ts
@@ -388,6 +388,14 @@ export const routes = [
title: '骨架屏 Skeleton',
},
},
+ {
+ path: '/image-viewer',
+ name: 'ImageViewer',
+ component: () => import('@opendesign-src/image-viewer/__demo__/TheIndex.vue'),
+ meta: {
+ title: '图片形变 ImageViewer',
+ },
+ },
{
path: '/resize-observer',
name: 'ResizeObserver',
--
Gitee