@10yun/cv-mobile-ui 0.5.62 → 0.5.63

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.
Files changed (67) hide show
  1. package/package.json +1 -1
  2. package/plugins/uni-extend.js +10 -10
  3. package/ui-fireui/components/u-action-sheet/u-action-sheet.vue +46 -16
  4. package/ui-fireui/components/u-alert/u-alert.vue +11 -5
  5. package/ui-fireui/components/u-badge/u-badge.vue +52 -69
  6. package/ui-fireui/components/u-bottom-navigation/u-bottom-navigation.vue +28 -20
  7. package/ui-fireui/components/u-bottom-popup/u-bottom-popup.vue +40 -11
  8. package/ui-fireui/components/u-bubble-popup/u-bubble-popup.vue +3 -6
  9. package/ui-fireui/components/u-button/u-button.vue +262 -259
  10. package/ui-fireui/components/u-calendar/u-calendar.vue +227 -44
  11. package/ui-fireui/components/u-calendar/u-calendar2.js +562 -0
  12. package/ui-fireui/components/u-card/u-card.vue +50 -32
  13. package/ui-fireui/components/u-cascade-selection/u-cascade-selection.vue +197 -74
  14. package/ui-fireui/components/u-circular-progress/u-circular-progress.vue +324 -0
  15. package/ui-fireui/components/u-clipboard2/tui-clipboard.js +53 -0
  16. package/ui-fireui/components/u-collapse/u-collapse.vue +8 -8
  17. package/ui-fireui/components/u-config/index.js +129 -0
  18. package/ui-fireui/components/u-count-down/u-count-down.vue +124 -19
  19. package/ui-fireui/components/u-datetime/u-datetime.vue +416 -176
  20. package/ui-fireui/components/u-divider/u-divider.vue +3 -3
  21. package/ui-fireui/components/u-drawer/u-drawer.vue +55 -12
  22. package/ui-fireui/components/u-dropdown-list/u-dropdown-list.vue +103 -0
  23. package/ui-fireui/components/u-fab/u-fab.vue +344 -0
  24. package/ui-fireui/components/u-footer/u-footer.vue +148 -0
  25. package/ui-fireui/components/u-grid/u-grid.vue +2 -8
  26. package/ui-fireui/components/u-grid-item/u-grid-item.vue +22 -5
  27. package/ui-fireui/components/u-icon/u-icon-new.js +190 -0
  28. package/ui-fireui/components/u-icon/u-icon-new.vue +100 -0
  29. package/ui-fireui/components/u-image-cropper/u-image-cropper.vue +1144 -0
  30. package/ui-fireui/components/u-image-group/u-image-group.vue +164 -0
  31. package/ui-fireui/components/u-keyboard/u-keyboard.vue +3 -2
  32. package/ui-fireui/components/u-keyboard-input/u-keyboard-input.vue +1 -1
  33. package/ui-fireui/components/u-list-cell/u-list-cell.vue +82 -72
  34. package/ui-fireui/components/u-list-view/u-list-view.vue +33 -8
  35. package/ui-fireui/components/u-loading/u-loading.vue +107 -27
  36. package/ui-fireui/components/u-loadmore/u-loadmore.vue +21 -3
  37. package/ui-fireui/components/u-modal/u-modal.vue +140 -176
  38. package/ui-fireui/components/u-navigation-bar/u-navigation-bar.vue +121 -28
  39. package/ui-fireui/components/u-no-data/u-no-data.vue +58 -20
  40. package/ui-fireui/components/u-nomore/u-nomore.vue +5 -4
  41. package/ui-fireui/components/u-numberbox/u-numberbox.vue +88 -45
  42. package/ui-fireui/components/u-picture-cropper/u-picture-cropper.vue +94 -36
  43. package/ui-fireui/components/u-picture-cropper/u-picture-cropper.wxs +27 -17
  44. package/ui-fireui/components/u-rate/u-rate.vue +197 -0
  45. package/ui-fireui/components/u-round-progress/u-round-progress.vue +62 -42
  46. package/ui-fireui/components/u-scroll-top/u-scroll-top.vue +4 -3
  47. package/ui-fireui/components/u-section/u-section.vue +149 -0
  48. package/ui-fireui/components/u-skeleton/u-skeleton.vue +37 -6
  49. package/ui-fireui/components/u-steps/u-steps.vue +110 -27
  50. package/ui-fireui/components/u-sticky/u-sticky.vue +35 -21
  51. package/ui-fireui/components/u-sticky-wxs/u-sticky-wxs.vue +7 -4
  52. package/ui-fireui/components/u-sticky-wxs/u-sticky.wxs +39 -36
  53. package/ui-fireui/components/u-swipe-action/u-swipe-action.vue +76 -19
  54. package/ui-fireui/components/u-tabbar/u-tabbar.vue +71 -38
  55. package/ui-fireui/components/u-tabs/u-tabs.vue +133 -51
  56. package/ui-fireui/components/u-tag/u-tag.vue +109 -226
  57. package/ui-fireui/components/u-time-axis/u-time-axis.vue +1 -1
  58. package/ui-fireui/components/u-timeaxis-item/u-timeaxis-item.vue +1 -1
  59. package/ui-fireui/components/u-tips/u-tips.vue +35 -15
  60. package/ui-fireui/components/u-toast/u-toast.vue +9 -5
  61. package/ui-fireui/components/u-top-dropdown/u-top-dropdown.vue +8 -6
  62. package/ui-fireui/components/u-upload/u-upload-old.vue +462 -0
  63. package/ui-fireui/components/u-upload/u-upload.vue +648 -446
  64. package/ui-fireui/components/u-white-space/u-white-space.vue +68 -0
  65. package/ui-fireui/components/u-wing-blank/u-wing-blank.vue +100 -0
  66. package/uview-plus/libs/ctocode/index.js +1 -0
  67. package/uview-plus/libs/ctocode/richText.js +0 -1
