uview-plus 3.4.83 → 3.4.85

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/changelog.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## 3.4.85(2025-08-11)
2
+ feat: 完善图片裁剪功能支持props及JS两种方式
3
+
4
+ fix: 修复H5下裁剪后图片黑屏
5
+
6
+ ## 3.4.84(2025-08-11)
7
+ feat: 新增cropper图片裁剪组件
8
+
1
9
  ## 3.4.83(2025-08-11)
2
10
  feat: 新增barcode无三方依赖条码组
3
11
 
@@ -0,0 +1,1213 @@
1
+ <template>
2
+ <view class="u-cropper">
3
+ <!-- <image :src="imgSrc.imgSrc" @click="select" :style="[ imgStyle ]" class="my-avatar"></image> -->
4
+ <canvas :canvas-id="'avatar-canvas-' + instanceId" :id="'avatar-canvas-' + instanceId" class="my-canvas"
5
+ :style="{top: styleTop, height: cvsStyleHeight}" disable-scroll="false"></canvas>
6
+ <canvas :canvas-id="'oper-canvas-' + instanceId" :id="'oper-canvas-' + instanceId" class="oper-canvas"
7
+ :style="{top: styleTop, height: cvsStyleHeight}"
8
+ disable-scroll="false" @touchstart="start" @touchmove="move" @touchend="end"></canvas>
9
+ <canvas :canvas-id="'prv-canvas-' + instanceId" :id="'prv-canvas-' + instanceId" class="prv-canvas"disable-scroll="false"
10
+ @touchstart="hideImg":style="{ height: cvsStyleHeight, top: prvTop }"></canvas>
11
+ <view class="oper-wrapper" :style="{display: styleDisplay}">
12
+ <view class="oper">
13
+ <view class="btn-wrapper" v-if="showOper">
14
+ <view @click="select" hover-class="hover" :style="{width: btnWidth}"><text>重选</text></view>
15
+ <view @click="close" hover-class="hover" :style="{width: btnWidth}"><text>关闭</text></view>
16
+ <view @click="rotate" hover-class="hover" :style="{width: btnWidth, display: btnDsp}"><text>旋转</text></view>
17
+ <view @click="preview" hover-class="hover" :style="{width: btnWidth}"><text>预览</text></view>
18
+ <view @click="confirm" hover-class="hover" :style="{width: btnWidth}"><text>确认</text></view>
19
+ </view>
20
+ <view class="clr-wrapper" v-else>
21
+ <slider class="my-slider" @change="colorChange"
22
+ block-size="25" value="0" min="-100" max="100" activeColor="red" backgroundColor="green" block-color="grey" show-value></slider>
23
+ <view @click="prvUpload" hover-class="hover" :style="{width: btnWidth}"><text>确认</text></view>
24
+ </view>
25
+ </view>
26
+ </view>
27
+ <view @click="chooseImage(0, {})" v-if="styleDisplay == 'none'">
28
+ <slot>
29
+
30
+ </slot>
31
+ </view>
32
+ </view>
33
+ </template>
34
+
35
+ <script>
36
+ const tabHeight = 50;
37
+ export default {
38
+ name: "u-cropper",
39
+ data() {
40
+ return {
41
+ // 添加实例ID用于区分不同实例
42
+ instanceId: Date.now() + '-' + Math.random().toString(36).substr(2, 9),
43
+ cvsStyleHeight: '0px',
44
+ styleDisplay: 'none',
45
+ styleTop: '-10000px',
46
+ prvTop: '-10000px',
47
+ imgStyle: {},
48
+ selStyle: {},
49
+ showOper: true,
50
+ imgSrc: {
51
+ imgSrc: ''
52
+ },
53
+ btnWidth: '19%',
54
+ btnDsp: 'flex',
55
+ // 裁剪区域宽度,用于设置选择区域的宽度
56
+ arWidth: '',
57
+ // 裁剪区域高度,用于设置选择区域的高度
58
+ arHeight: '',
59
+ // 导出图片宽度,用于设置最终导出图片的宽度
60
+ expWidth: '',
61
+ // 导出图片高度,用于设置最终导出图片的高度
62
+ expHeight: '',
63
+ // 是否允许调整裁剪框大小
64
+ letChangeSize: false,
65
+
66
+ };
67
+ },
68
+ watch: {
69
+ avatarSrc() {
70
+ this.imgSrc.imgSrc = this.avatarSrc;
71
+ }
72
+ },
73
+ emits: ['avtinit', 'confirm'],
74
+ props:{
75
+ minScale: '',
76
+ maxScale: '',
77
+ canScale: true,
78
+ canRotate: true,
79
+ lockWidth: '',
80
+ lockHeight: '',
81
+ stretch: '',
82
+ lock: '',
83
+ noTab: true,
84
+ inner: false,
85
+ quality: '',
86
+ index: '',
87
+ canChangeSize: false,
88
+ areaWidth: '300rpx',
89
+ // 裁剪区域高度,用于设置选择区域的高度
90
+ areaHeight: '300rpx',
91
+ // 导出图片宽度,用于设置最终导出图片的宽度
92
+ exportWidth: '260rpx',
93
+ // 导出图片高度,用于设置最终导出图片的高度
94
+ exportHeight: '260rpx',
95
+ },
96
+ created() {
97
+ this.ctxCanvas = uni.createCanvasContext('avatar-canvas-' + this.instanceId, this);
98
+ this.ctxCanvasOper = uni.createCanvasContext('oper-canvas-' + this.instanceId, this);
99
+ this.ctxCanvasPrv = uni.createCanvasContext('prv-canvas-' + this.instanceId, this);
100
+ this.qlty = parseInt(this.quality) || 0.9;
101
+ this.imgSrc.imgSrc = this.imageSrc;
102
+ this.letRotate = (this.canRotate === false || this.inner === true) ? 0 : 1;
103
+ this.letScale = this.canScale === false ? 0 : 1;
104
+ // 是否允许调整裁剪框大小,false表示不允许,其他值表示允许
105
+ this.letChangeSize = this.canChangeSize;
106
+ this.isin = this.inner === true ? 1 : 0;
107
+ this.indx = this.index || undefined;
108
+ this.mnScale = this.minScale || 0.3;
109
+ this.mxScale = this.maxScale || 4;
110
+ this.noBar = this.noTab === true ? 1 : 0;
111
+ this.stc = this.stretch;
112
+ this.lck = this.lock;
113
+ if(this.isin) {
114
+ this.btnWidth = '24%';
115
+ this.btnDsp = 'none';
116
+ } else {
117
+ this.btnWidth = '19%';
118
+ this.btnDsp = 'flex';
119
+ }
120
+
121
+ if(this.noBar) {
122
+ this.moreHeight = 0;
123
+ this.windowResize();
124
+ } else {
125
+ uni.showTabBar({
126
+ complete:(res) => {
127
+ this.moreHeight = (res.errMsg === 'showTabBar:ok') ? 50 : 0;
128
+ this.windowResize();
129
+ }
130
+ });
131
+ }
132
+ },
133
+ methods: {
134
+ windowResize() {
135
+ let sysInfo = uni.getSystemInfoSync();
136
+ this.platform = sysInfo.platform;
137
+ this.pixelRatio = sysInfo.pixelRatio;
138
+ this.windowWidth = sysInfo.windowWidth;
139
+ // #ifdef H5
140
+ this.drawTop = sysInfo.windowTop;
141
+ this.windowHeight = sysInfo.windowHeight + sysInfo.windowBottom;
142
+ this.cvsStyleHeight = this.windowHeight - tabHeight + 'px';
143
+ // #endif
144
+ // #ifdef APP-PLUS
145
+ if(this.platform === 'android') {
146
+ this.windowHeight = sysInfo.screenHeight + sysInfo.statusBarHeight;
147
+ this.cvsStyleHeight = this.windowHeight - tabHeight + 'px';
148
+ } else {
149
+ this.windowHeight = sysInfo.windowHeight + this.moreHeight;
150
+ this.cvsStyleHeight = this.windowHeight - tabHeight + 6 + 'px';
151
+ }
152
+ // #endif
153
+ // #ifdef MP
154
+ this.windowHeight = sysInfo.windowHeight + this.moreHeight;
155
+ this.cvsStyleHeight = this.windowHeight - tabHeight - 2 + 'px';
156
+ // #endif
157
+ this.pxRatio = this.windowWidth/750;
158
+
159
+ let style = this.avatarStyle;
160
+ if(style && style !== true && (style=style.trim()) ) {
161
+ style = style.split(';');
162
+ let obj = {};
163
+ for( let v of style ) {
164
+ if(!v) continue;
165
+ v = v.trim().split(':');
166
+ if(v[1].indexOf('rpx') >= 0) {
167
+ let arr = v[1].trim().split(' ');
168
+ for( let k in arr ) {
169
+ if(!arr[k]) continue;
170
+ if(arr[k].indexOf('rpx') >= 0) {
171
+ arr[k] = parseFloat(arr[k]) * this.pxRatio + 'px';
172
+ }
173
+ }
174
+ v[1] = arr.join(' ');
175
+ }
176
+ obj[v[0].trim()] = v[1].trim();
177
+ }
178
+ this.imgStyle = obj;
179
+ }
180
+
181
+ this.expWidth && (this.expWidth = this.expWidth.indexOf('rpx') >= 0 ? parseInt(this.expWidth)*this.pxRatio : parseInt(this.expWidth));
182
+ this.expHeight && (this.expHeight = this.expHeight.indexOf('rpx') >= 0 ? parseInt(this.expHeight)*this.pxRatio : parseInt(this.expHeight));
183
+
184
+ if(this.styleDisplay === 'flex') {
185
+ this.drawInit(true);
186
+ }
187
+ this.hideImg();
188
+ },
189
+ select() {
190
+ if(this.fSelecting) return;
191
+ this.fSelecting = true;
192
+ setTimeout(()=>{ this.fSelecting = false; }, 500);
193
+
194
+ uni.chooseImage({
195
+ count: 1,
196
+ sizeType: ['original', 'compressed'],
197
+ sourceType: ['album', 'camera'],
198
+ success: (r)=>{
199
+ uni.showLoading({ mask: true });
200
+ let path = this.imgPath = r.tempFilePaths[0];
201
+ uni.getImageInfo({
202
+ src: path,
203
+ success: r => {
204
+ this.imgWidth = r.width;
205
+ this.imgHeight = r.height;
206
+ this.path = path;
207
+ if( !this.hasSel ) {
208
+ let style = this.selStyle || {};
209
+ if( this.arWidth && this.arHeight ) {
210
+ let areaWidth = this.arWidth.indexOf('rpx') >= 0 ? parseInt(this.arWidth) * this.pxRatio: parseInt(this.arWidth),
211
+ areaHeight = this.arHeight.indexOf('rpx') >= 0 ? parseInt(this.arHeight) * this.pxRatio: parseInt(this.arHeight);
212
+ style.width = areaWidth + 'px';
213
+ style.height = areaHeight + 'px';
214
+ style.top = (this.windowHeight - areaHeight - tabHeight)/2 + 'px';
215
+ style.left = (this.windowWidth - areaWidth)/2 + 'px';
216
+ } else {
217
+ uni.showModal({
218
+ title: '裁剪框的宽或高没有设置',
219
+ showCancel: false
220
+ })
221
+ return;
222
+ }
223
+ this.selStyle = style;
224
+ }
225
+
226
+ if( this.noBar ) {
227
+ this.drawInit(true);
228
+ } else {
229
+ uni.hideTabBar({
230
+ complete: () => {
231
+ this.drawInit(true);
232
+ }
233
+ });
234
+ }
235
+ },
236
+ fail: ()=>{
237
+ uni.showToast({
238
+ title: "error3",
239
+ duration: 2000,
240
+ })
241
+ },
242
+ complete() {
243
+ uni.hideLoading();
244
+ }
245
+ });
246
+ }
247
+ })
248
+ },
249
+ confirm() {
250
+ if(this.fUploading) return;
251
+ this.fUploading = true;
252
+ setTimeout(()=>{ this.fUploading = false; }, 1000)
253
+
254
+ let style = this.selStyle,
255
+ x = parseInt(style.left),
256
+ y = parseInt(style.top),
257
+ width = parseInt(style.width),
258
+ height = parseInt(style.height),
259
+ expWidth = this.expWidth || width,
260
+ expHeight = this.expHeight || height;
261
+
262
+ // #ifdef H5
263
+ // x *= this.pixelRatio;
264
+ // y *= this.pixelRatio;
265
+ expWidth = width;
266
+ expHeight = height;
267
+ // #endif
268
+
269
+ uni.showLoading({ mask: true });
270
+ this.styleDisplay = 'none';
271
+ this.styleTop = '-10000px';
272
+ this.hasSel = false;
273
+ this.hideImg();
274
+ uni.canvasToTempFilePath({
275
+ x: x,
276
+ y: y,
277
+ width: width,
278
+ height: height,
279
+ destWidth: expWidth,
280
+ destHeight: expHeight,
281
+ canvasId: 'avatar-canvas-' + this.instanceId,
282
+ fileType: 'png',
283
+ quality: this.qlty,
284
+ success: (r)=>{
285
+ r = r.tempFilePath;
286
+ // #ifdef H5
287
+ this.btop(r).then((r)=> {
288
+ if(this.expWidth && this.expHeight) {
289
+ let ctxCanvas = this.ctxCanvas;
290
+ expWidth = this.expWidth,
291
+ expHeight = this.expHeight;
292
+
293
+ ctxCanvas.drawImage(r, 0, 0, expWidth, expHeight);
294
+ ctxCanvas.draw(false,()=>{
295
+ uni.canvasToTempFilePath({
296
+ x: 0,
297
+ y: 0,
298
+ width: expWidth,
299
+ height: expHeight,
300
+ destWidth: expWidth,
301
+ destHeight: expHeight,
302
+ canvasId: 'avatar-canvas-' + this.instanceId,
303
+ fileType: 'png',
304
+ quality: this.qlty,
305
+ success: (r)=>{
306
+ r = r.tempFilePath;
307
+ this.btop(r).then((r)=> {
308
+ this.$emit("confirm", {avatar: this.imgSrc, path: r, index: this.indx, data: this.rtn});
309
+ });
310
+ },
311
+ fail: ()=>{
312
+ uni.showToast({
313
+ title: "error0",
314
+ duration: 2000,
315
+ })
316
+ }
317
+ });
318
+ });
319
+ } else {
320
+ this.$emit("confirm", {avatar: this.imgSrc, path: r, index: this.indx, data: this.rtn});
321
+ }
322
+ })
323
+ // #endif
324
+ // #ifndef H5
325
+ this.$emit("confirm", {avatar: this.imgSrc, path: r, index: this.indx, data: this.rtn});
326
+ // #endif
327
+ },
328
+ fail: (res)=>{
329
+ uni.showToast({
330
+ title: "error1",
331
+ duration: 2000,
332
+ })
333
+ },
334
+ complete: () => {
335
+ uni.hideLoading();
336
+ this.noBar || uni.showTabBar();
337
+ }
338
+ }, this);
339
+ },
340
+ // 用户点击"预览"模式下的"确认"按钮时被调用,用于将预览的裁剪结果上传
341
+ prvUpload() {
342
+ if(this.fPrvUploading) return;
343
+ this.fPrvUploading = true;
344
+ setTimeout(()=>{ this.fPrvUploading = false; }, 1000)
345
+
346
+ let style = this.selStyle,
347
+ destWidth = parseInt(style.width),
348
+ destHeight = parseInt(style.height),
349
+ prvX = this.prvX,
350
+ prvY = this.prvY,
351
+ prvWidth = this.prvWidth,
352
+ prvHeight = this.prvHeight,
353
+ expWidth = this.expWidth || prvWidth,
354
+ expHeight = this.expHeight || prvHeight;
355
+
356
+ // #ifdef H5
357
+ // prvX *= this.pixelRatio;
358
+ // prvY *= this.pixelRatio;
359
+ expWidth = prvWidth;
360
+ expHeight = prvHeight;
361
+ // #endif
362
+
363
+ uni.showLoading({ mask: true });
364
+
365
+ this.styleDisplay = 'none';
366
+ this.styleTop = '-10000px';
367
+ this.hasSel = false;
368
+ this.hideImg();
369
+ uni.canvasToTempFilePath({
370
+ x: prvX,
371
+ y: prvY,
372
+ width: prvWidth,
373
+ height: prvHeight,
374
+ destWidth: expWidth,
375
+ destHeight: expHeight,
376
+ canvasId: 'prv-canvas-' + this.instanceId,
377
+ fileType: 'png',
378
+ quality: this.qlty,
379
+ success: (r)=>{
380
+ r = r.tempFilePath;
381
+ // #ifdef H5
382
+ this.btop(r).then((r)=> {
383
+ if(this.expWidth && this.expHeight) {
384
+ let ctxCanvas = this.ctxCanvas;
385
+ expWidth = this.expWidth,
386
+ expHeight = this.expHeight;
387
+
388
+ ctxCanvas.drawImage(r, 0, 0, expWidth, expHeight);
389
+ ctxCanvas.draw(false, ()=>{
390
+ uni.canvasToTempFilePath({
391
+ x: 0,
392
+ y: 0,
393
+ width: expWidth,
394
+ height: expHeight,
395
+ destWidth: expWidth,
396
+ destHeight: expHeight,
397
+ canvasId: 'avatar-canvas-' + this.instanceId,
398
+ fileType: 'png',
399
+ quality: this.qlty,
400
+ success: (r)=>{
401
+ r = r.tempFilePath;
402
+ this.btop(r).then((r)=> {
403
+ this.$emit("confirm", {avatar: this.imgSrc, path: r, index: this.indx, data: this.rtn});
404
+ });
405
+ },
406
+ fail: ()=>{
407
+ uni.showToast({
408
+ title: "error0",
409
+ duration: 2000,
410
+ })
411
+ }
412
+ });
413
+ });
414
+ } else {
415
+ this.$emit("confirm", {avatar: this.imgSrc, path: r, index: this.indx, data: this.rtn});
416
+ }
417
+ })
418
+ // #endif
419
+ // #ifndef H5
420
+ this.$emit("confirm", {avatar: this.imgSrc, path: r, index: this.indx, data: this.rtn});
421
+ // #endif
422
+ },
423
+ fail: ()=>{
424
+ uni.showToast({
425
+ title: "error_prv",
426
+ duration: 2000,
427
+ })
428
+ },
429
+ complete: () => {
430
+ uni.hideLoading();
431
+ this.noBar || uni.showTabBar();
432
+ }
433
+ }, this);
434
+ },
435
+ drawInit(ini=false) {
436
+ let allWidth = this.windowWidth,
437
+ allHeight = this.windowHeight,
438
+ imgWidth = this.imgWidth,
439
+ imgHeight = this.imgHeight,
440
+ imgRadio = imgWidth/imgHeight,
441
+ useWidth = allWidth - 40,
442
+ useHeight = allHeight - tabHeight - 80,
443
+ pixelRatio = this.pixelRatio,
444
+ selWidth = parseInt(this.selStyle.width),
445
+ selHeight = parseInt(this.selStyle.height);
446
+
447
+ this.fixWidth = 0;
448
+ this.fixHeight = 0;
449
+ this.lckWidth = 0;
450
+ this.lckHeight = 0;
451
+ switch(this.stc) {
452
+ case 'x': this.fixWidth = 1; break;
453
+ case 'y': this.fixHeight = 1; break;
454
+ case 'long': if(imgRadio > 1) this.fixWidth = 1; else this.fixHeight = 1; break;
455
+ case 'short': if(imgRadio > 1) this.fixHeight = 1; else this.fixWidth = 1; break;
456
+ case 'longSel': if(selWidth > selHeight) this.fixWidth = 1; else this.fixHeight = 1; break;
457
+ case 'shortSel': if(selWidth > selHeight) this.fixHeight = 1; else this.fixWidth = 1; break;
458
+ }
459
+ // lck 用于控制裁剪框的宽度和高度锁定行为
460
+ // 'x': 锁定宽度,不允许水平方向调整
461
+ // 'y': 锁定高度,不允许垂直方向调整
462
+ // 'long': 根据图片长边锁定,如果图片横向较长则锁定宽度,否则锁定高度
463
+ // 'short': 根据图片短边锁定,如果图片横向较长则锁定高度,否则锁定宽度
464
+ // 'longSel': 根据选择框的长边锁定,如果选择框宽度大于高度则锁定宽度,否则锁定高度
465
+ // 'shortSel': 根据选择框的短边锁定,如果选择框宽度大于高度则锁定高度,否则锁定宽度
466
+ switch(this.lck) {
467
+ case 'x': this.lckWidth = 1; break;
468
+ case 'y': this.lckHeight = 1; break;
469
+ case 'long': if(imgRadio > 1) this.lckWidth = 1; else this.lckHeight = 1; break;
470
+ case 'short': if(imgRadio > 1) this.lckHeight = 1; else this.lckWidth = 1; break;
471
+ case 'longSel': if(selWidth > selHeight) this.lckWidth = 1; else this.lckHeight = 1; break;
472
+ case 'shortSel': if(selWidth > selHeight) this.lckHeight = 1; else this.lckWidth = 1; break;
473
+ }
474
+ if( this.fixWidth ) {
475
+ useWidth = selWidth;
476
+ useHeight = useWidth/imgRadio;
477
+ } else if( this.fixHeight ) {
478
+ useHeight = selHeight;
479
+ useWidth = useHeight*imgRadio;
480
+ } else if( imgRadio < 1 ) {
481
+ if( imgHeight < useHeight ) {
482
+ useWidth = imgWidth;
483
+ useHeight = imgHeight;
484
+ } else {
485
+ useHeight = useHeight;
486
+ useWidth = useHeight*imgRadio;
487
+ }
488
+ } else {
489
+ if( imgWidth < useWidth ) {
490
+ useWidth = imgWidth;
491
+ useHeight = imgHeight;
492
+ } else {
493
+ useWidth = useWidth;
494
+ useHeight = useWidth/imgRadio;
495
+ }
496
+ }
497
+ if( this.isin ) {
498
+ this.scaleWidth = 0;
499
+ this.scaleHeight = 0;
500
+ if(useWidth < selWidth) {
501
+ useWidth = selWidth;
502
+ useHeight = useWidth/imgRadio;
503
+ this.lckHeight = 0;
504
+ }
505
+ if(useHeight < selHeight) {
506
+ useHeight = selHeight;
507
+ useWidth = useHeight*imgRadio;
508
+ this.lckWidth = 0;
509
+ }
510
+ }
511
+
512
+ this.scaleSize = 1;
513
+ this.rotateDeg = 0;
514
+ this.posWidth = (allWidth-useWidth)/2;
515
+ this.posHeight = (allHeight-useHeight-tabHeight)/2;
516
+ this.useWidth = useWidth;
517
+ this.useHeight = useHeight;
518
+
519
+ let style = this.selStyle,
520
+ left = parseInt(style.left),
521
+ top = parseInt(style.top),
522
+ width = parseInt(style.width),
523
+ height = parseInt(style.height),
524
+ canvas = this.canvas,
525
+ canvasOper = this.canvasOper,
526
+ ctxCanvas = this.ctxCanvas,
527
+ ctxCanvasOper = this.ctxCanvasOper;
528
+
529
+ ctxCanvasOper.setLineWidth(3);
530
+ ctxCanvasOper.setStrokeStyle('grey');
531
+ ctxCanvasOper.setGlobalAlpha(0.4);
532
+ ctxCanvasOper.setFillStyle('black');
533
+ ctxCanvasOper.strokeRect( left, top, width, height );
534
+ ctxCanvasOper.fillRect(0, 0, this.windowWidth, top);
535
+ ctxCanvasOper.fillRect(0, top, left, height);
536
+ ctxCanvasOper.fillRect(0, top+height, this.windowWidth, this.windowHeight-height-top-tabHeight);
537
+ ctxCanvasOper.fillRect(left+width, top,this.windowWidth-width-left, height);
538
+ ctxCanvasOper.setStrokeStyle('red');
539
+ ctxCanvasOper.moveTo(left+20, top);ctxCanvasOper.lineTo(left, top);ctxCanvasOper.lineTo(left, top+20);
540
+ ctxCanvasOper.moveTo(left+width-20, top);ctxCanvasOper.lineTo(left+width, top);ctxCanvasOper.lineTo(left+width, top+20);
541
+ ctxCanvasOper.moveTo(left+20, top+height);ctxCanvasOper.lineTo(left, top+height);ctxCanvasOper.lineTo(left, top+height-20);
542
+ ctxCanvasOper.moveTo(left+width-20, top+height);ctxCanvasOper.lineTo(left+width, top+height);ctxCanvasOper.lineTo(left+width, top+height-20);
543
+
544
+ // 绘制控制点(四个角)
545
+ const controlPointSize = 10;
546
+ ctxCanvasOper.setFillStyle('white');
547
+ ctxCanvasOper.setStrokeStyle('grey');
548
+ ctxCanvasOper.setLineWidth(1);
549
+ // 左上角
550
+ ctxCanvasOper.fillRect(left - controlPointSize/2, top - controlPointSize/2, controlPointSize, controlPointSize);
551
+ ctxCanvasOper.strokeRect(left - controlPointSize/2, top - controlPointSize/2, controlPointSize, controlPointSize);
552
+ // 右上角
553
+ ctxCanvasOper.fillRect(left + width - controlPointSize/2, top - controlPointSize/2, controlPointSize, controlPointSize);
554
+ ctxCanvasOper.strokeRect(left + width - controlPointSize/2, top - controlPointSize/2, controlPointSize, controlPointSize);
555
+ // 左下角
556
+ ctxCanvasOper.fillRect(left - controlPointSize/2, top + height - controlPointSize/2, controlPointSize, controlPointSize);
557
+ ctxCanvasOper.strokeRect(left - controlPointSize/2, top + height - controlPointSize/2, controlPointSize, controlPointSize);
558
+ // 右下角
559
+ ctxCanvasOper.fillRect(left + width - controlPointSize/2, top + height - controlPointSize/2, controlPointSize, controlPointSize);
560
+ ctxCanvasOper.strokeRect(left + width - controlPointSize/2, top + height - controlPointSize/2, controlPointSize, controlPointSize);
561
+
562
+ ctxCanvasOper.stroke();
563
+
564
+ ctxCanvasOper.draw(false, ()=>{
565
+ if( ini ) {
566
+ this.styleDisplay = 'flex';
567
+ // #ifdef H5
568
+ this.styleTop = this.drawTop + 'px';
569
+ // #endif
570
+ // #ifndef H5
571
+ this.styleTop = '0';
572
+ // #endif
573
+ ctxCanvas.setFillStyle('black');
574
+ this.drawImage();
575
+ }
576
+ });
577
+
578
+ this.$emit("avtinit");
579
+ },
580
+ drawImage() {
581
+ let tm_now = Date.now();
582
+ if(tm_now - this.drawTm < 20) return;
583
+ this.drawTm = tm_now;
584
+ let ctxCanvas = this.ctxCanvas;
585
+ ctxCanvas.fillRect(0, 0, this.windowWidth, this.windowHeight-tabHeight);
586
+ ctxCanvas.translate(this.posWidth+this.useWidth/2, this.posHeight+this.useHeight/2);
587
+ ctxCanvas.scale(this.scaleSize, this.scaleSize);
588
+ ctxCanvas.rotate(this.rotateDeg * Math.PI/180);
589
+ ctxCanvas.drawImage(this.imgPath, -this.useWidth/2, -this.useHeight/2, this.useWidth, this.useHeight);
590
+ ctxCanvas.draw(false);
591
+ },
592
+ hideImg() {
593
+ this.prvImg = '';
594
+ this.prvTop = '-10000px';
595
+ this.showOper = true;
596
+ this.prvImgData = null;
597
+ this.target = null;
598
+ },
599
+ close() {
600
+ this.styleDisplay = 'none';
601
+ this.styleTop = '-10000px';
602
+ this.hasSel = false;
603
+ this.hideImg();
604
+ this.noBar || uni.showTabBar();
605
+ },
606
+ preview() {
607
+ if(this.fPreviewing) return;
608
+ this.fPreviewing = true;
609
+ setTimeout(()=>{ this.fPreviewing = false; }, 1000);
610
+ let style = this.selStyle,
611
+ x = parseInt(style.left),
612
+ y = parseInt(style.top),
613
+ width = parseInt(style.width),
614
+ height = parseInt(style.height);
615
+
616
+ uni.showLoading({ mask: true });
617
+ // console.log('size', x, y, width, height)
618
+ uni.canvasToTempFilePath({
619
+ x: x,
620
+ y: y,
621
+ width: width,
622
+ height: height,
623
+ canvasId: 'avatar-canvas-' + this.instanceId,
624
+ fileType: 'png',
625
+ quality: this.qlty,
626
+ success: (r)=>{
627
+ // console.log(r)
628
+ this.prvImgTmp = r = r.tempFilePath;
629
+
630
+ let ctxCanvasPrv = this.ctxCanvasPrv,
631
+ prvX = this.windowWidth,
632
+ prvY = parseInt(this.cvsStyleHeight),
633
+ prvWidth = parseInt(this.selStyle.width),
634
+ prvHeight = parseInt(this.selStyle.height),
635
+ useWidth = prvX - 40,
636
+ useHeight = prvY - 80,
637
+ radio = useWidth/prvWidth,
638
+ rHeight = prvHeight*radio;
639
+ if(rHeight < useHeight) {
640
+ prvWidth = useWidth;
641
+ prvHeight = rHeight;
642
+ } else {
643
+ radio = useHeight/prvHeight;
644
+ prvWidth *= radio;
645
+ prvHeight = useHeight;
646
+ }
647
+ ctxCanvasPrv.setFillStyle('black');
648
+ ctxCanvasPrv.fillRect(0, 0, prvX, prvY);
649
+ ctxCanvasPrv.fillRect(x, y, width, height);
650
+ this.prvX = prvX = (prvX-prvWidth)/2;
651
+ this.prvY = prvY = (prvY-prvHeight)/2;
652
+ this.prvWidth = prvWidth;
653
+ this.prvHeight = prvHeight;
654
+ ctxCanvasPrv.drawImage(r, prvX, prvY, prvWidth, prvHeight);
655
+ ctxCanvasPrv.draw(false, () => {
656
+ // #ifdef H5
657
+ this.btop(this.prvImgTmp).then((r)=> {
658
+ this.showOper = false;
659
+ this.prvTop = this.drawTop + 'px';
660
+ })
661
+ // #endif
662
+ // #ifndef H5
663
+ if( this.platform != 'android' ) {
664
+ this.showOper = false;
665
+ }
666
+ this.prvTop = '0';
667
+ // #endif
668
+ });
669
+ },
670
+ fail: ()=>{
671
+ uni.showToast({
672
+ title: "error2",
673
+ duration: 2000,
674
+ })
675
+ },
676
+ complete: () => {
677
+ uni.hideLoading();
678
+ }
679
+ }, this);
680
+ },
681
+ chooseImage(index=undefined, params=undefined, data=undefined) {
682
+ if(params) {
683
+ console.log(params)
684
+ let areaWidth = params.areaWidth || this.areaWidth,
685
+ areaHeight = params.areaHeight || this.areaHeight,
686
+ expWidth = params.exportWidth || this.exportWidth,
687
+ expHeight = params.exportHeight || this.exportHeight,
688
+ quality = params.quality,
689
+ canRotate = params.canRotate,
690
+ canScale = params.canScale,
691
+ canChangeSize = params.canChangeSize,
692
+ minScale = params.minScale,
693
+ maxScale = params.maxScale,
694
+ stretch = params.stretch,
695
+ inner = params.inner,
696
+ lock = params.lock;
697
+ console.log('areaWidth', this.areaWidth)
698
+
699
+ expWidth && (this.expWidth = expWidth.indexOf('rpx') >= 0 ? parseInt(expWidth)*this.pxRatio : parseInt(expWidth));
700
+ expHeight && (this.expHeight = expHeight.indexOf('rpx') >= 0 ? parseInt(expHeight)*this.pxRatio : parseInt(expHeight));
701
+ this.letRotate = canRotate === false ? 0 : 1;
702
+ this.letScale = canScale === false ? 0 : 1;
703
+ // 设置是否允许调整裁剪框大小
704
+ this.letChangeSize = canChangeSize || false;
705
+ this.qlty = parseInt(quality) || 0.9;
706
+ this.mnScale = minScale || 0.3;
707
+ this.mxScale = maxScale || 4;
708
+ this.stc = stretch;
709
+ this.isin = inner === true ? 1 : 0;
710
+ this.lck = lock;
711
+ if(this.isin) {
712
+ this.btnWidth = '24%';
713
+ this.btnDsp = 'none';
714
+ } else {
715
+ this.btnWidth = '19%';
716
+ this.btnDsp = 'flex';
717
+ }
718
+
719
+ if( areaWidth && areaHeight) {
720
+ areaWidth = areaWidth.indexOf('rpx') >= 0 ? parseInt(areaWidth) * this.pxRatio: parseInt(areaWidth);
721
+ areaHeight = areaHeight.indexOf('rpx') >= 0 ? parseInt(areaHeight) * this.pxRatio: parseInt(areaHeight);
722
+ this.selStyle.width = areaWidth + 'px';
723
+ this.selStyle.height = areaHeight + 'px';
724
+ this.selStyle.top = (this.windowHeight - areaHeight - tabHeight)/2 + 'px';
725
+ this.selStyle.left = (this.windowWidth - areaWidth)/2 + 'px';
726
+ // console.log(this.selStyle);
727
+ this.hasSel = true;
728
+ }
729
+ }
730
+ this.rtn = data;
731
+ this.indx = index;
732
+ this.select();
733
+ },
734
+ rotate() {
735
+ // #ifdef APP-PLUS
736
+ if(this.platform === 'android') {
737
+ if(this.fRotateing) return;
738
+ this.fRotateing = true;
739
+ setTimeout(()=>{ this.fRotateing = false; }, 500);
740
+ }
741
+ // #endif
742
+
743
+ // if(this.letRotate) {
744
+ this.rotateDeg += 90 - this.rotateDeg%90;
745
+ this.drawImage();
746
+ // }
747
+ },
748
+ start(e) {
749
+ let touches = e.touches,
750
+ touch0 = touches[0],
751
+ touch1 = touches[1];
752
+
753
+ this.touch0 = touch0;
754
+ this.touch1 = touch1;
755
+
756
+ if( touch1 ) {
757
+ let x = touch1.x - touch0.x,
758
+ y = touch1.y - touch0.y;
759
+ this.fgDistance = Math.sqrt(x * x + y * y);
760
+ } else {
761
+ // 只有在允许调整大小时才检查控制点
762
+ if (this.letChangeSize) {
763
+ // 检查是否点击在控制点上
764
+ const controlPointSize = 20;
765
+ const x = touch0.x;
766
+ const y = touch0.y;
767
+ const style = this.selStyle;
768
+ const left = parseInt(style.left);
769
+ const top = parseInt(style.top);
770
+ const width = parseInt(style.width);
771
+ const height = parseInt(style.height);
772
+
773
+ // 检查四个控制点
774
+ if (Math.abs(x - left) < controlPointSize && Math.abs(y - top) < controlPointSize) {
775
+ this.resizeHandle = 'top-left';
776
+ } else if (Math.abs(x - (left + width)) < controlPointSize && Math.abs(y - top) < controlPointSize) {
777
+ this.resizeHandle = 'top-right';
778
+ } else if (Math.abs(x - left) < controlPointSize && Math.abs(y - (top + height)) < controlPointSize) {
779
+ this.resizeHandle = 'bottom-left';
780
+ } else if (Math.abs(x - (left + width)) < controlPointSize && Math.abs(y - (top + height)) < controlPointSize) {
781
+ this.resizeHandle = 'bottom-right';
782
+ } else {
783
+ this.resizeHandle = null;
784
+ }
785
+ } else {
786
+ this.resizeHandle = null;
787
+ }
788
+ }
789
+ },
790
+ move(e) {
791
+ let touches = e.touches,
792
+ touch0 = touches[0],
793
+ touch1 = touches[1];
794
+
795
+ if( touch1 ) {
796
+ let x = touch1.x - touch0.x,
797
+ y = touch1.y - touch0.y,
798
+ fgDistance = Math.sqrt(x * x + y * y),
799
+ scaleSize = 0.005 * (fgDistance - this.fgDistance),
800
+ beScaleSize = this.scaleSize + scaleSize;
801
+
802
+ do {
803
+ if( !this.letScale ) break;
804
+ if( beScaleSize < this.mnScale) break;
805
+ if( beScaleSize > this.mxScale) break;
806
+ if(this.isin) {
807
+ let imgWidth = this.useWidth*beScaleSize,
808
+ imgHeight = this.useHeight*beScaleSize,
809
+ rx0 = this.posWidth+this.useWidth/2,
810
+ ry0 = this.posHeight+this.useHeight/2,
811
+ l = rx0-imgWidth/2, t = ry0-imgHeight/2,
812
+ r = l+imgWidth, b = t+imgHeight,
813
+ left = parseInt(this.selStyle.left),
814
+ top = parseInt(this.selStyle.top),
815
+ width = parseInt(this.selStyle.width),
816
+ height = parseInt(this.selStyle.height);
817
+ if(left < l || left+width > r || top < t || top+height > b) break;
818
+ this.scaleWidth = (this.useWidth-imgWidth)/2;
819
+ this.scaleHeight = (this.useHeight-imgHeight)/2;
820
+ }
821
+
822
+ this.scaleSize = beScaleSize;
823
+ } while(0);
824
+ this.fgDistance = fgDistance;
825
+
826
+ if(touch1.x !== touch0.x && this.letRotate) {
827
+ x = (this.touch1.y - this.touch0.y)/(this.touch1.x - this.touch0.x);
828
+ y = (touch1.y - touch0.y)/(touch1.x - touch0.x);
829
+ this.rotateDeg += Math.atan((y-x)/(1+x*y)) * 180/Math.PI;
830
+ this.touch0 = touch0;
831
+ this.touch1 = touch1;
832
+ }
833
+
834
+ this.drawImage();
835
+ } else if( this.touch0 ) {
836
+ // 只有在允许调整大小时才处理裁剪框大小调整
837
+ if (this.resizeHandle && this.letChangeSize) {
838
+ const style = {...this.selStyle};
839
+ const left = parseInt(style.left);
840
+ const top = parseInt(style.top);
841
+ const width = parseInt(style.width);
842
+ const height = parseInt(style.height);
843
+ const minWidth = 50;
844
+ const minHeight = 50;
845
+
846
+ switch (this.resizeHandle) {
847
+ case 'top-left':
848
+ style.left = touch0.x + 'px';
849
+ style.top = touch0.y + 'px';
850
+ style.width = (left + width - touch0.x) + 'px';
851
+ style.height = (top + height - touch0.y) + 'px';
852
+ break;
853
+ case 'top-right':
854
+ style.top = touch0.y + 'px';
855
+ style.width = (touch0.x - left) + 'px';
856
+ style.height = (top + height - touch0.y) + 'px';
857
+ break;
858
+ case 'bottom-left':
859
+ style.left = touch0.x + 'px';
860
+ style.width = (left + width - touch0.x) + 'px';
861
+ style.height = (touch0.y - top) + 'px';
862
+ break;
863
+ case 'bottom-right':
864
+ style.width = (touch0.x - left) + 'px';
865
+ style.height = (touch0.y - top) + 'px';
866
+ break;
867
+ }
868
+
869
+ // 确保最小尺寸
870
+ if (parseInt(style.width) >= minWidth && parseInt(style.height) >= minHeight) {
871
+ // 确保裁剪框不超出屏幕边界
872
+ if (parseInt(style.left) >= 0 &&
873
+ parseInt(style.top) >= 0 &&
874
+ (parseInt(style.left) + parseInt(style.width)) <= this.windowWidth &&
875
+ (parseInt(style.top) + parseInt(style.height)) <= (this.windowHeight - tabHeight)) {
876
+ this.selStyle = style;
877
+ // 重新绘制操作层
878
+ this.drawInit();
879
+ }
880
+ }
881
+ } else {
882
+ // 原有的移动图片逻辑
883
+ let x = touch0.x - this.touch0.x,
884
+ y = touch0.y - this.touch0.y,
885
+ beX = this.posWidth + x,
886
+ beY = this.posHeight + y;
887
+ if(this.isin) {
888
+ let imgWidth = this.useWidth*this.scaleSize,
889
+ imgHeight = this.useHeight*this.scaleSize,
890
+ rx0 = beX+this.useWidth/2,
891
+ ry0 = beY+this.useHeight/2,
892
+ l = rx0-imgWidth/2, t = ry0-imgHeight/2,
893
+ r = l+imgWidth, b = t+imgHeight,
894
+ left = parseInt(this.selStyle.left),
895
+ top = parseInt(this.selStyle.top),
896
+ width = parseInt(this.selStyle.width),
897
+ height = parseInt(this.selStyle.height);
898
+ if(!this.lckWidth && Math.abs(x) < 100) {
899
+ if(left >= l && left+width <= r) {
900
+ this.posWidth = beX;
901
+ } else if(left < l){
902
+ this.posWidth = left - this.scaleWidth;
903
+ } else if(left+width > r) {
904
+ this.posWidth = left-(imgWidth-width) - this.scaleWidth;
905
+ }
906
+ }
907
+ if(!this.lckHeight && Math.abs(y) < 100) {
908
+ if(top >= t && top+height <= b) {
909
+ this.posHeight = beY;
910
+ } else if(top < t) {
911
+ this.posHeight = top - this.scaleHeight;
912
+ } else if(top+height > b) {
913
+ this.posHeight = top-(imgHeight-height) - this.scaleHeight;
914
+ }
915
+ }
916
+ } else {
917
+ if( Math.abs(x) < 100 && !this.lckWidth) this.posWidth = beX;
918
+ if( Math.abs(y) < 100 && !this.lckHeight) this.posHeight = beY;
919
+ }
920
+
921
+ this.touch0 = touch0;
922
+ this.drawImage();
923
+ }
924
+ }
925
+ },
926
+ end(e) {
927
+ let touches = e.touches,
928
+ touch0 = touches && touches[0],
929
+ touch1 = touches && touches[1];
930
+ if(touch0) {
931
+ this.touch0 = touch0;
932
+ } else {
933
+ this.touch0 = null;
934
+ this.touch1 = null;
935
+ this.resizeHandle = null; // 重置调整手柄
936
+ }
937
+ },
938
+ getImgData() {
939
+ return new Promise((resolve, reject)=>{
940
+ let prvX = this.prvX,
941
+ prvY = this.prvY,
942
+ prvWidth = this.prvWidth,
943
+ prvHeight = this.prvHeight;
944
+ // #ifdef APP-PLUS||H5
945
+ prvX *= this.pixelRatio;
946
+ prvY *= this.pixelRatio;
947
+ prvWidth *= this.pixelRatio;
948
+ prvHeight *= this.pixelRatio;
949
+ // #endif
950
+ uni.canvasGetImageData({
951
+ canvasId: 'prv-canvas-' + this.instanceId,
952
+ x: prvX,
953
+ y: prvY,
954
+ width: prvWidth,
955
+ height: prvHeight,
956
+ success(res) {
957
+ resolve(res.data);
958
+ },
959
+ fail(err) {
960
+ reject(err);
961
+ }
962
+ }, this);
963
+ });
964
+ },
965
+ async colorChange(e) {
966
+ let tm_now = Date.now();
967
+ if(tm_now - this.prvTm < 100) return;
968
+ this.prvTm = tm_now;
969
+
970
+ uni.showLoading({ mask: true });
971
+
972
+ if( !this.prvImgData ) {
973
+ if( !(this.prvImgData = await this.getImgData().catch((res)=>{
974
+ uni.showToast({
975
+ title: "error_read",
976
+ duration: 2000,
977
+ })
978
+ }))) return;
979
+ this.target = new Uint8ClampedArray(this.prvImgData.length);
980
+ }
981
+
982
+ let data = this.prvImgData,
983
+ target = this.target,
984
+ i = e.detail.value,
985
+ r,g,b,a,h,s,l,d,p,q,t,min,max,hK,tR,tG,tB;
986
+
987
+ if( i === 0 ) {
988
+ target = data;
989
+ } else {
990
+ i = (i+100)/200;
991
+ if( i < 0.005 ) i = 0;
992
+ if( i > 0.995 ) i = 1;
993
+ for( let n = data.length-1; n >= 0; n-=4 ) {
994
+ r = data[n-3] / 255;
995
+ g = data[n-2] / 255;
996
+ b = data[n-1] / 255;
997
+ max = Math.max(r,g,b);
998
+ min = Math.min(r,g,b);
999
+ d = max-min;
1000
+ if ( max === min ){
1001
+ h = 0 ;
1002
+ }else if( max === r && g>=b ){
1003
+ h = 60*( (g-b)/d ) ;
1004
+ }else if( max === r && g<b ){
1005
+ h = 60*( (g-b)/d ) + 360 ;
1006
+ }else if( max === g ){
1007
+ h = 60*( (b-r)/d ) + 120 ;
1008
+ }else if( max === b ){
1009
+ h = 60*( (r-g)/d ) + 240 ;
1010
+ }
1011
+ l = (max+min)/2 ;
1012
+ if ( l===0 || max===min ){
1013
+ s = 0 ;
1014
+ }else if( 0<l && l<=0.5 ){
1015
+ s = d/(2*l) ;
1016
+ }else if( l>0.5 ){
1017
+ s = d/(2-2*l) ;
1018
+ }
1019
+ data[n] && (a = data[n]);
1020
+
1021
+ if ( i < 0.5 ){
1022
+ s = s*i/0.5 ;
1023
+ }else if ( i > 0.5 ){
1024
+ s = 2*s + 2*i - (s*i/0.5) - 1 ;
1025
+ }
1026
+
1027
+ if ( s === 0 ){
1028
+ r = g = b = Math.round( l*255 ) ;
1029
+ }else{
1030
+ if ( l<0.5 ){
1031
+ q = l * ( 1 + s ) ;
1032
+ }else if( l>=0.5 ){
1033
+ q = l + s - ( l * s ) ;
1034
+ }
1035
+ p = 2*l-q ;
1036
+ hK = h/360 ;
1037
+ tR = hK + 1/3 ;
1038
+ tG = hK ;
1039
+ tB = hK - 1/3 ;
1040
+ let correctRGB = (t)=>{
1041
+ if( t<0 ){
1042
+ return t + 1.0 ;
1043
+ }
1044
+ if( t>1 ){
1045
+ return t - 1.0 ;
1046
+ }
1047
+ return t ;
1048
+ } ;
1049
+ let createRGB = (t)=>{
1050
+ if ( t<(1/6) ){
1051
+ return p+((q-p)*6*t) ;
1052
+ }else if( t>=(1/6) && t<(1/2) ){
1053
+ return q ;
1054
+ }else if( t>=(1/2) && t<(2/3) ){
1055
+ return p+((q-p)*6*((2/3)-t)) ;
1056
+ }
1057
+ return p ;
1058
+ } ;
1059
+ r = tR = Math.round( createRGB( correctRGB( tR ) )*255 ) ;
1060
+ g = tG = Math.round( createRGB( correctRGB( tG ) )*255 ) ;
1061
+ b = tB = Math.round( createRGB( correctRGB( tB ) )*255 ) ;
1062
+ }
1063
+ a && ( target[n] = a ) ;
1064
+ target[n-3] = r;
1065
+ target[n-2] = g;
1066
+ target[n-1] = b;
1067
+ }
1068
+ }
1069
+ let prvX = this.prvX,
1070
+ prvY = this.prvY,
1071
+ prvWidth = this.prvWidth,
1072
+ prvHeight = this.prvHeight;
1073
+
1074
+ this.ctxCanvasPrv.setFillStyle('black');
1075
+ this.ctxCanvasPrv.fillRect(prvX, prvY, prvWidth, prvHeight);
1076
+ this.ctxCanvasPrv.draw(true);
1077
+
1078
+ // #ifdef APP-PLUS||H5
1079
+ prvX *= this.pixelRatio;
1080
+ prvY *= this.pixelRatio;
1081
+ prvWidth *= this.pixelRatio;
1082
+ prvHeight *= this.pixelRatio;
1083
+ // #endif
1084
+ uni.canvasPutImageData({
1085
+ canvasId: 'prv-canvas-' + this.instanceId,
1086
+ x: prvX,
1087
+ y: prvY,
1088
+ width: prvWidth,
1089
+ height: prvHeight,
1090
+ data: target,
1091
+ fail() {
1092
+ uni.showToast({
1093
+ title: 'error_put',
1094
+ duration: 2000
1095
+ })
1096
+ },
1097
+ complete() {
1098
+ uni.hideLoading();
1099
+ }
1100
+ }, this);
1101
+ },
1102
+ btop(base64) {
1103
+ return new Promise(function(resolve, reject) {
1104
+ var arr = base64.split(','),
1105
+ mime = arr[0].match(/:(.*?);/)[1],
1106
+ bstr = atob(arr[1]),
1107
+ n = bstr.length,
1108
+ u8arr = new Uint8Array(n);
1109
+ while (n--) {
1110
+ u8arr[n] = bstr.charCodeAt(n);
1111
+ }
1112
+ return resolve((window.URL || window.webkitURL).createObjectURL(new Blob([u8arr], { type: mime })));
1113
+ });
1114
+ },
1115
+ }
1116
+ }
1117
+ </script>
1118
+
1119
+ <style lang="scss" scoped>
1120
+ .u-cropper {
1121
+ .my-canvas{
1122
+ display: flex;
1123
+ position: fixed !important;
1124
+ background: #000000;
1125
+ left: 0;
1126
+ z-index: 100000;
1127
+ width: 100%;
1128
+ }
1129
+ .my-avatar {
1130
+ width: 150rpx;
1131
+ height: 150rpx;
1132
+ border-radius: 100%;
1133
+ }
1134
+ .oper-canvas {
1135
+ display: flex;
1136
+ position: fixed !important;
1137
+ left: 0;
1138
+ z-index: 100001;
1139
+ width: 100%;
1140
+ }
1141
+ .prv-canvas {
1142
+ display: flex;
1143
+ position: fixed !important;
1144
+ background: #000000;
1145
+ left: 0;
1146
+ z-index: 200000;
1147
+ width: 100%;
1148
+ }
1149
+ .oper-wrapper {
1150
+ height: 50px;
1151
+ position: fixed !important;
1152
+ box-sizing: border-box;
1153
+ border: 1px solid #F1F1F1;
1154
+ background: #ffffff;
1155
+ width: 100%;
1156
+ left: 0;
1157
+ bottom: 0;
1158
+ z-index: 100009;
1159
+ flex-direction: row;
1160
+ }
1161
+ .oper {
1162
+ display: flex;
1163
+ flex-direction: column;
1164
+ justify-content: center;
1165
+ padding: 10rpx 20rpx;
1166
+ width: 100%;
1167
+ height: 100%;
1168
+ box-sizing: border-box;
1169
+ align-self: center;
1170
+ }
1171
+ .btn-wrapper {
1172
+ display: flex;
1173
+ flex-direction: row;
1174
+ /* #ifndef H5 */
1175
+ flex-grow: 1;
1176
+ /* #endif */
1177
+ /* #ifdef H5 */
1178
+ height: 50px;
1179
+ /* #endif */
1180
+ justify-content: space-between;
1181
+ }
1182
+ .btn-wrapper view {
1183
+ display: flex;
1184
+ align-items: center;
1185
+ justify-content: center;
1186
+ font-size: 16px;
1187
+ color: #333;
1188
+ border: 1px solid #f1f1f1;
1189
+ border-radius: 6%;
1190
+ }
1191
+ .hover {
1192
+ background: #f1f1f1;
1193
+ border-radius: 6%;
1194
+ }
1195
+ .clr-wrapper {
1196
+ display: flex;
1197
+ flex-direction: row;
1198
+ flex-grow: 1;
1199
+ }
1200
+ .clr-wrapper view {
1201
+ display: flex;
1202
+ align-items: center;
1203
+ justify-content: center;
1204
+ font-size: 16px;
1205
+ color: #333;
1206
+ border: 1px solid #f1f1f1;
1207
+ border-radius: 6%;
1208
+ }
1209
+ .my-slider {
1210
+ flex-grow: 1;
1211
+ }
1212
+ }
1213
+ </style>
@@ -161,7 +161,7 @@
161
161
  $u-icon-error: $u-error !default;
