@leafer-draw/miniapp 1.6.1 → 1.6.3

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.
@@ -1,8 +1,9 @@
1
- import { LeaferCanvasBase, Platform, canvasPatch, DataHelper, canvasSizeAttrs, ResizeEvent, FileHelper, Creator, LeaferImage, defineKey, LeafList, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, LeafBoundsHelper, Bounds, Debug, LeafLevelList, LayoutEvent, Run, ImageManager, BoundsHelper, MatrixHelper, MathHelper, AlignHelper, ImageEvent, AroundHelper, PointHelper, Direction4 } from '@leafer/core';
1
+ import { LeaferCanvasBase, Platform, canvasPatch, DataHelper, canvasSizeAttrs, ResizeEvent, FileHelper, Creator, LeaferImage, defineKey, LeafList, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, LeafBoundsHelper, Bounds, Debug, LeafLevelList, LayoutEvent, Run, ImageManager, BoundsHelper, MatrixHelper, MathHelper, AlignHelper, PointHelper, ImageEvent, AroundHelper, Direction4 } from '@leafer/core';
2
2
  export * from '@leafer/core';
3
3
  export { LeaferImage } from '@leafer/core';
4
- import { PaintImage, ColorConvert, PaintGradient, Export, Group, TextConvert, Paint, Effect } from '@leafer-ui/draw';
4
+ import { PaintImage, ColorConvert, PaintGradient, Export, Group, TextConvert, Paint as Paint$1, Effect } from '@leafer-ui/draw';
5
5
  export * from '@leafer-ui/draw';
6
+ import { Platform as Platform$1 } from '@leafer-ui/core';
6
7
 
7
8
  class LeaferCanvas extends LeaferCanvasBase {
8
9
  get allowBackgroundColor() { return false; }
@@ -300,17 +301,15 @@ class Watcher {
300
301
  this.target.emitEvent(new WatchEvent(WatchEvent.DATA, { updatedList: this.updatedList }));
301
302
  this.__updatedList = new LeafList();
302
303
  this.totalTimes++;
303
- this.changed = false;
304
- this.hasVisible = false;
305
- this.hasRemove = false;
306
- this.hasAdd = false;
304
+ this.changed = this.hasVisible = this.hasRemove = this.hasAdd = false;
307
305
  }
308
306
  __listenEvents() {
309
- const { target } = this;
310
307
  this.__eventIds = [
311
- target.on_(PropertyEvent.CHANGE, this.__onAttrChange, this),
312
- target.on_([ChildEvent.ADD, ChildEvent.REMOVE], this.__onChildEvent, this),
313
- target.on_(WatchEvent.REQUEST, this.__onRquestData, this)
308
+ this.target.on_([
309
+ [PropertyEvent.CHANGE, this.__onAttrChange, this],
310
+ [[ChildEvent.ADD, ChildEvent.REMOVE], this.__onChildEvent, this],
311
+ [WatchEvent.REQUEST, this.__onRquestData, this]
312
+ ])
314
313
  ];
315
314
  }
316
315
  __removeListenEvents() {
@@ -320,13 +319,12 @@ class Watcher {
320
319
  if (this.target) {
321
320
  this.stop();
322
321
  this.__removeListenEvents();
323
- this.target = null;
324
- this.__updatedList = null;
322
+ this.target = this.__updatedList = null;
325
323
  }
326
324
  }
327
325
  }
328
326
 
329
- const { updateAllMatrix: updateAllMatrix$1, updateBounds: updateOneBounds, updateAllWorldOpacity } = LeafHelper;
327
+ const { updateAllMatrix: updateAllMatrix$1, updateBounds: updateOneBounds, updateChange: updateOneChange } = LeafHelper;
330
328
  const { pushAllChildBranch, pushAllParent } = BranchHelper;
331
329
  function updateMatrix(updateList, levelList) {
332
330
  let layout;
@@ -369,15 +367,7 @@ function updateBounds(boundsList) {
369
367
  });
370
368
  }
371
369
  function updateChange(updateList) {
372
- let layout;
373
- updateList.list.forEach(leaf => {
374
- layout = leaf.__layout;
375
- if (layout.opacityChanged)
376
- updateAllWorldOpacity(leaf);
377
- if (layout.stateStyleChanged)
378
- setTimeout(() => layout.stateStyleChanged && leaf.updateState());
379
- leaf.__updateChange();
380
- });
370
+ updateList.list.forEach(updateOneChange);
381
371
  }
382
372
 
383
373
  const { worldBounds } = LeafBoundsHelper;