@@ -0,0 +1,1144 @@
1
+ <template>
2
+ <view class="up-container" @touchmove.stop.prevent="stop">
3
+ <view class="up-image-cropper" @touchend="cutTouchEnd" @touchstart="cutTouchStart" @touchmove="cutTouchMove">
4
+ <view class="up-content">
5
+ <view
6
+ class="up-content-top up-bg-transparent"
7
+ :style="{ height: cutY + 'px', transitionProperty: cutAnimation ? '' : 'background' }"
8
+ ></view>
9
+ <view class="up-content-middle" :style="{ height: canvasHeight + 'px' }">
10
+ <view
11
+ class="up-bg-transparent"
12
+ :style="{ width: cutX + 'px', transitionProperty: cutAnimation ? '' : 'background' }"
13
+ ></view>
14
+ <view
15
+ class="up-cropper-box"
16
+ :style="{
17
+ width: canvasWidth + 'px',
18
+ height: canvasHeight + 'px',
19
+ borderColor: borderColor,
20
+ transitionProperty: cutAnimation ? '' : 'background'
21
+ }"
22
+ >
23
+ <view
24
+ v-for="(item, index) in 4"
25
+ :key="index"
26
+ class="up-edge"
27
+ :class="[`up-${index < 2 ? 'top' : 'bottom'}-${index === 0 || index === 2 ? 'left' : 'right'}`]"
28
+ :style="{
29
+ width: edgeWidth,
30
+ height: edgeWidth,
31
+ borderColor: edgeColor,
32
+ borderWidth: edgeBorderWidth,
33
+ left: index === 0 || index === 2 ? `-${edgeOffsets}` : 'auto',
34
+ right: index === 1 || index === 3 ? `-${edgeOffsets}` : 'auto',
35
+ top: index < 2 ? `-${edgeOffsets}` : 'auto',
36
+ bottom: index > 1 ? `-${edgeOffsets}` : 'auto'
37
+ }"
38
+ ></view>
39
+ </view>
40
+ <view class="up-flex-auto up-bg-transparent" :style="{ transitionProperty: cutAnimation ? '' : 'background' }"></view>
41
+ </view>
42
+ <view class="up-flex-auto up-bg-transparent" :style="{ transitionProperty: cutAnimation ? '' : 'background' }"></view>
43
+ </view>
44
+ <image
45
+ @load="imageLoad"
46
+ @error="imageLoad"
47
+ @touchstart="start"
48
+ @touchmove="move"
49
+ @touchend="end"
50
+ :style="{
51
+ width: imgWidth ? imgWidth + 'px' : 'auto',
52
+ height: imgHeight ? imgHeight + 'px' : 'auto',
53
+ transform: imgTransform,
54
+ transitionDuration: (cutAnimation ? 0.35 : 0) + 's'
55
+ }"
56
+ class="up-cropper-image"
57
+ :class="{ 'up-cropper__image-hidden': !imageUrl }"
58
+ :src="imageUrl"
59
+ mode="widthFix"
60
+ ></image>
61
+ </view>
62
+ <canvas
63
+ canvas-id="up-image-cropper"
64
+ id="up-image-cropper"
65
+ :disable-scroll="true"
66
+ :style="{ width: CROPPER_WIDTH * scaleRatio + 'px', height: CROPPER_HEIGHT * scaleRatio + 'px' }"
67
+ class="up-cropper-canvas"
68
+ ></canvas>
69
+ <view class="up-cropper-tabbar" v-if="!custom">
70
+ <view class="up-op-btn" @tap.stop="back">取消</view>
71
+ <image :src="rotateImg" class="up-rotate-img" @tap="setAngle"></image>
72
+ <view class="up-op-btn" @tap.stop="getImage">完成</view>
73
+ </view>
74
+ </view>
75
+ </template>
76
+
77
+ <script>
78
+ /**
79
+ * 注意:组件中使用的图片地址,将文件复制到自己项目中
80
+ * 如果图片位置与组件同级,编译成小程序时图片会丢失
81
+ * 拷贝static下整个components文件夹
82
+ *也可直接转成base64(不建议)
83
+ * */
84
+ export default {
85
+ name: 'tuiImageCropper',
86
+ emits: ['ready', 'cropper', 'imageLoad'],
87
+ props: {
88
+ //图片路径
89
+ imageUrl: {
90
+ type: String,
91
+ default: ''
92
+ },
93
+ /*
94
+ 默认正方形,可修改大小控制比例
95
+ 裁剪框高度 px
96
+ */
97
+ height: {
98
+ type: Number,
99
+ default: 280
100
+ },
101
+ //裁剪框宽度 px
102
+ width: {
103
+ type: Number,
104
+ default: 280
105
+ },
106
+ //裁剪框最小宽度 px
107
+ minWidth: {
108
+ type: Number,
109
+ default: 100
110
+ },
111
+ //裁剪框最小高度 px
112
+ minHeight: {
113
+ type: Number,
114
+ default: 100
115
+ },
116
+ //裁剪框最大宽度 px
117
+ maxWidth: {
118
+ type: Number,
119
+ default: 360
120
+ },
121
+ //裁剪框最大高度 px
122
+ maxHeight: {
123
+ type: Number,
124
+ default: 360
125
+ },
126
+ //裁剪框border颜色
127
+ borderColor: {
128
+ type: String,
129
+ default: 'rgba(255,255,255,0.1)'
130
+ },
131
+ //裁剪框边缘线颜色
132
+ edgeColor: {
133
+ type: String,
134
+ default: '#FFFFFF'
135
+ },
136
+ //裁剪框边缘线宽度 w=h
137
+ edgeWidth: {
138
+ type: String,
139
+ default: '34rpx'
140
+ },
141
+ //裁剪框边缘线border宽度
142
+ edgeBorderWidth: {
143
+ type: String,
144
+ default: '6rpx'
145
+ },
146
+ //偏移距离,根据edgeBorderWidth进行调整
147
+ edgeOffsets: {
148
+ type: String,
149
+ default: '6rpx'
150
+ },
151
+ /**
152
+ * 如果宽度和高度都为true则裁剪框禁止拖动
153
+ * 裁剪框宽度锁定
154
+ */
155
+ lockWidth: {
156
+ type: Boolean,
157
+ default: false
158
+ },
159
+ //裁剪框高度锁定
160
+ lockHeight: {
161
+ type: Boolean,
162
+ default: false
163
+ },
164
+ //锁定裁剪框比例(放大或缩小)
165
+ lockRatio: {
166
+ type: Boolean,
167
+ default: false
168
+ },
169
+ //生成的图片尺寸相对剪裁框的比例
170
+ // #ifndef MP-QQ
171
+ scaleRatio: {
172
+ type: [Number, String],
173
+ default: 2
174
+ },
175
+ // #endif
176
+ // #ifdef MP-QQ
177
+ scaleRatio: {
178
+ type: [Number, String],
179
+ default: 3
180
+ },
181
+ // #endif
182
+ //图片的质量,取值范围为 (0, 1],不在范围内时当作1.0处理
183
+ quality: {
184
+ type: Number,
185
+ default: 0.8
186
+ },
187
+ //图片旋转角度
188
+ rotateAngle: {
189
+ type: Number,
190
+ default: 0
191
+ },
192
+ //图片最小缩放比
193
+ minScale: {
194
+ type: Number,
195
+ default: 0.5
196
+ },
197
+ //图片最大缩放比
198
+ maxScale: {
199
+ type: Number,
200
+ default: 2
201
+ },
202
+ //是否禁用触摸旋转(为false则可以触摸转动图片,limitMove为false生效)
203
+ disableRotate: {
204
+ type: Boolean,
205
+ default: true
206
+ },
207
+ //是否限制移动范围(剪裁框只能在图片内,为true不可触摸转动图片)
208
+ limitMove: {
209
+ type: Boolean,
210
+ default: true
211
+ },
212
+ //自定义操作栏(为true时隐藏底部操作栏)
213
+ custom: {
214
+ type: Boolean,
215
+ default: false
216
+ },
217
+ //值发生改变开始裁剪(custom为true时生效)
218
+ startCutting: {
219
+ type: [Number, Boolean],
220
+ default: 0
221
+ },
222
+ /**
223
+ * 是否返回base64(H5端默认base64)
224
+ * 支持平台:App,微信小程序,支付宝小程序,H5(默认url就是base64)
225
+ **/
226
+ isBase64: {
227
+ type: Boolean,
228
+ default: false
229
+ },
230
+ //裁剪时是否显示loadding
231
+ loadding: {
232
+ type: Boolean,
233
+ default: true
234
+ },
235
+ //旋转icon
236
+ rotateImg: {
237
+ type: String,
238
+ default: '/static/components/cropper/img_rotate.png'
239
+ },
240
+ //裁剪后图片类型:jpg/png
241
+ fileType: {
242
+ type: String,
243
+ default: 'png'
244
+ }
245
+ },
246
+ data() {
247
+ return {
248
+ MOVE_THROTTLE: null, //触摸移动节流setTimeout
249
+ MOVE_THROTTLE_FLAG: true, //节流标识
250
+ TIME_CUT_CENTER: null,
251
+ CROPPER_WIDTH: 200, //裁剪框宽
252
+ CROPPER_HEIGHT: 200, //裁剪框高
253
+ CUT_START: null,
254
+ cutX: 0, //画布x轴起点
255
+ cutY: 0, //画布y轴起点0
256
+ touchRelative: [
257
+ {
258
+ x: 0,
259
+ y: 0
260
+ }
261
+ ], //手指或鼠标和图片中心的相对位置
262
+ flagCutTouch: false, //是否是拖动裁剪框
263
+ hypotenuseLength: 0, //双指触摸时斜边长度
264
+ flagEndTouch: false, //是否结束触摸
265
+ canvasWidth: 0,
266
+ canvasHeight: 0,
267
+ imgWidth: 0, //图片宽度
268
+ imgHeight: 0, //图片高度
269
+ scale: 1, //图片缩放比
270
+ angle: 0, //图片旋转角度
271
+ cutAnimation: false, //是否开启图片和裁剪框过渡
272
+ cutAnimationTime: null,
273
+ imgTop: 0, //图片上边距
274
+ imgLeft: 0, //图片左边距
275
+ ctx: null,
276
+ sysInfo: null
277
+ };
278
+ },
279
+ computed: {
280
+ imgTransform: function () {
281
+ return `translate3d(${this.imgLeft - this.imgWidth / 2}px,${this.imgTop - this.imgHeight / 2}px,0) scale(${this.scale}) rotate(${this.angle}deg)`;
282
+ }
283
+ },
284
+ watch: {
285
+ imageUrl(val, oldVal) {
286
+ this.imageReset();
287
+ this.showLoading();
288
+ uni.getImageInfo({
289
+ src: val,
290
+ success: (res) => {
291
+ //计算图片尺寸
292
+ this.imgComputeSize(res.width, res.height);
293
+ if (this.limitMove) {
294
+ //限制移动,不留空白处理
295
+ this.imgMarginDetectionScale();
296
+ }
297
+ },
298
+ fail: (err) => {
299
+ this.imgComputeSize();
300
+ if (this.limitMove) {
301
+ this.imgMarginDetectionScale();
302
+ }
303
+ }
304
+ });
305
+ },
306
+ //监听截取框宽高变化
307
+ canvasWidth(val) {
308
+ if (val < this.minWidth) {
309
+ this.canvasWidth = this.minWidth;
310
+ }
311
+ this.computeCutSize();
312
+ },
313
+ canvasHeight(val) {
314
+ if (val < this.minHeight) {
315
+ this.canvasHeight = this.minHeight;
316
+ }
317
+ this.computeCutSize();
318
+ },
319
+ rotateAngle(val) {
320
+ this.cutAnimation = true;
321
+ this.angle = val;
322
+ },
323
+ angle(val) {
324
+ this.moveStop();
325
+ if (this.limitMove && val % 90) {
326
+ this.angle = Math.round(val / 90) * 90;
327
+ }
328
+ this.imgMarginDetectionScale();
329
+ },
330
+ cutAnimation(val) {
331
+ //开启过渡260毫秒之后自动关闭
332
+ clearTimeout(this.cutAnimationTime);
333
+ if (val) {
334
+ this.cutAnimationTime = setTimeout(() => {
335
+ this.cutAnimation = false;
336
+ }, 260);
337
+ }
338
+ },
339
+ limitMove(val) {
340
+ if (val) {
341
+ if (this.angle % 90) {
342
+ this.angle = Math.round(this.angle / 90) * 90;
343
+ }
344
+ this.imgMarginDetectionScale();
345
+ }
346
+ },
347
+ cutY(value) {
348
+ this.cutDetectionPosition();
349
+ },
350
+ cutX(value) {
351
+ this.cutDetectionPosition();
352
+ },
353
+ startCutting(val) {
354
+ if (this.custom && val) {
355
+ this.getImage();
356
+ }
357
+ }
358
+ },
359
+ mounted() {
360
+ this.sysInfo = uni.getSystemInfoSync();
361
+ this.imgTop = this.sysInfo.windowHeight / 2;
362
+ this.imgLeft = this.sysInfo.windowWidth / 2;
363
+ this.CROPPER_WIDTH = this.width;
364
+ this.CROPPER_HEIGHT = this.height;
365
+ this.canvasHeight = this.height;
366
+ this.canvasWidth = this.width;
367
+ this.ctx = uni.createCanvasContext('up-image-cropper', this);
368
+ this.setCutCenter();
369
+ //设置裁剪框大小>设置图片尺寸>绘制canvas
370
+ this.computeCutSize();
371
+ //检查裁剪框是否在范围内
372
+ this.cutDetectionPosition();
373
+ setTimeout(() => {
374
+ this.$emit('ready', {});
375
+ }, 200);
376
+ },
377
+ methods: {
378
+ //网络图片转成本地文件[同步执行]
379
+ async getLocalImage(url) {
380
+ return await new Promise((resolve, reject) => {
381
+ uni.downloadFile({
382
+ url: url,
383
+ success: (res) => {
384
+ resolve(res.tempFilePath);
385
+ },
386
+ fail: (res) => {
387
+ reject(false);
388
+ }
389
+ });
390
+ });
391
+ },
392
+ //返回裁剪后图片信息
393
+ getImage() {
394
+ if (!this.imageUrl) {
395
+ uni.showToast({
396
+ title: '请选择图片',
397
+ icon: 'none'
398
+ });
399
+ return;
400
+ }
401
+ this.loadding && this.showLoading();
402
+ let draw = async () => {
403
+ //图片实际大小
404
+ let imgWidth = this.imgWidth * this.scale * this.scaleRatio;
405
+ let imgHeight = this.imgHeight * this.scale * this.scaleRatio;
406
+ //canvas和图片的相对距离
407
+ let xpos = this.imgLeft - this.cutX;
408
+ let ypos = this.imgTop - this.cutY;
409
+ //旋转画布
410
+ this.ctx.translate(xpos * this.scaleRatio, ypos * this.scaleRatio);
411
+ this.ctx.rotate((this.angle * Math.PI) / 180);
412
+ let imgUrl = this.imageUrl;
413
+ // #ifdef APP-PLUS || MP-WEIXIN
414
+ if (~this.imageUrl.indexOf('https:')) {
415
+ imgUrl = await this.getLocalImage(this.imageUrl);
416
+ }
417
+ // #endif
418
+ this.ctx.drawImage(imgUrl, -imgWidth / 2, -imgHeight / 2, imgWidth, imgHeight);
419
+ this.ctx.draw(false, () => {
420
+ let params = {
421
+ width: this.canvasWidth * this.scaleRatio,
422
+ height: Math.round(this.canvasHeight * this.scaleRatio),
423
+ // #ifdef MP-QQ
424
+ destWidth: this.canvasWidth * this.scaleRatio * 2,
425
+ destHeight: Math.round(this.canvasHeight) * this.scaleRatio * 2,
426
+ // #endif
427
+
428
+ // #ifndef MP-QQ
429
+ destWidth: this.canvasWidth * this.scaleRatio,
430
+ destHeight: Math.round(this.canvasHeight) * this.scaleRatio,
431
+ // #endif
432
+
433
+ fileType: this.fileType || 'png',
434
+ quality: this.quality
435
+ };
436
+ let data = {
437
+ url: '',
438
+ base64: '',
439
+ width: this.canvasWidth * this.scaleRatio,
440
+ height: this.canvasHeight * this.scaleRatio
441
+ };
442
+ // #ifdef MP-ALIPAY
443
+
444
+ if (this.isBase64) {
445
+ this.ctx.toDataURL(params).then((dataURL) => {
446
+ data.base64 = dataURL;
447
+ this.loadding && uni.hideLoading();
448
+ this.ctx.rotate(((360 - (this.angle % 360)) * Math.PI) / 180);
449
+ this.ctx.translate(-xpos * this.scaleRatio, -ypos * this.scaleRatio);
450
+ this.ctx.clearRect(0, 0, this.canvasWidth * this.scaleRatio, this.canvasHeight * this.scaleRatio);
451
+ this.ctx.draw();
452
+ this.$emit('cropper', data);
453
+ });
454
+ } else {
455
+ this.ctx.toTempFilePath({
456
+ ...params,
457
+ success: (res) => {
458
+ data.url = res.apFilePath;
459
+ this.loadding && uni.hideLoading();
460
+ this.ctx.rotate(((360 - (this.angle % 360)) * Math.PI) / 180);
461
+ this.ctx.translate(-xpos * this.scaleRatio, -ypos * this.scaleRatio);
462
+ this.ctx.clearRect(0, 0, this.canvasWidth * this.scaleRatio, this.canvasHeight * this.scaleRatio);
463
+ this.ctx.draw();
464
+ this.$emit('cropper', data);
465
+ }
466
+ });
467
+ }
468
+ // #endif
469
+
470
+ // #ifndef MP-ALIPAY
471
+ let isBase64 = this.isBase64;
472
+ // #ifdef MP-BAIDU || MP-TOUTIAO || H5
473
+ isBase64 = false;
474
+ // #endif
475
+ if (isBase64) {
476
+ // #ifndef MP-WEIXIN
477
+ uni.canvasGetImageData(
478
+ {
479
+ canvasId: 'up-image-cropper',
480
+ x: 0,
481
+ y: 0,
482
+ width: this.canvasWidth * this.scaleRatio,
483
+ height: Math.round(this.canvasHeight * this.scaleRatio),
484
+ success: (res) => {
485
+ const arrayBuffer = new Uint8Array(res.data);
486
+ const base64 = uni.arrayBufferToBase64(arrayBuffer);
487
+ data.base64 = base64;
488
+ this.loadding && uni.hideLoading();
489
+ this.$emit('cropper', data);
490
+ }
491
+ },
492
+ this
493
+ );
494
+ // #endif
495
+
496
+ // #ifdef MP-WEIXIN
497
+ uni.canvasToTempFilePath(
498
+ {
499
+ ...params,
500
+ canvasId: 'up-image-cropper',
501
+ success: (res) => {
502
+ data.url = res.tempFilePath;
503
+ const fs = wx.getFileSystemManager();
504
+ // 读取文件, base64 格式
505
+ const base64Str = fs.readFileSync(res.tempFilePath, 'base64');
506
+ const imgBase64 = `data:image/png;base64,${base64Str}`;
507
+ data.base64 = imgBase64;
508
+ this.loadding && uni.hideLoading();
509
+ this.$emit('cropper', data);
510
+ },
511
+ fail(res) {
512
+ console.log(res);
513
+ }
514
+ },
515
+ this
516
+ );
517
+ // #endif
518
+ } else {
519
+ uni.canvasToTempFilePath(
520
+ {
521
+ ...params,
522
+ canvasId: 'up-image-cropper',
523
+ success: (res) => {
524
+ data.url = res.tempFilePath;
525
+ // #ifdef H5
526
+ data.base64 = res.tempFilePath;
527
+ // #endif
528
+ this.loadding && uni.hideLoading();
529
+ this.$emit('cropper', data);
530
+ },
531
+ fail(res) {
532
+ console.log(res);
533
+ }
534
+ },
535
+ this
536
+ );
537
+ }
538
+ // #endif
539
+ });
540
+ };
541
+ if (this.CROPPER_WIDTH != this.canvasWidth || this.CROPPER_HEIGHT != this.canvasHeight) {
542
+ this.CROPPER_WIDTH = this.canvasWidth;
543
+ this.CROPPER_HEIGHT = this.canvasHeight;
544
+ this.ctx.draw();
545
+ this.$nextTick(() => {
546
+ setTimeout(() => {
547
+ draw();
548
+ }, 100);
549
+ });
550
+ } else {
551
+ draw();
552
+ }
553
+ },
554
+ /**
555
+ * 设置剪裁框和图片居中
556
+ */
557
+ setCutCenter() {
558
+ let sys = this.sysInfo || uni.getSystemInfoSync();
559
+ let cutY = (sys.windowHeight - this.canvasHeight) * 0.5;
560
+ let cutX = (sys.windowWidth - this.canvasWidth) * 0.5;
561
+ //顺序不能变
562
+ this.imgTop = this.imgTop - this.cutY + cutY;
563
+ this.cutY = cutY; //截取的框上边距
564
+ this.imgLeft = this.imgLeft - this.cutX + cutX;
565
+ this.cutX = cutX; //截取的框左边距
566
+ },
567
+ imageReset() {
568
+ // this.cutAnimation = true;
569
+ this.scale = 1;
570
+ this.angle = 0;
571
+ let sys = this.sysInfo || uni.getSystemInfoSync();
572
+ this.imgTop = sys.windowHeight / 2;
573
+ this.imgLeft = sys.windowWidth / 2;
574
+ },
575
+ imageLoad(e) {
576
+ this.imageReset();
577
+ uni.hideLoading();
578
+ this.$emit('imageLoad', {});
579
+ },
580
+ //检测剪裁框位置是否在允许的范围内(屏幕内)
581
+ cutDetectionPosition() {
582
+ let cutDetectionPositionTop = () => {
583
+ //检测上边距是否在范围内
584
+ if (this.cutY < 0) {
585
+ this.cutY = 0;
586
+ }
587
+ if (this.cutY > this.sysInfo.windowHeight - this.canvasHeight) {
588
+ this.cutY = this.sysInfo.windowHeight - this.canvasHeight;
589
+ }
590
+ },
591
+ cutDetectionPositionLeft = () => {
592
+ //检测左边距是否在范围内
593
+ if (this.cutX < 0) {
594
+ this.cutX = 0;
595
+ }
596
+ if (this.cutX > this.sysInfo.windowWidth - this.canvasWidth) {
597
+ this.cutX = this.sysInfo.windowWidth - this.canvasWidth;
598
+ }
599
+ };
600
+ //裁剪框坐标处理(如果只写一个参数则另一个默认为0,都不写默认居中)
601
+ if (this.cutY == null && this.cutX == null) {
602
+ let cutY = (this.sysInfo.windowHeight - this.canvasHeight) * 0.5;
603
+ let cutX = (this.sysInfo.windowWidth - this.canvasWidth) * 0.5;
604
+ this.cutY = cutY; //截取的框上边距
605
+ this.cutX = cutX; //截取的框左边距
606
+ } else if (this.cutY != null && this.cutX != null) {
607
+ cutDetectionPositionTop();
608
+ cutDetectionPositionLeft();
609
+ } else if (this.cutY != null && this.cutX == null) {
610
+ cutDetectionPositionTop();
611
+ this.cutX = (this.sysInfo.windowWidth - this.canvasWidth) / 2;
612
+ } else if (this.cutY == null && this.cutX != null) {
613
+ cutDetectionPositionLeft();
614
+ this.cutY = (this.sysInfo.windowHeight - this.canvasHeight) / 2;
615
+ }
616
+ },
617
+ /**
618
+ * 图片边缘检测-位置
619
+ */
620
+ imgMarginDetectionPosition(scale) {
621
+ if (!this.limitMove) return;
622
+ let left = this.imgLeft;
623
+ let top = this.imgTop;
624
+ scale = scale || this.scale;
625
+ let imgWidth = this.imgWidth;
626
+ let imgHeight = this.imgHeight;
627
+ if ((this.angle / 90) % 2) {
628
+ imgWidth = this.imgHeight;
629
+ imgHeight = this.imgWidth;
630
+ }
631
+ left = this.cutX + (imgWidth * scale) / 2 >= left ? left : this.cutX + (imgWidth * scale) / 2;
632
+ left =
633
+ this.cutX + this.canvasWidth - (imgWidth * scale) / 2 <= left
634
+ ? left
635
+ : this.cutX + this.canvasWidth - (imgWidth * scale) / 2;
636
+ top = this.cutY + (imgHeight * scale) / 2 >= top ? top : this.cutY + (imgHeight * scale) / 2;
637
+ top =
638
+ this.cutY + this.canvasHeight - (imgHeight * scale) / 2 <= top
639
+ ? top
640
+ : this.cutY + this.canvasHeight - (imgHeight * scale) / 2;
641
+ this.imgLeft = left;
642
+ this.imgTop = top;
643
+ this.scale = scale;
644
+ },
645
+ /**
646
+ * 图片边缘检测-缩放
647
+ */
648
+ imgMarginDetectionScale(scale) {
649
+ if (!this.limitMove) return;
650
+ scale = scale || this.scale;
651
+ let imgWidth = this.imgWidth;
652
+ let imgHeight = this.imgHeight;
653
+ if ((this.angle / 90) % 2) {
654
+ imgWidth = this.imgHeight;
655
+ imgHeight = this.imgWidth;
656
+ }
657
+ if (imgWidth * scale < this.canvasWidth) {
658
+ scale = this.canvasWidth / imgWidth;
659
+ }
660
+ if (imgHeight * scale < this.canvasHeight) {
661
+ scale = Math.max(scale, this.canvasHeight / imgHeight);
662
+ }
663
+ this.imgMarginDetectionPosition(scale);
664
+ },
665
+ /**
666
+ * 计算图片尺寸
667
+ */
668
+ imgComputeSize(width, height) {
669
+ //默认按图片最小边 = 对应裁剪框尺寸
670
+ let imgWidth = width,
671
+ imgHeight = height;
672
+ if (imgWidth && imgHeight) {
673
+ if (imgWidth / imgHeight > (this.canvasWidth || this.width) / (this.canvasHeight || this.height)) {
674
+ imgHeight = this.canvasHeight || this.height;
675
+ imgWidth = (width / height) * imgHeight;
676
+ } else {
677
+ imgWidth = this.canvasWidth || this.width;
678
+ imgHeight = (height / width) * imgWidth;
679
+ }
680
+ } else {
681
+ let sys = this.sysInfo || uni.getSystemInfoSync();
682
+ imgWidth = sys.windowWidth;
683
+ imgHeight = 0;
684
+ }
685
+ this.imgWidth = imgWidth;
686
+ this.imgHeight = imgHeight;
687
+ },
688
+ //改变截取框大小
689
+ computeCutSize() {
690
+ if (this.canvasWidth > this.sysInfo.windowWidth) {
691
+ this.canvasWidth = this.sysInfo.windowWidth;
692
+ } else if (this.canvasWidth + this.cutX > this.sysInfo.windowWidth) {
693
+ this.cutX = this.sysInfo.windowWidth - this.cutX;
694
+ }
695
+ if (this.canvasHeight > this.sysInfo.windowHeight) {
696
+ this.canvasHeight = this.sysInfo.windowHeight;
697
+ } else if (this.canvasHeight + this.cutY > this.sysInfo.windowHeight) {
698
+ this.cutY = this.sysInfo.windowHeight - this.cutY;
699
+ }
700
+ },
701
+ //开始触摸
702
+ start(e) {
703
+ this.flagEndTouch = false;
704
+ if (e.touches.length == 1) {
705
+ //单指拖动
706
+ this.touchRelative[0] = {
707
+ x: e.touches[0].clientX - this.imgLeft,
708
+ y: e.touches[0].clientY - this.imgTop
709
+ };
710
+ } else {
711
+ //双指放大
712
+ let width = Math.abs(e.touches[0].clientX - e.touches[1].clientX);
713
+ let height = Math.abs(e.touches[0].clientY - e.touches[1].clientY);
714
+ this.touchRelative = [
715
+ {
716
+ x: e.touches[0].clientX - this.imgLeft,
717
+ y: e.touches[0].clientY - this.imgTop
718
+ },
719
+ {
720
+ x: e.touches[1].clientX - this.imgLeft,
721
+ y: e.touches[1].clientY - this.imgTop
722
+ }
723
+ ];
724
+ this.hypotenuseLength = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2));
725
+ }
726
+ },
727
+ moveThrottle() {
728
+ if (this.sysInfo.platform == 'android') {
729
+ clearTimeout(this.MOVE_THROTTLE);
730
+ this.MOVE_THROTTLE = setTimeout(() => {
731
+ this.MOVE_THROTTLE_FLAG = true;
732
+ }, 800 / 40);
733
+ return this.MOVE_THROTTLE_FLAG;
734
+ } else {
735
+ this.MOVE_THROTTLE_FLAG = true;
736
+ }
737
+ },
738
+ move(e) {
739
+ if (this.flagEndTouch || !this.MOVE_THROTTLE_FLAG) return;
740
+ this.MOVE_THROTTLE_FLAG = false;
741
+ this.moveThrottle();
742
+ this.moveDuring();
743
+ if (e.touches.length == 1) {
744
+ //单指拖动
745
+ let left = e.touches[0].clientX - this.touchRelative[0].x,
746
+ top = e.touches[0].clientY - this.touchRelative[0].y;
747
+ //图像边缘检测,防止截取到空白
748
+ this.imgLeft = left;
749
+ this.imgTop = top;
750
+ this.imgMarginDetectionPosition();
751
+ } else {
752
+ //双指放大
753
+ let width = Math.abs(e.touches[0].clientX - e.touches[1].clientX),
754
+ height = Math.abs(e.touches[0].clientY - e.touches[1].clientY),
755
+ hypotenuse = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)),
756
+ scale = this.scale * (hypotenuse / this.hypotenuseLength),
757
+ current_deg = 0;
758
+ scale = scale <= this.minScale ? this.minScale : scale;
759
+ scale = scale >= this.maxScale ? this.maxScale : scale;
760
+ //图像边缘检测,防止截取到空白
761
+ // this.scale = scale;
762
+ this.imgMarginDetectionScale(scale);
763
+ //双指旋转(如果没禁用旋转)
764
+ let touchRelative = [
765
+ {
766
+ x: e.touches[0].clientX - this.imgLeft,
767
+ y: e.touches[0].clientY - this.imgTop
768
+ },
769
+ {
770
+ x: e.touches[1].clientX - this.imgLeft,
771
+ y: e.touches[1].clientY - this.imgTop
772
+ }
773
+ ];
774
+ if (!this.disableRotate) {
775
+ let first_atan = (180 / Math.PI) * Math.atan2(touchRelative[0].y, touchRelative[0].x);
776
+ let first_atan_old = (180 / Math.PI) * Math.atan2(this.touchRelative[0].y, this.touchRelative[0].x);
777
+ let second_atan = (180 / Math.PI) * Math.atan2(touchRelative[1].y, touchRelative[1].x);
778
+ let second_atan_old = (180 / Math.PI) * Math.atan2(this.touchRelative[1].y, this.touchRelative[1].x);
779
+ //当前旋转的角度
780
+ let first_deg = first_atan - first_atan_old,
781
+ second_deg = second_atan - second_atan_old;
782
+ if (first_deg != 0) {
783
+ current_deg = first_deg;
784
+ } else if (second_deg != 0) {
785
+ current_deg = second_deg;
786
+ }
787
+ }
788
+ this.touchRelative = touchRelative;
789
+ this.hypotenuseLength = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2));
790
+ //更新视图
791
+ this.angle = this.angle + current_deg;
792
+ this.scale = this.scale;
793
+ }
794
+ },
795
+ //结束操作
796
+ end(e) {
797
+ this.flagEndTouch = true;
798
+ this.moveStop();
799
+ },
800
+ //裁剪框处理
801
+ cutTouchMove(e) {
802
+ if (this.flagCutTouch && this.MOVE_THROTTLE_FLAG) {
803
+ if (this.lockRatio && (this.lockWidth || this.lockHeight)) return;
804
+ //节流
805
+ this.MOVE_THROTTLE_FLAG = false;
806
+ this.moveThrottle();
807
+ let width = this.canvasWidth,
808
+ height = this.canvasHeight,
809
+ cutY = this.cutY,
810
+ cutX = this.cutX,
811
+ size_correct = () => {
812
+ width = width <= this.maxWidth ? (width >= this.minWidth ? width : this.minWidth) : this.maxWidth;
813
+ height = height <= this.maxHeight ? (height >= this.minHeight ? height : this.minHeight) : this.maxHeight;
814
+ },
815
+ size_inspect = () => {
816
+ if (
817
+ (width > this.maxWidth || width < this.minWidth || height > this.maxHeight || height < this.minHeight) &&
818
+ this.lockRatio
819
+ ) {
820
+ size_correct();
821
+ return false;
822
+ } else {
823
+ size_correct();
824
+ return true;
825
+ }
826
+ };
827
+ height =
828
+ this.CUT_START.height +
829
+ (this.CUT_START.corner > 1 && this.CUT_START.corner < 4 ? 1 : -1) * (this.CUT_START.y - e.touches[0].clientY);
830
+ switch (this.CUT_START.corner) {
831
+ case 1:
832
+ width = this.CUT_START.width - this.CUT_START.x + e.touches[0].clientX;
833
+ if (this.lockRatio) {
834
+ height = width / (this.canvasWidth / this.canvasHeight);
835
+ }
836
+ if (!size_inspect()) return;
837
+ break;
838
+ case 2:
839
+ width = this.CUT_START.width - this.CUT_START.x + e.touches[0].clientX;
840
+ if (this.lockRatio) {
841
+ height = width / (this.canvasWidth / this.canvasHeight);
842
+ }
843
+ if (!size_inspect()) return;
844
+ cutY = this.CUT_START.cutY - (height - this.CUT_START.height);
845
+ break;
846
+ case 3:
847
+ width = this.CUT_START.width + this.CUT_START.x - e.touches[0].clientX;
848
+ if (this.lockRatio) {
849
+ height = width / (this.canvasWidth / this.canvasHeight);
850
+ }
851
+ if (!size_inspect()) return;
852
+ cutY = this.CUT_START.cutY - (height - this.CUT_START.height);
853
+ cutX = this.CUT_START.cutX - (width - this.CUT_START.width);
854
+ break;
855
+ case 4:
856
+ width = this.CUT_START.width + this.CUT_START.x - e.touches[0].clientX;
857
+ if (this.lockRatio) {
858
+ height = width / (this.canvasWidth / this.canvasHeight);
859
+ }
860
+ if (!size_inspect()) return;
861
+ cutX = this.CUT_START.cutX - (width - this.CUT_START.width);
862
+ break;
863
+ default:
864
+ break;
865
+ }
866
+ if (!this.lockWidth && !this.lockHeight) {
867
+ this.canvasWidth = width;
868
+ this.cutX = cutX;
869
+ this.canvasHeight = height;
870
+ this.cutY = cutY;
871
+ } else if (!this.lockWidth) {
872
+ this.canvasWidth = width;
873
+ this.cutX = cutX;
874
+ } else if (!this.lockHeight) {
875
+ this.canvasHeight = height;
876
+ this.cutY = cutY;
877
+ }
878
+ this.imgMarginDetectionScale();
879
+ }
880
+ },
881
+ cutTouchStart(e) {
882
+ let currentX = e.touches[0].clientX;
883
+ let currentY = e.touches[0].clientY;
884
+
885
+ /*
886
+ * (右下-1 右上-2 左上-3 左下-4)
887
+ * left_x [3,4]
888
+ * top_y [2,3]
889
+ * right_x [1,2]
890
+ * bottom_y [1,4]
891
+ */
892
+ let left_x1 = this.cutX - 24;
893
+ let left_x2 = this.cutX + 24;
894
+
895
+ let top_y1 = this.cutY - 24;
896
+ let top_y2 = this.cutY + 24;
897
+
898
+ let right_x1 = this.cutX + this.canvasWidth - 24;
899
+ let right_x2 = this.cutX + this.canvasWidth + 24;
900
+
901
+ let bottom_y1 = this.cutY + this.canvasHeight - 24;
902
+ let bottom_y2 = this.cutY + this.canvasHeight + 24;
903
+
904
+ if (currentX > right_x1 && currentX < right_x2 && currentY > bottom_y1 && currentY < bottom_y2) {
905
+ this.moveDuring();
906
+ this.flagCutTouch = true;
907
+ this.flagEndTouch = true;
908
+ this.CUT_START = {
909
+ width: this.canvasWidth,
910
+ height: this.canvasHeight,
911
+ x: currentX,
912
+ y: currentY,
913
+ corner: 1
914
+ };
915
+ } else if (currentX > right_x1 && currentX < right_x2 && currentY > top_y1 && currentY < top_y2) {
916
+ this.moveDuring();
917
+ this.flagCutTouch = true;
918
+ this.flagEndTouch = true;
919
+ this.CUT_START = {
920
+ width: this.canvasWidth,
921
+ height: this.canvasHeight,
922
+ x: currentX,
923
+ y: currentY,
924
+ cutY: this.cutY,
925
+ cutX: this.cutX,
926
+ corner: 2
927
+ };
928
+ } else if (currentX > left_x1 && currentX < left_x2 && currentY > top_y1 && currentY < top_y2) {
929
+ this.moveDuring();
930
+ this.flagCutTouch = true;
931
+ this.flagEndTouch = true;
932
+ this.CUT_START = {
933
+ width: this.canvasWidth,
934
+ height: this.canvasHeight,
935
+ cutY: this.cutY,
936
+ cutX: this.cutX,
937
+ x: currentX,
938
+ y: currentY,
939
+ corner: 3
940
+ };
941
+ } else if (currentX > left_x1 && currentX < left_x2 && currentY > bottom_y1 && currentY < bottom_y2) {
942
+ this.moveDuring();
943
+ this.flagCutTouch = true;
944
+ this.flagEndTouch = true;
945
+ this.CUT_START = {
946
+ width: this.canvasWidth,
947
+ height: this.canvasHeight,
948
+ cutY: this.cutY,
949
+ cutX: this.cutX,
950
+ x: currentX,
951
+ y: currentY,
952
+ corner: 4
953
+ };
954
+ }
955
+ },
956
+ cutTouchEnd(e) {
957
+ this.moveStop();
958
+ this.flagCutTouch = false;
959
+ },
960
+ //停止移动时需要做的操作
961
+ moveStop() {
962
+ //清空之前的自动居中延迟函数并添加最新的
963
+ clearTimeout(this.TIME_CUT_CENTER);
964
+ this.TIME_CUT_CENTER = setTimeout(() => {
965
+ //动画启动
966
+ if (!this.cutAnimation) {
967
+ this.cutAnimation = true;
968
+ }
969
+ this.setCutCenter();
970
+ }, 800);
971
+ },
972
+ //移动中
973
+ moveDuring() {
974
+ //清空之前的自动居中延迟函数
975
+ clearTimeout(this.TIME_CUT_CENTER);
976
+ },
977
+ showLoading() {
978
+ uni.showLoading({
979
+ // #ifndef MP-ALIPAY
980
+ mask: true,
981
+ // #endif
982
+ title: '请稍候...'
983
+ });
984
+ },
985
+ stop() {},
986
+ back() {
987
+ uni.navigateBack();
988
+ },
989
+ setAngle() {
990
+ this.cutAnimation = true;
991
+ this.angle = this.angle + 90;
992
+ }
993
+ }
994
+ };
995
+ </script>
996
+
997
+ <style scoped>
998
+ .up-container {
999
+ width: 100vw;
1000
+ height: 100vh;
1001
+ padding: 0;
1002
+ background-color: rgba(0, 0, 0, 0.6);
1003
+ position: fixed;
1004
+ top: 0;
1005
+ left: 0;
1006
+ z-index: 1;
1007
+ }
1008
+
1009
+ .up-image-cropper {
1010
+ width: 100vw;
1011
+ height: 100vh;
1012
+ position: absolute;
1013
+ }
1014
+
1015
+ .up-content {
1016
+ width: 100vw;
1017
+ height: 100vh;
1018
+ padding: 0;
1019
+ position: absolute;
1020
+ z-index: 9;
1021
+ display: flex;
1022
+ flex-direction: column;
1023
+ pointer-events: none;
1024
+ }
1025
+
1026
+ .up-bg-transparent {
1027
+ background-color: rgba(0, 0, 0, 0.6);
1028
+ transition-duration: 0.35s;
1029
+ }
1030
+
1031
+ .up-content-top {
1032
+ pointer-events: none;
1033
+ }
1034
+
1035
+ .up-content-middle {
1036
+ width: 100%;
1037
+ height: 200px;
1038
+ display: flex;
1039
+ box-sizing: border-box;
1040
+ }
1041
+
1042
+ .up-cropper-box {
1043
+ position: relative;
1044
+ /* transition-duration: 0.3s; */
1045
+ border-style: solid;
1046
+ border-width: 1rpx;
1047
+ box-sizing: border-box;
1048
+ }
1049
+
1050
+ .up-flex-auto {
1051
+ flex: auto;
1052
+ }
1053
+
1054
+ .up-cropper-image {
1055
+ width: 100%;
1056
+ border-style: none;
1057
+ position: absolute;
1058
+ top: 0;
1059
+ left: 0;
1060
+ z-index: 2;
1061
+ -webkit-backface-visibility: hidden;
1062
+ backface-visibility: hidden;
1063
+ transform-origin: center;
1064
+ }
1065
+
1066
+ .up-cropper__image-hidden {
1067
+ opacity: 0;
1068
+ visibility: hidden;
1069
+ }
1070
+
1071
+ .up-cropper-canvas {
1072
+ position: fixed;
1073
+ z-index: 10;
1074
+ left: -2000px;
1075
+ top: -2000px;
1076
+ pointer-events: none;
1077
+ }
1078
+
1079
+ .up-edge {
1080
+ border-style: solid;
1081
+ pointer-events: auto;
1082
+ position: absolute;
1083
+ box-sizing: border-box;
1084
+ }
1085
+
1086
+ .up-top-left {
1087
+ border-bottom-width: 0 !important;
1088
+ border-right-width: 0 !important;
1089
+ }
1090
+
1091
+ .up-top-right {
1092
+ border-bottom-width: 0 !important;
1093
+ border-left-width: 0 !important;
1094
+ }
1095
+
1096
+ .up-bottom-left {
1097
+ border-top-width: 0 !important;
1098
+ border-right-width: 0 !important;
1099
+ }
1100
+
1101
+ .up-bottom-right {
1102
+ border-top-width: 0 !important;
1103
+ border-left-width: 0 !important;
1104
+ }
1105
+
1106
+ .up-cropper-tabbar {
1107
+ width: 100%;
1108
+ height: 120rpx;
1109
+ padding: 0 40rpx;
1110
+ box-sizing: border-box;
1111
+ position: fixed;
1112
+ left: 0;
1113
+ bottom: 0;
1114
+ z-index: 99;
1115
+ display: flex;
1116
+ align-items: center;
1117
+ justify-content: space-between;
1118
+ color: #ffffff;
1119
+ font-size: 32rpx;
1120
+ }
1121
+
1122
+ .up-cropper-tabbar::after {
1123
+ content: ' ';
1124
+ position: absolute;
1125
+ top: 0;
1126
+ right: 0;
1127
+ left: 0;
1128
+ border-top: 1rpx solid rgba(255, 255, 255, 0.2);
1129
+ -webkit-transform: scaleY(0.5) translateZ(0);
1130
+ transform: scaleY(0.5) translateZ(0);
1131
+ transform-origin: 0 100%;
1132
+ }
1133
+
1134
+ .up-op-btn {
1135
+ height: 80rpx;
1136
+ display: flex;
1137
+ align-items: center;
1138
+ }
1139
+
1140
+ .up-rotate-img {
1141
+ width: 44rpx;
1142
+ height: 44rpx;
1143
+ }
1144
+ </style>