162
162
  $u-icon-label-line-height:1 !default;
163
163
 
164
- /* #ifdef MP-QQ || MP-TOUTIAO || MP-BAIDU || MP-KUAISHOU || MP-XHS */
164
+ /* #ifdef APP || MP-QQ || MP-TOUTIAO || MP-BAIDU || MP-KUAISHOU || MP-XHS */
165
165
  // 2025/04/09在App/微信/支付宝/鸿蒙元服务已改用uni.loadFontFace加载字体
166
166
  @font-face {
167
167
  font-family: 'uicon-iconfont';
package/package.json CHANGED
@@ -2,8 +2,8 @@
2
2
  "id": "uview-plus",
3
3
  "name": "uview-plus",
4
4
  "displayName": "零云®uview-plus3.0重磅发布,全面的Vue3鸿蒙跨端移动组件库,组件丰富维护更新稳定。",
5
- "version": "3.4.83",
6
- "description": "零云®uview-plus已兼容vue3,100+全面的组件和便捷的工具会让您信手拈来,如鱼得水。",
5
+ "version": "3.4.85",
6
+ "description": "零云®uview-plus已兼容vue3,100+全面的组件和便捷的工具会让您信手拈来。近期新增拖动排序、条码、图片裁剪、下拉刷新、虚拟列表等。",
7
7
  "keywords": [
8
8
  "uview",
9
9
  "uview-plus",