hy-app 0.4.9 → 0.4.11
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/components/hy-empty/hy-empty.vue +0 -1
- package/components/hy-empty/icon.ts +27 -7
- package/components/hy-grid/hy-grid.vue +2 -2
- package/components/hy-image/hy-image.vue +8 -6
- package/components/hy-qrcode/hy-qrcode.vue +24 -11
- package/components/hy-qrcode/index.scss +7 -6
- package/components/hy-qrcode/qrcode.js +134 -0
- package/components/hy-search/hy-search.vue +13 -6
- package/components/hy-search/index.scss +4 -0
- package/components/hy-watermark/hy-watermark.vue +409 -17
- package/libs/composables/useShare.ts +12 -0
- package/libs/utils/inspect.ts +69 -43
- package/package.json +2 -2
- package/web-types.json +1 -1
|
@@ -38,7 +38,22 @@ defineOptions({});
|
|
|
38
38
|
|
|
39
39
|
// const props = withDefaults(defineProps<IProps>(), defaultProps)
|
|
40
40
|
const props = defineProps({
|
|
41
|
-
/**
|
|
41
|
+
/** 显示主标题 */
|
|
42
|
+
title: {
|
|
43
|
+
type: String,
|
|
44
|
+
default: "",
|
|
45
|
+
},
|
|
46
|
+
/** 主标题颜色 */
|
|
47
|
+
titleColor: {
|
|
48
|
+
type: String,
|
|
49
|
+
default: "",
|
|
50
|
+
},
|
|
51
|
+
/** 主标题字体大小,单位px */
|
|
52
|
+
titleSize: {
|
|
53
|
+
type: Number,
|
|
54
|
+
default: 0,
|
|
55
|
+
},
|
|
56
|
+
/** 显示副标题内容 */
|
|
42
57
|
content: {
|
|
43
58
|
type: String,
|
|
44
59
|
default: "",
|
|
@@ -264,6 +279,9 @@ function createWaterMark(
|
|
|
264
279
|
const contentWidth = width * pixelRatio.value;
|
|
265
280
|
const contentHeight = height * pixelRatio.value;
|
|
266
281
|
const fontSize = size * pixelRatio.value;
|
|
282
|
+
// 标题字体大小:如果设置了titleSize则使用titleSize,否则使用size的1.2倍
|
|
283
|
+
const titleFontSize = props.titleSize > 0 ? props.titleSize * pixelRatio.value : fontSize * 1.2;
|
|
284
|
+
|
|
267
285
|
// #ifndef H5
|
|
268
286
|
if (canvasOffScreenable.value) {
|
|
269
287
|
createOffscreenCanvas(
|
|
@@ -281,6 +299,8 @@ function createWaterMark(
|
|
|
281
299
|
image,
|
|
282
300
|
imageHeight,
|
|
283
301
|
imageWidth,
|
|
302
|
+
props.title,
|
|
303
|
+
titleFontSize
|
|
284
304
|
);
|
|
285
305
|
} else {
|
|
286
306
|
createCanvas(
|
|
@@ -293,6 +313,8 @@ function createWaterMark(
|
|
|
293
313
|
image,
|
|
294
314
|
imageHeight,
|
|
295
315
|
imageWidth,
|
|
316
|
+
props.title,
|
|
317
|
+
titleFontSize
|
|
296
318
|
);
|
|
297
319
|
}
|
|
298
320
|
// #endif
|
|
@@ -312,6 +334,8 @@ function createWaterMark(
|
|
|
312
334
|
image,
|
|
313
335
|
imageHeight,
|
|
314
336
|
imageWidth,
|
|
337
|
+
props.title,
|
|
338
|
+
titleFontSize
|
|
315
339
|
);
|
|
316
340
|
// #endif
|
|
317
341
|
}
|
|
@@ -348,6 +372,8 @@ function createOffscreenCanvas(
|
|
|
348
372
|
image: string,
|
|
349
373
|
imageHeight: number,
|
|
350
374
|
imageWidth: number,
|
|
375
|
+
title: string,
|
|
376
|
+
titleFontSize: number
|
|
351
377
|
) {
|
|
352
378
|
// 创建离屏canvas
|
|
353
379
|
const canvas: any = uni.createOffscreenCanvas({
|
|
@@ -357,7 +383,29 @@ function createOffscreenCanvas(
|
|
|
357
383
|
});
|
|
358
384
|
const ctx: any = canvas.getContext("2d");
|
|
359
385
|
if (ctx) {
|
|
360
|
-
if (image) {
|
|
386
|
+
if (image && (title || content)) {
|
|
387
|
+
// 图片和文字同时显示
|
|
388
|
+
const img = canvas.createImage() as HTMLImageElement;
|
|
389
|
+
drawImageAndTextOffScreen(
|
|
390
|
+
ctx,
|
|
391
|
+
img,
|
|
392
|
+
image,
|
|
393
|
+
imageHeight,
|
|
394
|
+
imageWidth,
|
|
395
|
+
title,
|
|
396
|
+
content,
|
|
397
|
+
rotate,
|
|
398
|
+
contentWidth,
|
|
399
|
+
contentHeight,
|
|
400
|
+
fontSize,
|
|
401
|
+
titleFontSize,
|
|
402
|
+
fontFamily,
|
|
403
|
+
fontStyle,
|
|
404
|
+
fontWeight,
|
|
405
|
+
color,
|
|
406
|
+
canvas,
|
|
407
|
+
);
|
|
408
|
+
} else if (image) {
|
|
361
409
|
const img = canvas.createImage() as HTMLImageElement;
|
|
362
410
|
drawImageOffScreen(
|
|
363
411
|
ctx,
|
|
@@ -373,7 +421,7 @@ function createOffscreenCanvas(
|
|
|
373
421
|
} else {
|
|
374
422
|
drawTextOffScreen(
|
|
375
423
|
ctx,
|
|
376
|
-
|
|
424
|
+
title,
|
|
377
425
|
contentWidth,
|
|
378
426
|
contentHeight,
|
|
379
427
|
rotate,
|
|
@@ -383,6 +431,8 @@ function createOffscreenCanvas(
|
|
|
383
431
|
fontWeight,
|
|
384
432
|
color,
|
|
385
433
|
canvas,
|
|
434
|
+
content,
|
|
435
|
+
titleFontSize
|
|
386
436
|
);
|
|
387
437
|
}
|
|
388
438
|
} else {
|
|
@@ -413,10 +463,28 @@ function createCanvas(
|
|
|
413
463
|
image: string,
|
|
414
464
|
imageHeight: number,
|
|
415
465
|
imageWidth: number,
|
|
466
|
+
title: string,
|
|
467
|
+
titleFontSize: number
|
|
416
468
|
) {
|
|
417
469
|
const ctx = uni.createCanvasContext(canvasId.value);
|
|
418
470
|
if (ctx) {
|
|
419
|
-
if (image) {
|
|
471
|
+
if (image && (title || content)) {
|
|
472
|
+
// 图片和文字同时显示
|
|
473
|
+
drawImageAndTextOnScreen(
|
|
474
|
+
ctx,
|
|
475
|
+
image,
|
|
476
|
+
imageHeight,
|
|
477
|
+
imageWidth,
|
|
478
|
+
title,
|
|
479
|
+
content,
|
|
480
|
+
rotate,
|
|
481
|
+
contentWidth,
|
|
482
|
+
contentHeight,
|
|
483
|
+
fontSize,
|
|
484
|
+
titleFontSize,
|
|
485
|
+
color
|
|
486
|
+
);
|
|
487
|
+
} else if (image) {
|
|
420
488
|
drawImageOnScreen(
|
|
421
489
|
ctx,
|
|
422
490
|
image,
|
|
@@ -427,7 +495,7 @@ function createCanvas(
|
|
|
427
495
|
contentHeight,
|
|
428
496
|
);
|
|
429
497
|
} else {
|
|
430
|
-
drawTextOnScreen(ctx,
|
|
498
|
+
drawTextOnScreen(ctx, title, contentWidth, rotate, fontSize, color, content, titleFontSize);
|
|
431
499
|
}
|
|
432
500
|
} else {
|
|
433
501
|
console.error("无法获取canvas上下文,请确认当前环境是否支持canvas");
|
|
@@ -466,13 +534,37 @@ function createH5Canvas(
|
|
|
466
534
|
image: string,
|
|
467
535
|
imageHeight: number,
|
|
468
536
|
imageWidth: number,
|
|
537
|
+
title: string,
|
|
538
|
+
titleFontSize: number
|
|
469
539
|
) {
|
|
470
540
|
const canvas = document.createElement("canvas");
|
|
471
541
|
const ctx = canvas.getContext("2d");
|
|
472
542
|
canvas.setAttribute("width", `${canvasWidth}px`);
|
|
473
543
|
canvas.setAttribute("height", `${canvasHeight}px`);
|
|
474
544
|
if (ctx) {
|
|
475
|
-
if (image) {
|
|
545
|
+
if (image && (title || content)) {
|
|
546
|
+
// 图片和文字同时显示
|
|
547
|
+
const img = new Image();
|
|
548
|
+
drawImageAndTextOffScreen(
|
|
549
|
+
ctx,
|
|
550
|
+
img,
|
|
551
|
+
image,
|
|
552
|
+
imageHeight,
|
|
553
|
+
imageWidth,
|
|
554
|
+
title,
|
|
555
|
+
content,
|
|
556
|
+
rotate,
|
|
557
|
+
contentWidth,
|
|
558
|
+
contentHeight,
|
|
559
|
+
fontSize,
|
|
560
|
+
titleFontSize,
|
|
561
|
+
fontFamily,
|
|
562
|
+
fontStyle,
|
|
563
|
+
fontWeight,
|
|
564
|
+
color,
|
|
565
|
+
canvas,
|
|
566
|
+
);
|
|
567
|
+
} else if (image) {
|
|
476
568
|
const img = new Image();
|
|
477
569
|
drawImageOffScreen(
|
|
478
570
|
ctx,
|
|
@@ -488,7 +580,7 @@ function createH5Canvas(
|
|
|
488
580
|
} else {
|
|
489
581
|
drawTextOffScreen(
|
|
490
582
|
ctx,
|
|
491
|
-
|
|
583
|
+
title,
|
|
492
584
|
contentWidth,
|
|
493
585
|
contentHeight,
|
|
494
586
|
rotate,
|
|
@@ -498,6 +590,8 @@ function createH5Canvas(
|
|
|
498
590
|
fontWeight,
|
|
499
591
|
color,
|
|
500
592
|
canvas,
|
|
593
|
+
content,
|
|
594
|
+
titleFontSize
|
|
501
595
|
);
|
|
502
596
|
}
|
|
503
597
|
} else {
|
|
@@ -519,9 +613,32 @@ function createH5Canvas(
|
|
|
519
613
|
* @param color 水印字体颜色
|
|
520
614
|
* @param canvas canvas实例
|
|
521
615
|
*/
|
|
616
|
+
// 测量文本宽度并自动换行
|
|
617
|
+
function wrapText(ctx: CanvasRenderingContext2D, text: string, maxWidth: number, fontSize: number) {
|
|
618
|
+
const words = text.split('');
|
|
619
|
+
const lines: string[] = [];
|
|
620
|
+
let currentLine = '';
|
|
621
|
+
|
|
622
|
+
for (let i = 0; i < words.length; i++) {
|
|
623
|
+
const testLine = currentLine + words[i];
|
|
624
|
+
const metrics = ctx.measureText(testLine);
|
|
625
|
+
const testWidth = metrics.width;
|
|
626
|
+
|
|
627
|
+
// 当文字宽度超过容器宽度的80%时换行
|
|
628
|
+
if (testWidth > maxWidth * 0.8 && currentLine !== '') {
|
|
629
|
+
lines.push(currentLine);
|
|
630
|
+
currentLine = words[i];
|
|
631
|
+
} else {
|
|
632
|
+
currentLine = testLine;
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
lines.push(currentLine);
|
|
636
|
+
return lines;
|
|
637
|
+
}
|
|
638
|
+
|
|
522
639
|
function drawTextOffScreen(
|
|
523
640
|
ctx: CanvasRenderingContext2D,
|
|
524
|
-
|
|
641
|
+
title: string,
|
|
525
642
|
contentWidth: number,
|
|
526
643
|
contentHeight: number,
|
|
527
644
|
rotate: number,
|
|
@@ -531,15 +648,50 @@ function drawTextOffScreen(
|
|
|
531
648
|
fontWeight: string | number,
|
|
532
649
|
color: string,
|
|
533
650
|
canvas: HTMLCanvasElement,
|
|
651
|
+
content: string = '',
|
|
652
|
+
titleFontSize: number = 0
|
|
534
653
|
) {
|
|
535
|
-
console.log(fontSize, "离屏");
|
|
536
654
|
ctx.textBaseline = "middle";
|
|
537
655
|
ctx.textAlign = "center";
|
|
538
|
-
ctx.translate(contentWidth / 2,
|
|
656
|
+
ctx.translate(contentWidth / 2, contentHeight / 2);
|
|
539
657
|
ctx.rotate((Math.PI / 180) * rotate);
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
658
|
+
|
|
659
|
+
// 计算总高度
|
|
660
|
+
let totalTextHeight = titleFontSize;
|
|
661
|
+
if (content) {
|
|
662
|
+
totalTextHeight += fontSize + 5; // 标题和副标题之间的间距
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
// 起始Y坐标
|
|
666
|
+
let startY = -totalTextHeight / 2;
|
|
667
|
+
|
|
668
|
+
// 绘制主标题(支持自动换行)
|
|
669
|
+
if (title) {
|
|
670
|
+
ctx.font = `${fontStyle} normal ${fontWeight} ${titleFontSize}px/${contentHeight}px ${fontFamily}`;
|
|
671
|
+
// 使用titleColor或默认color
|
|
672
|
+
ctx.fillStyle = props.titleColor || color;
|
|
673
|
+
const titleLines = wrapText(ctx, title, contentWidth, titleFontSize);
|
|
674
|
+
const titleLineHeight = titleFontSize * 1.2;
|
|
675
|
+
|
|
676
|
+
for (let i = 0; i < titleLines.length; i++) {
|
|
677
|
+
ctx.fillText(titleLines[i], 0, startY + i * titleLineHeight);
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
startY += titleLines.length * titleLineHeight + 5;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
// 绘制副标题(支持自动换行)
|
|
684
|
+
if (content) {
|
|
685
|
+
ctx.font = `${fontStyle} normal ${fontWeight} ${fontSize}px/${contentHeight}px ${fontFamily}`;
|
|
686
|
+
ctx.fillStyle = color;
|
|
687
|
+
const contentLines = wrapText(ctx, content, contentWidth, fontSize);
|
|
688
|
+
const contentLineHeight = fontSize * 1.2;
|
|
689
|
+
|
|
690
|
+
for (let i = 0; i < contentLines.length; i++) {
|
|
691
|
+
ctx.fillText(contentLines[i], 0, startY + i * contentLineHeight);
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
|
|
543
695
|
ctx.restore();
|
|
544
696
|
waterMarkUrl.value = canvas.toDataURL();
|
|
545
697
|
}
|
|
@@ -553,21 +705,79 @@ function drawTextOffScreen(
|
|
|
553
705
|
* @param fontSize 水印字体大小
|
|
554
706
|
* @param color 水印字体颜色
|
|
555
707
|
*/
|
|
708
|
+
// 简化版本的文字换行(UniApp CanvasContext不支持measureText)
|
|
709
|
+
function simpleWrapText(text: string, maxLength: number) {
|
|
710
|
+
const lines: string[] = [];
|
|
711
|
+
let currentLine = '';
|
|
712
|
+
|
|
713
|
+
// 基于字符数估算换行(适用于UniApp CanvasContext)
|
|
714
|
+
for (let i = 0; i < text.length; i++) {
|
|
715
|
+
currentLine += text[i];
|
|
716
|
+
if (currentLine.length >= maxLength) {
|
|
717
|
+
lines.push(currentLine);
|
|
718
|
+
currentLine = '';
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
if (currentLine) {
|
|
722
|
+
lines.push(currentLine);
|
|
723
|
+
}
|
|
724
|
+
return lines;
|
|
725
|
+
}
|
|
726
|
+
|
|
556
727
|
function drawTextOnScreen(
|
|
557
728
|
ctx: UniApp.CanvasContext,
|
|
558
|
-
|
|
729
|
+
title: string,
|
|
559
730
|
contentWidth: number,
|
|
560
731
|
rotate: number,
|
|
561
732
|
fontSize: number,
|
|
562
733
|
color: string,
|
|
734
|
+
content: string = '',
|
|
735
|
+
titleFontSize: number = 0
|
|
563
736
|
) {
|
|
564
737
|
ctx.setTextBaseline("middle");
|
|
565
738
|
ctx.setTextAlign("center");
|
|
566
739
|
ctx.translate(contentWidth / 2, contentWidth / 2);
|
|
567
740
|
ctx.rotate((Math.PI / 180) * rotate);
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
741
|
+
|
|
742
|
+
// 估算每行最大字符数
|
|
743
|
+
const maxChars = Math.floor(contentWidth / (fontSize * 0.5));
|
|
744
|
+
|
|
745
|
+
// 计算总高度
|
|
746
|
+
let totalTextHeight = titleFontSize;
|
|
747
|
+
if (content) {
|
|
748
|
+
totalTextHeight += fontSize + 5;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
// 起始Y坐标
|
|
752
|
+
let startY = -totalTextHeight / 2;
|
|
753
|
+
|
|
754
|
+
// 绘制主标题(支持自动换行)
|
|
755
|
+
if (title) {
|
|
756
|
+
// 使用titleColor或默认color
|
|
757
|
+
ctx.setFillStyle(props.titleColor || color);
|
|
758
|
+
ctx.setFontSize(titleFontSize);
|
|
759
|
+
const titleLines = simpleWrapText(title, maxChars);
|
|
760
|
+
const titleLineHeight = titleFontSize * 1.2;
|
|
761
|
+
|
|
762
|
+
for (let i = 0; i < titleLines.length; i++) {
|
|
763
|
+
ctx.fillText(titleLines[i], 0, startY + i * titleLineHeight);
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
startY += titleLines.length * titleLineHeight + 5;
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
// 绘制副标题(支持自动换行)
|
|
770
|
+
if (content) {
|
|
771
|
+
ctx.setFillStyle(color);
|
|
772
|
+
ctx.setFontSize(fontSize);
|
|
773
|
+
const contentLines = simpleWrapText(content, maxChars);
|
|
774
|
+
const contentLineHeight = fontSize * 1.2;
|
|
775
|
+
|
|
776
|
+
for (let i = 0; i < contentLines.length; i++) {
|
|
777
|
+
ctx.fillText(contentLines[i], 0, startY + i * contentLineHeight);
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
|
|
571
781
|
ctx.restore();
|
|
572
782
|
ctx.draw();
|
|
573
783
|
// #ifdef MP-DINGTALK
|
|
@@ -632,6 +842,188 @@ async function drawImageOffScreen(
|
|
|
632
842
|
};
|
|
633
843
|
}
|
|
634
844
|
|
|
845
|
+
// 绘制图片和文字(离屏)
|
|
846
|
+
async function drawImageAndTextOffScreen(
|
|
847
|
+
ctx: CanvasRenderingContext2D,
|
|
848
|
+
img: HTMLImageElement,
|
|
849
|
+
image: string,
|
|
850
|
+
imageHeight: number,
|
|
851
|
+
imageWidth: number,
|
|
852
|
+
title: string,
|
|
853
|
+
content: string,
|
|
854
|
+
rotate: number,
|
|
855
|
+
contentWidth: number,
|
|
856
|
+
contentHeight: number,
|
|
857
|
+
fontSize: number,
|
|
858
|
+
titleFontSize: number,
|
|
859
|
+
fontFamily: string,
|
|
860
|
+
fontStyle: string,
|
|
861
|
+
fontWeight: string | number,
|
|
862
|
+
color: string,
|
|
863
|
+
canvas: HTMLCanvasElement,
|
|
864
|
+
) {
|
|
865
|
+
ctx.translate(contentWidth / 2, contentHeight / 2);
|
|
866
|
+
ctx.rotate((Math.PI / 180) * Number(rotate));
|
|
867
|
+
img.crossOrigin = "anonymous";
|
|
868
|
+
img.referrerPolicy = "no-referrer";
|
|
869
|
+
|
|
870
|
+
const imgHeight = imageHeight * pixelRatio.value;
|
|
871
|
+
const imgWidth = imageWidth * pixelRatio.value;
|
|
872
|
+
|
|
873
|
+
img.src = image;
|
|
874
|
+
img.onload = () => {
|
|
875
|
+
// 计算总高度
|
|
876
|
+
let totalHeight = imgHeight;
|
|
877
|
+
const textSpacing = 10;
|
|
878
|
+
|
|
879
|
+
if (title) totalHeight += textSpacing + titleFontSize;
|
|
880
|
+
if (content) totalHeight += fontSize;
|
|
881
|
+
|
|
882
|
+
// 起始Y坐标
|
|
883
|
+
let startY = -totalHeight / 2;
|
|
884
|
+
|
|
885
|
+
// 绘制图片
|
|
886
|
+
ctx.drawImage(
|
|
887
|
+
img,
|
|
888
|
+
-imgWidth / 2,
|
|
889
|
+
startY,
|
|
890
|
+
imgWidth,
|
|
891
|
+
imgHeight,
|
|
892
|
+
);
|
|
893
|
+
|
|
894
|
+
startY += imgHeight + textSpacing;
|
|
895
|
+
|
|
896
|
+
// 设置文字样式
|
|
897
|
+
ctx.textBaseline = "top";
|
|
898
|
+
ctx.textAlign = "center";
|
|
899
|
+
|
|
900
|
+
// 绘制主标题
|
|
901
|
+
if (title) {
|
|
902
|
+
ctx.font = `${fontStyle} normal ${fontWeight} ${titleFontSize}px/${contentHeight}px ${fontFamily}`;
|
|
903
|
+
// 使用titleColor或默认color
|
|
904
|
+
ctx.fillStyle = props.titleColor || color;
|
|
905
|
+
const titleLines = wrapText(ctx, title, contentWidth * 0.9, titleFontSize);
|
|
906
|
+
const titleLineHeight = titleFontSize * 1.2;
|
|
907
|
+
|
|
908
|
+
for (let i = 0; i < titleLines.length; i++) {
|
|
909
|
+
ctx.fillText(titleLines[i], 0, startY + i * titleLineHeight);
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
startY += titleLines.length * titleLineHeight + 5;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
// 绘制副标题
|
|
916
|
+
if (content) {
|
|
917
|
+
ctx.font = `${fontStyle} normal ${fontWeight} ${fontSize}px/${contentHeight}px ${fontFamily}`;
|
|
918
|
+
ctx.fillStyle = color;
|
|
919
|
+
const contentLines = wrapText(ctx, content, contentWidth * 0.9, fontSize);
|
|
920
|
+
const contentLineHeight = fontSize * 1.2;
|
|
921
|
+
|
|
922
|
+
for (let i = 0; i < contentLines.length; i++) {
|
|
923
|
+
ctx.fillText(contentLines[i], 0, startY + i * contentLineHeight);
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
ctx.restore();
|
|
928
|
+
waterMarkUrl.value = canvas.toDataURL();
|
|
929
|
+
};
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
// 绘制图片和文字(在屏)
|
|
933
|
+
function drawImageAndTextOnScreen(
|
|
934
|
+
ctx: UniApp.CanvasContext,
|
|
935
|
+
image: string,
|
|
936
|
+
imageHeight: number,
|
|
937
|
+
imageWidth: number,
|
|
938
|
+
title: string,
|
|
939
|
+
content: string,
|
|
940
|
+
rotate: number,
|
|
941
|
+
contentWidth: number,
|
|
942
|
+
contentHeight: number,
|
|
943
|
+
fontSize: number,
|
|
944
|
+
titleFontSize: number,
|
|
945
|
+
color: string
|
|
946
|
+
) {
|
|
947
|
+
ctx.setTextBaseline("top");
|
|
948
|
+
ctx.setTextAlign("center");
|
|
949
|
+
ctx.translate(contentWidth / 2, contentWidth / 2);
|
|
950
|
+
ctx.rotate((Math.PI / 180) * Number(rotate));
|
|
951
|
+
|
|
952
|
+
const imgHeight = imageHeight * pixelRatio.value;
|
|
953
|
+
const imgWidth = imageWidth * pixelRatio.value;
|
|
954
|
+
const maxChars = Math.floor(contentWidth / (fontSize * 0.5));
|
|
955
|
+
|
|
956
|
+
// 计算总高度
|
|
957
|
+
let totalHeight = imgHeight;
|
|
958
|
+
const textSpacing = 10;
|
|
959
|
+
|
|
960
|
+
if (title) totalHeight += textSpacing + titleFontSize;
|
|
961
|
+
if (content) totalHeight += fontSize;
|
|
962
|
+
|
|
963
|
+
// 起始Y坐标
|
|
964
|
+
let startY = -totalHeight / 2;
|
|
965
|
+
|
|
966
|
+
// 绘制图片
|
|
967
|
+
ctx.drawImage(
|
|
968
|
+
image,
|
|
969
|
+
-imgWidth / 2,
|
|
970
|
+
startY,
|
|
971
|
+
imgWidth,
|
|
972
|
+
imgHeight,
|
|
973
|
+
);
|
|
974
|
+
|
|
975
|
+
startY += imgHeight + textSpacing;
|
|
976
|
+
|
|
977
|
+
// 绘制主标题
|
|
978
|
+
if (title) {
|
|
979
|
+
// 使用titleColor或默认color
|
|
980
|
+
ctx.setFillStyle(props.titleColor || color);
|
|
981
|
+
ctx.setFontSize(titleFontSize);
|
|
982
|
+
const titleLines = simpleWrapText(title, maxChars);
|
|
983
|
+
const titleLineHeight = titleFontSize * 1.2;
|
|
984
|
+
|
|
985
|
+
for (let i = 0; i < titleLines.length; i++) {
|
|
986
|
+
ctx.fillText(titleLines[i], 0, startY + i * titleLineHeight);
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
startY += titleLines.length * titleLineHeight + 5;
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
// 绘制副标题
|
|
993
|
+
if (content) {
|
|
994
|
+
ctx.setFillStyle(color);
|
|
995
|
+
ctx.setFontSize(fontSize);
|
|
996
|
+
const contentLines = simpleWrapText(content, maxChars);
|
|
997
|
+
const contentLineHeight = fontSize * 1.2;
|
|
998
|
+
|
|
999
|
+
for (let i = 0; i < contentLines.length; i++) {
|
|
1000
|
+
ctx.fillText(contentLines[i], 0, startY + i * contentLineHeight);
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
ctx.restore();
|
|
1005
|
+
ctx.draw(false, () => {
|
|
1006
|
+
// #ifdef MP-DINGTALK
|
|
1007
|
+
// 钉钉小程序的canvasToTempFilePath接口与其他平台不一样
|
|
1008
|
+
(ctx as any).toTempFilePath({
|
|
1009
|
+
success(res: any) {
|
|
1010
|
+
showCanvas.value = false;
|
|
1011
|
+
waterMarkUrl.value = res.filePath;
|
|
1012
|
+
},
|
|
1013
|
+
});
|
|
1014
|
+
// #endif
|
|
1015
|
+
// #ifndef MP-DINGTALK
|
|
1016
|
+
uni.canvasToTempFilePath({
|
|
1017
|
+
canvasId: canvasId.value,
|
|
1018
|
+
success: (res) => {
|
|
1019
|
+
showCanvas.value = false;
|
|
1020
|
+
waterMarkUrl.value = res.tempFilePath;
|
|
1021
|
+
},
|
|
1022
|
+
});
|
|
1023
|
+
// #endif
|
|
1024
|
+
});
|
|
1025
|
+
}
|
|
1026
|
+
|
|
635
1027
|
/**
|
|
636
1028
|
* 绘制在屏图片canvas
|
|
637
1029
|
* @param ctx canvas上下文
|
|
@@ -2,9 +2,21 @@
|
|
|
2
2
|
* 全局分享hooks
|
|
3
3
|
* */
|
|
4
4
|
interface ShareConfig {
|
|
5
|
+
/**
|
|
6
|
+
* 标题名称
|
|
7
|
+
* */
|
|
5
8
|
title?: string;
|
|
9
|
+
/**
|
|
10
|
+
* 页面路径
|
|
11
|
+
* */
|
|
6
12
|
path?: string;
|
|
13
|
+
/**
|
|
14
|
+
* 分享朋友的封面图片
|
|
15
|
+
* */
|
|
7
16
|
friendImageUrl?: string;
|
|
17
|
+
/**
|
|
18
|
+
* 分享朋友圈的封面图片
|
|
19
|
+
* */
|
|
8
20
|
timelineImageUrl?: string;
|
|
9
21
|
}
|
|
10
22
|
|