@@ -434,7 +424,7 @@ class Layouter {
434
424
  this.disabled = true;
435
425
  }
436
426
  layout() {
437
- if (!this.running)
427
+ if (this.layouting || !this.running)
438
428
  return;
439
429
  const { target } = this;
440
430
  this.times = 0;
@@ -517,12 +507,10 @@ class Layouter {
517
507
  }
518
508
  static fullLayout(target) {
519
509
  updateAllMatrix(target, true);
520
- if (target.isBranch) {
510
+ if (target.isBranch)
521
511
  BranchHelper.updateBounds(target);
522
- }
523
- else {
512
+ else
524
513
  LeafHelper.updateBounds(target);
525
- }
526
514
  updateAllChange(target);
527
515
  }
528
516
  addExtra(leaf) {
@@ -545,11 +533,12 @@ class Layouter {
545
533
  this.__updatedList = event.data.updatedList;
546
534
  }
547
535
  __listenEvents() {
548
- const { target } = this;
549
536
  this.__eventIds = [
550
- target.on_(LayoutEvent.REQUEST, this.layout, this),
551
- target.on_(LayoutEvent.AGAIN, this.layoutAgain, this),
552
- target.on_(WatchEvent.DATA, this.__onReceiveWatchData, this)
537
+ this.target.on_([
538
+ [LayoutEvent.REQUEST, this.layout, this],
539
+ [LayoutEvent.AGAIN, this.layoutAgain, this],
540
+ [WatchEvent.DATA, this.__onReceiveWatchData, this]
541
+ ])
553
542
  ];
554
543
  }
555
544
  __removeListenEvents() {
@@ -780,12 +769,13 @@ class Renderer {
780
769
  this.target.emitEvent(new RenderEvent(type, this.times, bounds, options));
781
770
  }
782
771
  __listenEvents() {
783
- const { target } = this;
784
772
  this.__eventIds = [
785
- target.on_(RenderEvent.REQUEST, this.update, this),
786
- target.on_(LayoutEvent.END, this.__onLayoutEnd, this),
787
- target.on_(RenderEvent.AGAIN, this.renderAgain, this),
788
- target.on_(ResizeEvent.RESIZE, this.__onResize, this)
773
+ this.target.on_([
774
+ [RenderEvent.REQUEST, this.update, this],
775
+ [LayoutEvent.END, this.__onLayoutEnd, this],
776
+ [RenderEvent.AGAIN, this.renderAgain, this],
777
+ [ResizeEvent.RESIZE, this.__onResize, this]
778
+ ])
789
779
  ];
790
780
  }
791
781
  __removeListenEvents() {
@@ -811,8 +801,10 @@ Object.assign(Creator, {
811
801
  Platform.layout = Layouter.fullLayout;
812
802
 
813
803
  function fillText(ui, canvas) {
814
- let row, data = ui.__.__textDrawData;
815
- const { rows, decorationY } = data;
804
+ const data = ui.__, { rows, decorationY } = data.__textDrawData;
805
+ if (data.__isPlacehold && data.placeholderColor)
806
+ canvas.fillStyle = data.placeholderColor;
807
+ let row;
816
808
  for (let i = 0, len = rows.length; i < len; i++) {
817
809
  row = rows[i];
818
810
  if (row.text)
@@ -821,7 +813,7 @@ function fillText(ui, canvas) {
821
813
  row.data.forEach(charData => { canvas.fillText(charData.char, charData.x, row.y); });
822
814
  }
823
815
  if (decorationY) {
824
- const { decorationColor, decorationHeight } = data;
816
+ const { decorationColor, decorationHeight } = data.__textDrawData;
825
817
  if (decorationColor)
826
818
  canvas.fillStyle = decorationColor;
827
819
  rows.forEach(row => decorationY.forEach(value => canvas.fillRect(row.x, row.y + value, row.width, decorationHeight)));
@@ -830,65 +822,73 @@ function fillText(ui, canvas) {
830
822
 
831
823
  function fill(fill, ui, canvas) {
832
824
  canvas.fillStyle = fill;
833
- ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
825
+ fillPathOrText(ui, canvas);
834
826
  }
835
827
  function fills(fills, ui, canvas) {
836
828
  let item;
837
- const { windingRule, __font } = ui.__;
838
829
  for (let i = 0, len = fills.length; i < len; i++) {
839
830
  item = fills[i];
840
- if (item.image && PaintImage.checkImage(ui, canvas, item, !__font))
841
- continue;
842
- if (item.style) {
843
- canvas.fillStyle = item.style;
844
- if (item.transform) {
845
- canvas.save();
846
- canvas.transform(item.transform);
847
- if (item.blendMode)
848
- canvas.blendMode = item.blendMode;
849
- __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
850
- canvas.restore();
831
+ if (item.image) {
832
+ if (PaintImage.checkImage(ui, canvas, item, !ui.__.__font))
833
+ continue;
834
+ if (!item.style) {
835
+ if (!i && item.image.isPlacehold)
836
+ ui.drawImagePlaceholder(canvas, item.image);
837
+ continue;
851
838
  }
852
- else {
853
- if (item.blendMode) {
854
- canvas.saveBlendMode(item.blendMode);
855
- __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
856
- canvas.restoreBlendMode();
857
- }
858
- else {
859
- __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
860
- }
839
+ }
840
+ canvas.fillStyle = item.style;
841
+ if (item.transform) {
842
+ canvas.save();
843
+ canvas.transform(item.transform);
844
+ if (item.blendMode)
845
+ canvas.blendMode = item.blendMode;
846
+ fillPathOrText(ui, canvas);
847
+ canvas.restore();
848
+ }
849
+ else {
850
+ if (item.blendMode) {
851
+ canvas.saveBlendMode(item.blendMode);
852
+ fillPathOrText(ui, canvas);
853
+ canvas.restoreBlendMode();
861
854
  }
855
+ else
856
+ fillPathOrText(ui, canvas);
862
857
  }
863
858
  }
864
859
  }
860
+ function fillPathOrText(ui, canvas) {
861
+ ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
862
+ }
863
+
864
+ const Paint = {};
865
865
 
866
866
  function strokeText(stroke, ui, canvas) {
867
- const { strokeAlign } = ui.__;
868
- const isStrokes = typeof stroke !== 'string';
869
- switch (strokeAlign) {
867
+ switch (ui.__.strokeAlign) {
870
868
  case 'center':
871
- canvas.setStroke(isStrokes ? undefined : stroke, ui.__.strokeWidth, ui.__);
872
- isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
869
+ drawCenter$1(stroke, 1, ui, canvas);
873
870
  break;
874
871
  case 'inside':
875
- drawAlignStroke('inside', stroke, isStrokes, ui, canvas);
872
+ drawAlign(stroke, 'inside', ui, canvas);
876
873
  break;
877
874
  case 'outside':
878
- drawAlignStroke('outside', stroke, isStrokes, ui, canvas);
875
+ ui.__.__fillAfterStroke ? drawCenter$1(stroke, 2, ui, canvas) : drawAlign(stroke, 'outside', ui, canvas);
879
876
  break;
880
877
  }
881
878
  }
882
- function drawAlignStroke(align, stroke, isStrokes, ui, canvas) {
883
- const { __strokeWidth, __font } = ui.__;
879
+ function drawCenter$1(stroke, strokeWidthScale, ui, canvas) {
880
+ const data = ui.__;
881
+ canvas.setStroke(!data.__isStrokes && stroke, data.strokeWidth * strokeWidthScale, data);
882
+ data.__isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
883
+ }
884
+ function drawAlign(stroke, align, ui, canvas) {
884
885
  const out = canvas.getSameCanvas(true, true);
885
- out.setStroke(isStrokes ? undefined : stroke, __strokeWidth * 2, ui.__);
886
- out.font = __font;
887
- isStrokes ? drawStrokesStyle(stroke, true, ui, out) : drawTextStroke(ui, out);
886
+ out.font = ui.__.__font;
887
+ drawCenter$1(stroke, 2, ui, out);
888
888
  out.blendMode = align === 'outside' ? 'destination-out' : 'destination-in';
889
889
  fillText(ui, out);
890
890
  out.blendMode = 'normal';
891
- if (ui.__worldFlipped)
891
+ if (ui.__worldFlipped || Platform$1.fullImageShadow)
892
892
  canvas.copyWorldByReset(out, ui.__nowWorld);
893
893
  else
894
894
  canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
@@ -930,90 +930,60 @@ function drawStrokesStyle(strokes, isText, ui, canvas) {
930
930
  }
931
931
 
932
932
  function stroke(stroke, ui, canvas) {
933
- const options = ui.__;
934
- const { __strokeWidth, strokeAlign, __font } = options;
935
- if (!__strokeWidth)
933
+ const data = ui.__;
934
+ if (!data.__strokeWidth)
936
935
  return;
937
- if (__font) {
936
+ if (data.__font) {
938
937
  strokeText(stroke, ui, canvas);
939
938
  }
940
939
  else {
941
- switch (strokeAlign) {
940
+ switch (data.strokeAlign) {
942
941
  case 'center':
943
- canvas.setStroke(stroke, __strokeWidth, options);
944
- canvas.stroke();
945
- if (options.__useArrow)
946
- strokeArrow(ui, canvas);
942
+ drawCenter(stroke, 1, ui, canvas);
947
943
  break;
948
944
  case 'inside':
949
- canvas.save();
950
- canvas.setStroke(stroke, __strokeWidth * 2, options);
951
- options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
952
- canvas.stroke();
953
- canvas.restore();
945
+ drawInside(stroke, ui, canvas);
954
946
  break;
955
947
  case 'outside':
956
- const out = canvas.getSameCanvas(true, true);
957
- out.setStroke(stroke, __strokeWidth * 2, options);
958
- ui.__drawRenderPath(out);
959
- out.stroke();
960
- options.windingRule ? out.clip(options.windingRule) : out.clip();
961
- out.clearWorld(ui.__layout.renderBounds);
962
- if (ui.__worldFlipped)
963
- canvas.copyWorldByReset(out, ui.__nowWorld);
964
- else
965
- canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
966
- out.recycle(ui.__nowWorld);
948
+ drawOutside(stroke, ui, canvas);
967
949
  break;
968
950
  }
969
951
  }
970
952
  }
971
953
  function strokes(strokes, ui, canvas) {
972
- const options = ui.__;
973
- const { __strokeWidth, strokeAlign, __font } = options;
974
- if (!__strokeWidth)
975
- return;
976
- if (__font) {
977
- strokeText(strokes, ui, canvas);
954
+ stroke(strokes, ui, canvas);
955
+ }
956
+ function drawCenter(stroke, strokeWidthScale, ui, canvas) {
957
+ const data = ui.__;
958
+ canvas.setStroke(!data.__isStrokes && stroke, data.__strokeWidth * strokeWidthScale, data);
959
+ data.__isStrokes ? drawStrokesStyle(stroke, false, ui, canvas) : canvas.stroke();
960
+ if (data.__useArrow)
961
+ Paint.strokeArrow(stroke, ui, canvas);
962
+ }
963
+ function drawInside(stroke, ui, canvas) {
964
+ const data = ui.__;
965
+ canvas.save();
966
+ data.windingRule ? canvas.clip(data.windingRule) : canvas.clip();
967
+ drawCenter(stroke, 2, ui, canvas);
968
+ canvas.restore();
969
+ }
970
+ function drawOutside(stroke, ui, canvas) {
971
+ const data = ui.__;
972
+ if (data.__fillAfterStroke) {
973
+ drawCenter(stroke, 2, ui, canvas);
978
974
  }
979
975
  else {
980
- switch (strokeAlign) {
981
- case 'center':
982
- canvas.setStroke(undefined, __strokeWidth, options);
983
- drawStrokesStyle(strokes, false, ui, canvas);
984
- if (options.__useArrow)
985
- strokeArrow(ui, canvas);
986
- break;
987
- case 'inside':
988
- canvas.save();
989
- canvas.setStroke(undefined, __strokeWidth * 2, options);
990
- options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
991
- drawStrokesStyle(strokes, false, ui, canvas);
992
- canvas.restore();
993
- break;
994
- case 'outside':
995
- const { renderBounds } = ui.__layout;
996
- const out = canvas.getSameCanvas(true, true);
997
- ui.__drawRenderPath(out);
998
- out.setStroke(undefined, __strokeWidth * 2, options);
999
- drawStrokesStyle(strokes, false, ui, out);
1000
- options.windingRule ? out.clip(options.windingRule) : out.clip();
1001
- out.clearWorld(renderBounds);
1002
- if (ui.__worldFlipped)
1003
- canvas.copyWorldByReset(out, ui.__nowWorld);
1004
- else
1005
- canvas.copyWorldToInner(out, ui.__nowWorld, renderBounds);
1006
- out.recycle(ui.__nowWorld);
1007
- break;
1008
- }
1009
- }
1010
- }
1011
- function strokeArrow(ui, canvas) {
1012
- if (ui.__.dashPattern) {
1013
- canvas.beginPath();
1014
- ui.__drawPathByData(canvas, ui.__.__pathForArrow);
1015
- canvas.dashPattern = null;
1016
- canvas.stroke();
976
+ const { renderBounds } = ui.__layout;
977
+ const out = canvas.getSameCanvas(true, true);
978
+ ui.__drawRenderPath(out);
979
+ drawCenter(stroke, 2, ui, out);
980
+ data.windingRule ? out.clip(data.windingRule) : out.clip();
981
+ out.clearWorld(renderBounds);
982
+ if (ui.__worldFlipped || Platform$1.fullImageShadow)
983
+ canvas.copyWorldByReset(out, ui.__nowWorld);
984
+ else
985
+ canvas.copyWorldToInner(out, ui.__nowWorld, renderBounds);
986
+ out.recycle(ui.__nowWorld);
1017
987
  }
1018
988
  }
1019
989
 
@@ -1060,9 +1030,10 @@ function shape(ui, current, options) {
1060
1030
  }
1061
1031
 
1062
1032
  let recycleMap;
1033
+ const { stintSet } = DataHelper, { hasTransparent: hasTransparent$1 } = ColorConvert;
1063
1034
  function compute(attrName, ui) {
1064
1035
  const data = ui.__, leafPaints = [];
1065
- let paints = data.__input[attrName], hasOpacityPixel;
1036
+ let paints = data.__input[attrName], isAlphaPixel, isTransparent;
1066
1037
  if (!(paints instanceof Array))
1067
1038
  paints = [paints];
1068
1039
  recycleMap = PaintImage.recycleImage(attrName, data);
@@ -1072,35 +1043,62 @@ function compute(attrName, ui) {
1072
1043
  leafPaints.push(item);
1073
1044
  }
1074
1045
  data['_' + attrName] = leafPaints.length ? leafPaints : undefined;
1075
- if (leafPaints.length && leafPaints[0].image)
1076
- hasOpacityPixel = leafPaints[0].image.hasOpacityPixel;
1077
- attrName === 'fill' ? data.__pixelFill = hasOpacityPixel : data.__pixelStroke = hasOpacityPixel;
1046
+ if (leafPaints.length) {
1047
+ if (leafPaints.every(item => item.isTransparent)) {
1048
+ if (leafPaints.some(item => item.image))
1049
+ isAlphaPixel = true;
1050
+ isTransparent = true;
1051
+ }
1052
+ }
1053
+ if (attrName === 'fill') {
1054
+ stintSet(data, '__isAlphaPixelFill', isAlphaPixel);
1055
+ stintSet(data, '__isTransparentFill', isTransparent);
1056
+ }
1057
+ else {
1058
+ stintSet(data, '__isAlphaPixelStroke', isAlphaPixel);
1059
+ stintSet(data, '__isTransparentStroke', isTransparent);
1060
+ }
1078
1061
  }
1079
1062
  function getLeafPaint(attrName, paint, ui) {
1080
1063
  if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
1081
1064
  return undefined;
1065
+ let data;
1082
1066
  const { boxBounds } = ui.__layout;
1083
1067
  switch (paint.type) {
1084
- case 'solid':
1085
- let { type, blendMode, color, opacity } = paint;
1086
- return { type, blendMode, style: ColorConvert.string(color, opacity) };
1087
1068
  case 'image':
1088
- return PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
1069
+ data = PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
1070
+ break;
1089
1071
  case 'linear':
1090
- return PaintGradient.linearGradient(paint, boxBounds);
1072
+ data = PaintGradient.linearGradient(paint, boxBounds);
1073
+ break;
1091
1074
  case 'radial':
1092
- return PaintGradient.radialGradient(paint, boxBounds);
1075
+ data = PaintGradient.radialGradient(paint, boxBounds);
1076
+ break;
1093
1077
  case 'angular':
1094
- return PaintGradient.conicGradient(paint, boxBounds);
1078
+ data = PaintGradient.conicGradient(paint, boxBounds);
1079
+ break;
1080
+ case 'solid':
1081
+ const { type, blendMode, color, opacity } = paint;
1082
+ data = { type, blendMode, style: ColorConvert.string(color, opacity) };
1083
+ break;
1095
1084
  default:
1096
- return paint.r !== undefined ? { type: 'solid', style: ColorConvert.string(paint) } : undefined;
1085
+ if (paint.r !== undefined)
1086
+ data = { type: 'solid', style: ColorConvert.string(paint) };
1087
+ }
1088
+ if (data) {
1089
+ if (typeof data.style === 'string' && hasTransparent$1(data.style))
1090
+ data.isTransparent = true;
1091
+ if (paint.blendMode)
1092
+ data.blendMode = paint.blendMode;
1097
1093
  }
1094
+ return data;
1098
1095
  }
1099
1096
 
1100
1097
  const PaintModule = {
1101
1098
  compute,
1102
1099
  fill,
1103
1100
  fills,
1101
+ fillPathOrText,
1104
1102
  fillText,
1105
1103
  stroke,
1106
1104
  strokes,
@@ -1159,12 +1157,10 @@ function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, al
1159
1157
 
1160
1158
  const { get: get$2, translate } = MatrixHelper;
1161
1159
  const tempBox = new Bounds();
1162
- const tempPoint = {};
1163
1160
  const tempScaleData = {};
1161
+ const tempImage = {};
1164
1162
  function createData(leafPaint, image, paint, box) {
1165
- const { blendMode, changeful, sync } = paint;
1166
- if (blendMode)
1167
- leafPaint.blendMode = blendMode;
1163
+ const { changeful, sync } = paint;
1168
1164
  if (changeful)
1169
1165
  leafPaint.changeful = changeful;
1170
1166
  if (sync)
@@ -1172,38 +1168,38 @@ function createData(leafPaint, image, paint, box) {
1172
1168
  leafPaint.data = getPatternData(paint, box, image);
1173
1169
  }
1174
1170
  function getPatternData(paint, box, image) {
1175
- let { width, height } = image;
1176
1171
  if (paint.padding)
1177
1172
  box = tempBox.set(box).shrink(paint.padding);
1178
1173
  if (paint.mode === 'strench')
1179
1174
  paint.mode = 'stretch';
1175
+ let { width, height } = image;
1180
1176
  const { opacity, mode, align, offset, scale, size, rotation, repeat, filters } = paint;
1181
1177
  const sameBox = box.width === width && box.height === height;
1182
1178
  const data = { mode };
1183
1179
  const swapSize = align !== 'center' && (rotation || 0) % 180 === 90;
1184
- const swapWidth = swapSize ? height : width, swapHeight = swapSize ? width : height;
1185
- let x = 0, y = 0, scaleX, scaleY;
1180
+ BoundsHelper.set(tempImage, 0, 0, swapSize ? height : width, swapSize ? width : height);
1181
+ let scaleX, scaleY;
1186
1182
  if (!mode || mode === 'cover' || mode === 'fit') {
1187
1183
  if (!sameBox || rotation) {
1188
- const sw = box.width / swapWidth, sh = box.height / swapHeight;
1189
- scaleX = scaleY = mode === 'fit' ? Math.min(sw, sh) : Math.max(sw, sh);
1190
- x += (box.width - width * scaleX) / 2, y += (box.height - height * scaleY) / 2;
1184
+ scaleX = scaleY = BoundsHelper.getFitScale(box, tempImage, mode !== 'fit');
1185
+ BoundsHelper.put(box, image, align, scaleX, false, tempImage);
1186
+ BoundsHelper.scale(tempImage, scaleX, scaleY, true);
1191
1187
  }
1192
1188
  }
1193
- else if (scale || size) {
1194
- MathHelper.getScaleData(scale, size, image, tempScaleData);
1195
- scaleX = tempScaleData.scaleX;
1196
- scaleY = tempScaleData.scaleY;
1197
- }
1198
- if (align) {
1199
- const imageBounds = { x, y, width: swapWidth, height: swapHeight };
1200
- if (scaleX)
1201
- imageBounds.width *= scaleX, imageBounds.height *= scaleY;
1202
- AlignHelper.toPoint(align, imageBounds, box, tempPoint, true);
1203
- x += tempPoint.x, y += tempPoint.y;
1189
+ else {
1190
+ if (scale || size) {
1191
+ MathHelper.getScaleData(scale, size, image, tempScaleData);
1192
+ scaleX = tempScaleData.scaleX;
1193
+ scaleY = tempScaleData.scaleY;
1194
+ }
1195
+ if (align) {
1196
+ if (scaleX)
1197
+ BoundsHelper.scale(tempImage, scaleX, scaleY, true);
1198
+ AlignHelper.toPoint(align, tempImage, box, tempImage, true, true);
1199
+ }
1204
1200
  }
1205
1201
  if (offset)
1206
- x += offset.x, y += offset.y;
1202
+ PointHelper.move(tempImage, offset);
1207
1203
  switch (mode) {
1208
1204
  case 'stretch':
1209
1205
  if (!sameBox)
@@ -1211,12 +1207,12 @@ function getPatternData(paint, box, image) {
1211
1207
  break;
1212
1208
  case 'normal':
1213
1209
  case 'clip':
1214
- if (x || y || scaleX || rotation)
1215
- clipMode(data, box, x, y, scaleX, scaleY, rotation);
1210
+ if (tempImage.x || tempImage.y || scaleX || rotation)
1211
+ clipMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation);
1216
1212
  break;
1217
1213
  case 'repeat':
1218
1214
  if (!sameBox || scaleX || rotation)
1219
- repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, align);
1215
+ repeatMode(data, box, width, height, tempImage.x, tempImage.y, scaleX, scaleY, rotation, align);
1220
1216
  if (!repeat)
1221
1217
  data.repeat = 'repeat';
1222
1218
  break;
@@ -1224,7 +1220,7 @@ function getPatternData(paint, box, image) {
1224
1220
  case 'cover':
1225
1221
  default:
1226
1222
  if (scaleX)
1227
- fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation);
1223
+ fillOrFitMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation);
1228
1224
  }
1229
1225
  if (!data.transform) {
1230
1226
  if (box.x || box.y) {
@@ -1257,6 +1253,8 @@ function image(ui, attrName, paint, boxBounds, firstUse) {
1257
1253
  }
1258
1254
  else {
1259
1255
  leafPaint = { type: paint.type, image };
1256
+ if (image.hasAlphaPixel)
1257
+ leafPaint.isTransparent = true;
1260
1258
  cache = image.use > 1 ? { leafPaint, paint, boxBounds: box.set(boxBounds) } : null;
1261
1259
  }
1262
1260
  if (firstUse || image.loading)
@@ -1281,7 +1279,7 @@ function image(ui, attrName, paint, boxBounds, firstUse) {
1281
1279
  ignoreRender(ui, false);
1282
1280
  if (!ui.destroyed) {
1283
1281
  if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds)) {
1284
- if (image.hasOpacityPixel)
1282
+ if (image.hasAlphaPixel)
1285
1283
  ui.__layout.hitCanvasChanged = true;
1286
1284
  ui.forceUpdate('surface');
1287
1285
  }
@@ -1293,6 +1291,17 @@ function image(ui, attrName, paint, boxBounds, firstUse) {
1293
1291
  onLoadError(ui, event, error);
1294
1292
  leafPaint.loadId = null;
1295
1293
  });
1294
+ if (ui.placeholderColor) {
1295
+ if (!ui.placeholderDelay)
1296
+ image.isPlacehold = true;
1297
+ else
1298
+ setTimeout(() => {
1299
+ if (!image.ready) {
1300
+ image.isPlacehold = true;
1301
+ ui.forceUpdate('surface');
1302
+ }
1303
+ }, ui.placeholderDelay);
1304
+ }
1296
1305
  }
1297
1306
  return leafPaint;
1298
1307
  }
@@ -1530,32 +1539,33 @@ const PaintImageModule = {
1530
1539
  repeatMode
1531
1540
  };
1532
1541
 
1533
- const { toPoint: toPoint$2 } = AroundHelper;
1542
+ const { toPoint: toPoint$2 } = AroundHelper, { hasTransparent } = ColorConvert;
1534
1543
  const realFrom$2 = {};
1535
1544
  const realTo$2 = {};
1536
1545
  function linearGradient(paint, box) {
1537
- let { from, to, type, blendMode, opacity } = paint;
1546
+ let { from, to, type, opacity } = paint;
1538
1547
  toPoint$2(from || 'top', box, realFrom$2);
1539
1548
  toPoint$2(to || 'bottom', box, realTo$2);
1540
1549
  const style = Platform.canvas.createLinearGradient(realFrom$2.x, realFrom$2.y, realTo$2.x, realTo$2.y);
1541
- applyStops(style, paint.stops, opacity);
1542
1550
  const data = { type, style };
1543
- if (blendMode)
1544
- data.blendMode = blendMode;
1551
+ applyStops(data, style, paint.stops, opacity);
1545
1552
  return data;
1546
1553
  }
1547
- function applyStops(gradient, stops, opacity) {
1554
+ function applyStops(data, gradient, stops, opacity) {
1548
1555
  if (stops) {
1549
- let stop;
1556
+ let stop, color, offset, isTransparent;
1550
1557
  for (let i = 0, len = stops.length; i < len; i++) {
1551
1558
  stop = stops[i];
1552
- if (typeof stop === 'string') {
1553
- gradient.addColorStop(i / (len - 1), ColorConvert.string(stop, opacity));
1554
- }
1555
- else {
1556
- gradient.addColorStop(stop.offset, ColorConvert.string(stop.color, opacity));
1557
- }
1559
+ if (typeof stop === 'string')
1560
+ offset = i / (len - 1), color = ColorConvert.string(stop, opacity);
1561
+ else
1562
+ offset = stop.offset, color = ColorConvert.string(stop.color, opacity);
1563
+ gradient.addColorStop(offset, color);
1564
+ if (!isTransparent && hasTransparent(color))
1565
+ isTransparent = true;
1558
1566
  }
1567
+ if (isTransparent)
1568
+ data.isTransparent = true;
1559
1569
  }
1560
1570
  }
1561
1571
 
@@ -1565,17 +1575,15 @@ const { toPoint: toPoint$1 } = AroundHelper;
1565
1575
  const realFrom$1 = {};
1566
1576
  const realTo$1 = {};
1567
1577
  function radialGradient(paint, box) {
1568
- let { from, to, type, opacity, blendMode, stretch } = paint;
1578
+ let { from, to, type, opacity, stretch } = paint;
1569
1579
  toPoint$1(from || 'center', box, realFrom$1);
1570
1580
  toPoint$1(to || 'bottom', box, realTo$1);
1571
1581
  const style = Platform.canvas.createRadialGradient(realFrom$1.x, realFrom$1.y, 0, realFrom$1.x, realFrom$1.y, getDistance$1(realFrom$1, realTo$1));
1572
- applyStops(style, paint.stops, opacity);
1573
1582
  const data = { type, style };
1583
+ applyStops(data, style, paint.stops, opacity);
1574
1584
  const transform = getTransform(box, realFrom$1, realTo$1, stretch, true);
1575
1585
  if (transform)
1576
1586
  data.transform = transform;
1577
- if (blendMode)
1578
- data.blendMode = blendMode;
1579
1587
  return data;
1580
1588
  }
1581
1589
  function getTransform(box, from, to, stretch, rotate90) {
@@ -1601,17 +1609,15 @@ const { toPoint } = AroundHelper;
1601
1609
  const realFrom = {};
1602
1610
  const realTo = {};
1603
1611
  function conicGradient(paint, box) {
1604
- let { from, to, type, opacity, blendMode, stretch } = paint;
1612
+ let { from, to, type, opacity, stretch } = paint;
1605
1613
  toPoint(from || 'center', box, realFrom);
1606
1614
  toPoint(to || 'bottom', box, realTo);
1607
1615
  const style = Platform.conicGradientSupport ? Platform.canvas.createConicGradient(0, realFrom.x, realFrom.y) : Platform.canvas.createRadialGradient(realFrom.x, realFrom.y, 0, realFrom.x, realFrom.y, getDistance(realFrom, realTo));
1608
- applyStops(style, paint.stops, opacity);
1609
1616
  const data = { type, style };
1617
+ applyStops(data, style, paint.stops, opacity);
1610
1618
  const transform = getTransform(box, realFrom, realTo, stretch || 1, Platform.conicGradientRotate90);
1611
1619
  if (transform)
1612
1620
  data.transform = transform;
1613
- if (blendMode)
1614
- data.blendMode = blendMode;
1615
1621
  return data;
1616
1622
  }
1617
1623
 
@@ -1944,6 +1950,8 @@ function createRows(drawData, content, style) {
1944
1950
  lastCharType = null;
1945
1951
  startCharSize = charWidth = charSize = wordWidth = rowWidth = 0;
1946
1952
  word = { data: [] }, row = { words: [] };
1953
+ if (__letterSpacing)
1954
+ content = [...content];
1947
1955
  for (let i = 0, len = content.length; i < len; i++) {
1948
1956
  char = content[i];
1949
1957
  if (char === '\n') {
@@ -2350,7 +2358,7 @@ const ColorConvertModule = {
2350
2358
 
2351
2359
  Object.assign(TextConvert, TextConvertModule);
2352
2360
  Object.assign(ColorConvert, ColorConvertModule);
2353
- Object.assign(Paint, PaintModule);
2361
+ Object.assign(Paint$1, PaintModule);
2354
2362
  Object.assign(PaintImage, PaintImageModule);
2355
2363
  Object.assign(PaintGradient, PaintGradientModule);
2356
2364
  Object.assign(Effect, EffectModule);
@@ -2362,4 +2370,3 @@ try {
2362
2370
  catch (_a) { }
2363
2371
 
2364
2372
  export { Layouter, LeaferCanvas, Renderer, Watcher, useCanvas };
2365
- //# sourceMappingURL=miniapp.esm.js.map