@veltra/desktop 1.7.8 → 1.7.10
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/components/batch-edit/batch-edit-form.js +7 -3
- package/dist/components/batch-edit/batch-edit-form.js.map +1 -1
- package/dist/components/batch-edit/batch-edit.js +1 -0
- package/dist/components/batch-edit/batch-edit.js.map +1 -1
- package/dist/components/batch-edit/use-edit-state.js.map +1 -1
- package/dist/components/form/form.js.map +1 -1
- package/dist/components/form/form.vue_vue_type_script_setup_true_lang.js +31 -6
- package/dist/components/form/form.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/form/is-field-modified.js +12 -0
- package/dist/components/form/is-field-modified.js.map +1 -0
- package/dist/components/form/style2.css +37 -1
- package/dist/components/form/use-form-fields.js +11 -6
- package/dist/components/form/use-form-fields.js.map +1 -1
- package/dist/components/form-item/form-item.js.map +1 -1
- package/dist/components/form-item/form-item.vue_vue_type_script_setup_true_lang.js +18 -5
- package/dist/components/form-item/form-item.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/image-cropper/draw-crop.js +63 -0
- package/dist/components/image-cropper/draw-crop.js.map +1 -0
- package/dist/components/image-cropper/image-cropper.js +344 -0
- package/dist/components/image-cropper/image-cropper.js.map +1 -0
- package/dist/components/image-cropper/style.d.ts +1 -0
- package/dist/components/image-cropper/style.js +1 -0
- package/dist/components/image-cropper/style2.css +205 -0
- package/dist/components/image-cropper/use-image-loader.js +59 -0
- package/dist/components/image-cropper/use-image-loader.js.map +1 -0
- package/dist/components/image-cropper/use-preview.js +44 -0
- package/dist/components/image-cropper/use-preview.js.map +1 -0
- package/dist/components/image-cropper/use-selection.js +183 -0
- package/dist/components/image-cropper/use-selection.js.map +1 -0
- package/dist/components/image-cropper/use-transform.js +182 -0
- package/dist/components/image-cropper/use-transform.js.map +1 -0
- package/dist/components/index.d.ts +2 -1
- package/dist/components/index.js +3 -1
- package/dist/components/index.js.map +1 -1
- package/dist/index.d.ts +47 -45
- package/dist/index.js +46 -45
- package/dist/types/batch-edit.d.ts +2 -0
- package/dist/types/form-item.d.ts +4 -1
- package/dist/types/form.d.ts +10 -1
- package/dist/types/image-cropper.d.ts +68 -0
- package/dist/types/index.d.ts +2 -1
- package/package.json +6 -6
- package/src/components/auto-complete/style.scss +3 -15
- package/src/components/batch-edit/__test__/batch-edit.test.ts +138 -0
- package/src/components/batch-edit/batch-edit-form.vue +18 -4
- package/src/components/batch-edit/use-edit-state.ts +1 -1
- package/src/components/contextmenu/style.scss +4 -20
- package/src/components/form/__test__/form.test.ts +80 -0
- package/src/components/form/__test__/is-field-modified.test.ts +37 -0
- package/src/components/form/form.vue +28 -4
- package/src/components/form/is-field-modified.ts +16 -0
- package/src/components/form/style.scss +53 -2
- package/src/components/form/use-form-fields.ts +20 -6
- package/src/components/form-item/__test__/form-item.test.ts +90 -0
- package/src/components/form-item/form-item.vue +42 -7
- package/src/components/image-cropper/__test__/draw-crop.test.ts +131 -0
- package/src/components/image-cropper/__test__/image-cropper.test.ts +744 -0
- package/src/components/image-cropper/__test__/use-transform.test.ts +229 -0
- package/src/components/image-cropper/draw-crop.ts +112 -0
- package/src/components/image-cropper/image-cropper.vue +302 -0
- package/src/components/image-cropper/index.ts +1 -0
- package/src/components/image-cropper/style.scss +232 -0
- package/src/components/image-cropper/style.ts +1 -0
- package/src/components/image-cropper/use-image-loader.ts +79 -0
- package/src/components/image-cropper/use-preview.ts +58 -0
- package/src/components/image-cropper/use-selection.ts +255 -0
- package/src/components/image-cropper/use-transform.ts +256 -0
- package/src/components/index.ts +2 -0
- package/src/components/select/style.scss +3 -15
- package/src/types/batch-edit.ts +2 -0
- package/src/types/form-item.ts +4 -1
- package/src/types/form.ts +10 -2
- package/src/types/image-cropper.ts +73 -0
- package/src/types/index.ts +1 -0
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import { onBeforeUnmount, reactive, watch, type Ref, type ShallowRef } from 'vue'
|
|
2
|
+
|
|
3
|
+
/** 图片变换状态:缩放 / 平移 / 90° 步进旋转 / 翻转 */
|
|
4
|
+
export interface TransformState {
|
|
5
|
+
scale: number
|
|
6
|
+
translateX: number
|
|
7
|
+
translateY: number
|
|
8
|
+
/** 90° 步进角度:0 / 90 / 180 / 270 */
|
|
9
|
+
rotation: number
|
|
10
|
+
flipX: boolean
|
|
11
|
+
flipY: boolean
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface Size {
|
|
15
|
+
width: number
|
|
16
|
+
height: number
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** 画布内的屏幕坐标点(相对画布左上角) */
|
|
20
|
+
interface Point {
|
|
21
|
+
x: number
|
|
22
|
+
y: number
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** 滚轮 / 按钮单次缩放步进系数 */
|
|
26
|
+
const ZOOM_STEP = 1.2
|
|
27
|
+
/** 最大缩放倍数(相对适应容器的缩放) */
|
|
28
|
+
const MAX_ZOOM_RATIO = 10
|
|
29
|
+
|
|
30
|
+
interface UseTransformOptions {
|
|
31
|
+
/** 画布元素(wheel 缩放与选区外平移的交互目标) */
|
|
32
|
+
target: ShallowRef<HTMLElement | undefined | null> | Ref<HTMLElement | undefined | null>
|
|
33
|
+
/** 画布可视尺寸(屏幕像素) */
|
|
34
|
+
canvasSize: () => Size
|
|
35
|
+
/** 图片原始宽(图片像素) */
|
|
36
|
+
imageWidth: () => number
|
|
37
|
+
/** 图片原始高(图片像素) */
|
|
38
|
+
imageHeight: () => number
|
|
39
|
+
/** 重置变换时复位选区 */
|
|
40
|
+
onReset: () => void
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
interface UseTransformReturn {
|
|
44
|
+
/** 当前变换状态 */
|
|
45
|
+
transform: TransformState
|
|
46
|
+
/** 图片按比例适应容器并居中(按当前旋转交换宽高计算) */
|
|
47
|
+
fit: () => void
|
|
48
|
+
/** 复位变换状态(不重新布局、不复位选区) */
|
|
49
|
+
reset: () => void
|
|
50
|
+
/** 重置:恢复初始变换,重新适应容器并复位选区 */
|
|
51
|
+
resetTransform: () => void
|
|
52
|
+
/** 放大一级,anchor 为缩放锚点(默认画布中心) */
|
|
53
|
+
zoomIn: (anchor?: Point) => void
|
|
54
|
+
/** 缩小一级,anchor 为缩放锚点(默认画布中心) */
|
|
55
|
+
zoomOut: (anchor?: Point) => void
|
|
56
|
+
/** 缩放到指定值(按适应缩放钳制范围),anchor 为缩放锚点(默认画布中心) */
|
|
57
|
+
zoomTo: (scale: number, anchor?: Point) => void
|
|
58
|
+
/** 90° 步进旋转,direction 为 1 顺时针、-1 逆时针 */
|
|
59
|
+
rotate: (direction: 1 | -1) => void
|
|
60
|
+
/** 水平 / 垂直翻转 */
|
|
61
|
+
flip: (axis: 'horizontal' | 'vertical') => void
|
|
62
|
+
/** 屏幕位移换算为图片像素位移(考虑旋转 / 翻转 / 缩放) */
|
|
63
|
+
toImageDelta: (dx: number, dy: number) => Point
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* 图片变换:滚轮以指针为锚缩放、选区外拖动平移、90° 步进旋转、翻转与重置。
|
|
68
|
+
* 舞台 transform-origin 为中心,旋转 / 翻转不改变图片中心位置,无需补偿平移
|
|
69
|
+
*/
|
|
70
|
+
export function useTransform(options: UseTransformOptions): UseTransformReturn {
|
|
71
|
+
const { target, canvasSize, imageWidth, imageHeight, onReset } = options
|
|
72
|
+
|
|
73
|
+
const transform = reactive<TransformState>({
|
|
74
|
+
scale: 1,
|
|
75
|
+
translateX: 0,
|
|
76
|
+
translateY: 0,
|
|
77
|
+
rotation: 0,
|
|
78
|
+
flipX: false,
|
|
79
|
+
flipY: false
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
/** 当前旋转下的显示尺寸(90° / 270° 交换宽高,图片像素) */
|
|
83
|
+
function displaySize(): Size {
|
|
84
|
+
const width = imageWidth()
|
|
85
|
+
const height = imageHeight()
|
|
86
|
+
return transform.rotation % 180 === 0 ? { width, height } : { width: height, height: width }
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** 适应容器的缩放(同时是缩放范围下限) */
|
|
90
|
+
function fitScale() {
|
|
91
|
+
const { width: cw, height: ch } = canvasSize()
|
|
92
|
+
const { width: dw, height: dh } = displaySize()
|
|
93
|
+
if (!cw || !ch || !dw || !dh) return 0
|
|
94
|
+
return Math.min(cw / dw, ch / dh)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function fit() {
|
|
98
|
+
const scale = fitScale()
|
|
99
|
+
if (!scale) return
|
|
100
|
+
const { width: cw, height: ch } = canvasSize()
|
|
101
|
+
transform.scale = scale
|
|
102
|
+
// transform-origin 为舞台中心,居中平移只取决于舞台原始尺寸,与缩放 / 旋转无关
|
|
103
|
+
transform.translateX = (cw - imageWidth()) / 2
|
|
104
|
+
transform.translateY = (ch - imageHeight()) / 2
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function reset() {
|
|
108
|
+
transform.scale = 1
|
|
109
|
+
transform.translateX = 0
|
|
110
|
+
transform.translateY = 0
|
|
111
|
+
transform.rotation = 0
|
|
112
|
+
transform.flipX = false
|
|
113
|
+
transform.flipY = false
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function resetTransform() {
|
|
117
|
+
reset()
|
|
118
|
+
fit()
|
|
119
|
+
onReset()
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function zoomTo(scale: number, anchor?: Point) {
|
|
123
|
+
const base = fitScale()
|
|
124
|
+
if (!base) return
|
|
125
|
+
const next = Math.min(Math.max(scale, base), base * MAX_ZOOM_RATIO)
|
|
126
|
+
const { width: cw, height: ch } = canvasSize()
|
|
127
|
+
const { x: ax, y: ay } = anchor ?? { x: cw / 2, y: ch / 2 }
|
|
128
|
+
// 舞台中心(transform-origin)局部坐标
|
|
129
|
+
const cx = imageWidth() / 2
|
|
130
|
+
const cy = imageHeight() / 2
|
|
131
|
+
const k = next / transform.scale
|
|
132
|
+
// 缩放前后锚点下的图片点保持不动:t' = A - C - k·(A - t - C)
|
|
133
|
+
transform.translateX = ax - cx - k * (ax - transform.translateX - cx)
|
|
134
|
+
transform.translateY = ay - cy - k * (ay - transform.translateY - cy)
|
|
135
|
+
transform.scale = next
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function zoomIn(anchor?: Point) {
|
|
139
|
+
zoomTo(transform.scale * ZOOM_STEP, anchor)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function zoomOut(anchor?: Point) {
|
|
143
|
+
zoomTo(transform.scale / ZOOM_STEP, anchor)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function rotate(direction: 1 | -1) {
|
|
147
|
+
transform.rotation = (transform.rotation + direction * 90 + 360) % 360
|
|
148
|
+
// 90° / 270° 后按交换宽高重新适应布局
|
|
149
|
+
fit()
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function flip(axis: 'horizontal' | 'vertical') {
|
|
153
|
+
if (axis === 'horizontal') transform.flipX = !transform.flipX
|
|
154
|
+
else transform.flipY = !transform.flipY
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function toImageDelta(dx: number, dy: number): Point {
|
|
158
|
+
// 先按旋转逆变换,再除掉带翻转符号的缩放
|
|
159
|
+
let x = dx
|
|
160
|
+
let y = dy
|
|
161
|
+
if (transform.rotation === 90) {
|
|
162
|
+
x = dy
|
|
163
|
+
y = -dx
|
|
164
|
+
} else if (transform.rotation === 180) {
|
|
165
|
+
x = -dx
|
|
166
|
+
y = -dy
|
|
167
|
+
} else if (transform.rotation === 270) {
|
|
168
|
+
x = -dy
|
|
169
|
+
y = dx
|
|
170
|
+
}
|
|
171
|
+
return {
|
|
172
|
+
x: x / ((transform.flipX ? -1 : 1) * transform.scale),
|
|
173
|
+
y: y / ((transform.flipY ? -1 : 1) * transform.scale)
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// ---------- wheel 缩放(以指针位置为锚点) ----------
|
|
178
|
+
|
|
179
|
+
function handleWheel(e: WheelEvent) {
|
|
180
|
+
e.preventDefault()
|
|
181
|
+
const el = target.value
|
|
182
|
+
if (!el) return
|
|
183
|
+
const rect = el.getBoundingClientRect()
|
|
184
|
+
const anchor = { x: e.clientX - rect.left, y: e.clientY - rect.top }
|
|
185
|
+
if (e.deltaY < 0) zoomIn(anchor)
|
|
186
|
+
else zoomOut(anchor)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// ---------- 选区外拖动平移(选区内拖动由 use-selection 拦截,不冒泡到这里) ----------
|
|
190
|
+
|
|
191
|
+
/** 图片显示尺寸超出容器才允许平移 */
|
|
192
|
+
function isOverflowing() {
|
|
193
|
+
const { width: cw, height: ch } = canvasSize()
|
|
194
|
+
const { width: dw, height: dh } = displaySize()
|
|
195
|
+
return dw * transform.scale > cw || dh * transform.scale > ch
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
let panStart: Point | null = null
|
|
199
|
+
|
|
200
|
+
function handleMousedown(e: MouseEvent) {
|
|
201
|
+
if (e.button !== 0 || !isOverflowing()) return
|
|
202
|
+
e.preventDefault()
|
|
203
|
+
|
|
204
|
+
panStart = { x: e.clientX, y: e.clientY }
|
|
205
|
+
document.addEventListener('mousemove', handleMousemove, { passive: true })
|
|
206
|
+
document.addEventListener('mouseup', handleMouseup)
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function handleMousemove(e: MouseEvent) {
|
|
210
|
+
if (!panStart) return
|
|
211
|
+
transform.translateX += e.clientX - panStart.x
|
|
212
|
+
transform.translateY += e.clientY - panStart.y
|
|
213
|
+
panStart = { x: e.clientX, y: e.clientY }
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function handleMouseup() {
|
|
217
|
+
panStart = null
|
|
218
|
+
cleanup()
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function cleanup() {
|
|
222
|
+
document.removeEventListener('mousemove', handleMousemove)
|
|
223
|
+
document.removeEventListener('mouseup', handleMouseup)
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
watch(
|
|
227
|
+
target,
|
|
228
|
+
(el, oldEl) => {
|
|
229
|
+
oldEl?.removeEventListener('mousedown', handleMousedown)
|
|
230
|
+
oldEl?.removeEventListener('wheel', handleWheel)
|
|
231
|
+
el?.addEventListener('mousedown', handleMousedown)
|
|
232
|
+
// wheel 需要 preventDefault 阻止页面滚动,必须非 passive
|
|
233
|
+
el?.addEventListener('wheel', handleWheel, { passive: false })
|
|
234
|
+
},
|
|
235
|
+
{ immediate: true }
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
onBeforeUnmount(() => {
|
|
239
|
+
target.value?.removeEventListener('mousedown', handleMousedown)
|
|
240
|
+
target.value?.removeEventListener('wheel', handleWheel)
|
|
241
|
+
cleanup()
|
|
242
|
+
})
|
|
243
|
+
|
|
244
|
+
return {
|
|
245
|
+
transform,
|
|
246
|
+
fit,
|
|
247
|
+
reset,
|
|
248
|
+
resetTransform,
|
|
249
|
+
zoomIn,
|
|
250
|
+
zoomOut,
|
|
251
|
+
zoomTo,
|
|
252
|
+
rotate,
|
|
253
|
+
flip,
|
|
254
|
+
toImageDelta
|
|
255
|
+
}
|
|
256
|
+
}
|
package/src/components/index.ts
CHANGED
|
@@ -63,16 +63,8 @@ $root-name: select;
|
|
|
63
63
|
@include m.ellipsis;
|
|
64
64
|
|
|
65
65
|
&:hover {
|
|
66
|
-
background-color: fn.component-var(
|
|
67
|
-
|
|
68
|
-
option-hover-bg,
|
|
69
|
-
fn.use-var(bg-color, hover)
|
|
70
|
-
);
|
|
71
|
-
color: fn.component-var(
|
|
72
|
-
select,
|
|
73
|
-
option-hover-color,
|
|
74
|
-
fn.use-var(text-color, title)
|
|
75
|
-
);
|
|
66
|
+
background-color: fn.component-var(select, option-hover-bg, fn.use-var(bg-color, hover));
|
|
67
|
+
color: fn.component-var(select, option-hover-color, fn.use-var(text-color, title));
|
|
76
68
|
}
|
|
77
69
|
|
|
78
70
|
@include m.is(selected) {
|
|
@@ -82,11 +74,7 @@ $root-name: select;
|
|
|
82
74
|
option-selected-bg,
|
|
83
75
|
fn.use-var(color, primary, light-9)
|
|
84
76
|
);
|
|
85
|
-
color: fn.component-var(
|
|
86
|
-
select,
|
|
87
|
-
option-selected-color,
|
|
88
|
-
fn.use-var(color, primary)
|
|
89
|
-
);
|
|
77
|
+
color: fn.component-var(select, option-selected-color, fn.use-var(color, primary));
|
|
90
78
|
font-weight: 600;
|
|
91
79
|
|
|
92
80
|
&::before {
|
package/src/types/batch-edit.ts
CHANGED
|
@@ -115,6 +115,8 @@ export interface BatchEditProps extends TableProps {
|
|
|
115
115
|
|
|
116
116
|
/** 批量编辑组件定义的事件 */
|
|
117
117
|
export interface BatchEditEmits extends TableEmits {
|
|
118
|
+
/** 表单控件 change,透传自 UForm */
|
|
119
|
+
(e: 'field:change', field: string, ...args: any[]): void
|
|
118
120
|
/** 更新数据 */
|
|
119
121
|
(e: 'update:data', value: Record<string, any>[]): void
|
|
120
122
|
/** 点击底部「新增一行」 */
|
package/src/types/form-item.ts
CHANGED
|
@@ -9,7 +9,10 @@ export interface FormItemProps extends FormComponentProps {
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
/** 组件项组件定义的事件 */
|
|
12
|
-
export interface FormItemEmits {
|
|
12
|
+
export interface FormItemEmits {
|
|
13
|
+
/** 内部控件 change,参数与控件一致 */
|
|
14
|
+
(e: 'change', ...args: any[]): void
|
|
15
|
+
}
|
|
13
16
|
|
|
14
17
|
/** 组件项组件暴露的属性和方法 */
|
|
15
18
|
export interface FormItemExposed {}
|
package/src/types/form.ts
CHANGED
|
@@ -10,7 +10,12 @@ export interface FormProps extends ComponentProps {
|
|
|
10
10
|
cols?: number
|
|
11
11
|
/** 表单数据 */
|
|
12
12
|
model?: Record<string, any>
|
|
13
|
-
|
|
13
|
+
/** 开启后,字段当前值与基准值不同时,在控件下方展示「变更前」 */
|
|
14
|
+
showModified?: boolean
|
|
15
|
+
/** 「变更前」标签文案,默认「变更前:」 */
|
|
16
|
+
modifiedLabel?: string
|
|
17
|
+
/** 变更前基准数据;未传时回退到 model 引用首次传入时的快照(与 reset 一致) */
|
|
18
|
+
initialModel?: Record<string, any>
|
|
14
19
|
/** 表单项label宽度 */
|
|
15
20
|
labelWidth?: string | number
|
|
16
21
|
/** 表单项 label 位置 */
|
|
@@ -24,7 +29,10 @@ export interface FormProps extends ComponentProps {
|
|
|
24
29
|
}
|
|
25
30
|
|
|
26
31
|
export interface FormEmits {
|
|
27
|
-
|
|
32
|
+
/** 控件 change 事件,仅用户操作触发 */
|
|
33
|
+
(e: 'field:change', field: string, ...args: any[]): void
|
|
34
|
+
/** model 字段值更新,含编程写入 */
|
|
35
|
+
(e: 'field:update', field: string, value: any): void
|
|
28
36
|
}
|
|
29
37
|
|
|
30
38
|
export interface _FormExposed {
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { DeconstructValue } from '@veltra/utils'
|
|
2
|
+
|
|
3
|
+
/** 图片裁剪组件属性 */
|
|
4
|
+
export interface ImageCropperProps {
|
|
5
|
+
/** 图片源:File / Blob / URL */
|
|
6
|
+
src?: File | Blob | string
|
|
7
|
+
/** 选区宽高比,不传为自由比例 */
|
|
8
|
+
aspectRatio?: number
|
|
9
|
+
/** 是否显示工具栏 */
|
|
10
|
+
showToolbar?: boolean
|
|
11
|
+
/** 是否显示预览区 */
|
|
12
|
+
showPreview?: boolean
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** getResult 输出尺寸:缺省维度按选区比例推算,都不传则为原图选区像素尺寸 */
|
|
16
|
+
export interface ImageCropperResultOptions {
|
|
17
|
+
/** 目标输出宽度(像素) */
|
|
18
|
+
width?: number
|
|
19
|
+
/** 目标输出高度(像素) */
|
|
20
|
+
height?: number
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** getResult 裁剪结果 */
|
|
24
|
+
export interface ImageCropperResult {
|
|
25
|
+
/** 裁剪图像 Blob(image/png) */
|
|
26
|
+
blob: Blob
|
|
27
|
+
/** 裁剪图像的 dataURL(data:image/png;base64,...),可直接用于 img.src */
|
|
28
|
+
base64: string
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** 裁剪选区(图片像素坐标) */
|
|
32
|
+
export interface ImageCropperSelection {
|
|
33
|
+
x: number
|
|
34
|
+
y: number
|
|
35
|
+
width: number
|
|
36
|
+
height: number
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** 影响裁剪输出的图片变换(缩放 / 平移只影响画布展示,不在其列) */
|
|
40
|
+
export interface ImageCropperCropTransform {
|
|
41
|
+
/** 90° 步进角度:0 / 90 / 180 / 270 */
|
|
42
|
+
rotation: number
|
|
43
|
+
/** 水平翻转 */
|
|
44
|
+
flipX: boolean
|
|
45
|
+
/** 垂直翻转 */
|
|
46
|
+
flipY: boolean
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** 裁剪变化事件载荷 */
|
|
50
|
+
export interface ImageCropperChangePayload {
|
|
51
|
+
/** 当前选区(图片像素坐标) */
|
|
52
|
+
selection: ImageCropperSelection
|
|
53
|
+
/** 影响输出的图片变换摘要,与 getResult 应用的一致 */
|
|
54
|
+
transform: ImageCropperCropTransform
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** 图片裁剪组件定义的事件 */
|
|
58
|
+
export interface ImageCropperEmits {
|
|
59
|
+
/** 选区或图片变换变化时触发 */
|
|
60
|
+
(e: 'crop-change', payload: ImageCropperChangePayload): void
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** 图片裁剪组件暴露的属性和方法(组件内部使用) */
|
|
64
|
+
export interface _ImageCropperExposed {
|
|
65
|
+
/**
|
|
66
|
+
* 输出当前选区裁剪结果:默认按原图选区像素,可传目标宽 / 高缩放输出。
|
|
67
|
+
* 图片未加载 / 无选区、或跨域图片污染画布时 Promise 拒绝,不静默失败
|
|
68
|
+
*/
|
|
69
|
+
getResult: (options?: ImageCropperResultOptions) => Promise<ImageCropperResult>
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** 图片裁剪组件暴露的属性和方法(组件外部使用, 引用的值会被自动解构) */
|
|
73
|
+
export type ImageCropperExposed = DeconstructValue<_ImageCropperExposed>
|
package/src/types/index.ts
CHANGED