@leafer-ui/node 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.
package/dist/node.esm.js CHANGED
@@ -1,10 +1,10 @@
1
- import { LeaferCanvasBase, Platform, canvasPatch, FileHelper, Creator, LeaferImage, defineKey, LeafList, DataHelper, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, LeafBoundsHelper, Bounds, Debug, LeafLevelList, LayoutEvent, Run, ImageManager, ResizeEvent, BoundsHelper, Plugin, MatrixHelper, MathHelper, AlignHelper, ImageEvent, AroundHelper, PointHelper, Direction4 } from '@leafer/core';
1
+ import { LeaferCanvasBase, Platform, canvasPatch, FileHelper, Creator, LeaferImage, defineKey, LeafList, DataHelper, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, LeafBoundsHelper, Bounds, Debug, LeafLevelList, LayoutEvent, Run, ImageManager, ResizeEvent, BoundsHelper, Plugin, MatrixHelper, MathHelper, AlignHelper, PointHelper, ImageEvent, AroundHelper, Direction4 } from '@leafer/core';
2
2
  export * from '@leafer/core';
3
3
  export { LeaferImage } from '@leafer/core';
4
4
  import { writeFileSync } from 'fs';
5
- import { HitCanvasManager, InteractionBase } from '@leafer-ui/core';
5
+ import { Platform as Platform$1, HitCanvasManager, InteractionBase } from '@leafer-ui/core';
6
6
  export * from '@leafer-ui/core';
7
- import { PaintImage, ColorConvert, PaintGradient, Export, Group, TextConvert, Paint, Effect, TwoPointBoundsHelper, Bounds as Bounds$1, FileHelper as FileHelper$1, Platform as Platform$1, Matrix, MathHelper as MathHelper$1, Creator as Creator$1, TaskProcessor, Resource, LeaferCanvasBase as LeaferCanvasBase$1, Debug as Debug$1, Plugin as Plugin$1, UI } from '@leafer-ui/draw';
7
+ import { PaintImage, ColorConvert, PaintGradient, Export, Group, TextConvert, Paint as Paint$1, Effect, TwoPointBoundsHelper, Bounds as Bounds$1, FileHelper as FileHelper$1, Platform as Platform$2, Matrix, MathHelper as MathHelper$1, Creator as Creator$1, TaskProcessor, Resource, LeaferCanvasBase as LeaferCanvasBase$1, Debug as Debug$1, Plugin as Plugin$1, UI } from '@leafer-ui/draw';
8
8
 
9
9
  /******************************************************************************
10
10
  Copyright (c) Microsoft Corporation.
@@ -175,17 +175,15 @@ class Watcher {
175
175
  this.target.emitEvent(new WatchEvent(WatchEvent.DATA, { updatedList: this.updatedList }));
176
176
  this.__updatedList = new LeafList();
177
177
  this.totalTimes++;
178
- this.changed = false;
179
- this.hasVisible = false;
180
- this.hasRemove = false;
181
- this.hasAdd = false;
178
+ this.changed = this.hasVisible = this.hasRemove = this.hasAdd = false;
182
179
  }
183
180
  __listenEvents() {
184
- const { target } = this;
185
181
  this.__eventIds = [
186
- target.on_(PropertyEvent.CHANGE, this.__onAttrChange, this),
187
- target.on_([ChildEvent.ADD, ChildEvent.REMOVE], this.__onChildEvent, this),
188
- target.on_(WatchEvent.REQUEST, this.__onRquestData, this)
182
+ this.target.on_([
183
+ [PropertyEvent.CHANGE, this.__onAttrChange, this],
184
+ [[ChildEvent.ADD, ChildEvent.REMOVE], this.__onChildEvent, this],
185
+ [WatchEvent.REQUEST, this.__onRquestData, this]
186
+ ])
189
187
  ];
190
188
  }
191
189
  __removeListenEvents() {
@@ -195,13 +193,12 @@ class Watcher {
195
193
  if (this.target) {
196
194
  this.stop();
197
195
  this.__removeListenEvents();
198
- this.target = null;
199
- this.__updatedList = null;
196
+ this.target = this.__updatedList = null;
200
197
  }
201
198
  }
202
199
  }
203
200
 
204
- const { updateAllMatrix: updateAllMatrix$1, updateBounds: updateOneBounds, updateAllWorldOpacity } = LeafHelper;
201
+ const { updateAllMatrix: updateAllMatrix$1, updateBounds: updateOneBounds, updateChange: updateOneChange } = LeafHelper;
205
202
  const { pushAllChildBranch, pushAllParent } = BranchHelper;
206
203
  function updateMatrix(updateList, levelList) {
207
204
  let layout;
@@ -244,15 +241,7 @@ function updateBounds(boundsList) {
244
241
  });
245
242
  }
246
243
  function updateChange(updateList) {
247
- let layout;
248
- updateList.list.forEach(leaf => {
249
- layout = leaf.__layout;
250
- if (layout.opacityChanged)
251
- updateAllWorldOpacity(leaf);
252
- if (layout.stateStyleChanged)
253
- setTimeout(() => layout.stateStyleChanged && leaf.updateState());
254
- leaf.__updateChange();
255
- });
244
+ updateList.list.forEach(updateOneChange);
256
245
  }
257
246
 
258
247
  const { worldBounds } = LeafBoundsHelper;
@@ -309,7 +298,7 @@ class Layouter {
309
298
  this.disabled = true;
310
299
  }
311
300
  layout() {
312
- if (!this.running)
301
+ if (this.layouting || !this.running)
313
302
  return;
314
303
  const { target } = this;
315
304
  this.times = 0;
@@ -392,12 +381,10 @@ class Layouter {
392
381
  }
393
382
  static fullLayout(target) {
394
383
  updateAllMatrix(target, true);
395
- if (target.isBranch) {
384
+ if (target.isBranch)
396
385
  BranchHelper.updateBounds(target);
397
- }
398
- else {
386
+ else
399
387
  LeafHelper.updateBounds(target);
400
- }
401
388
  updateAllChange(target);
402
389
  }
403
390
  addExtra(leaf) {
@@ -420,11 +407,12 @@ class Layouter {
420
407
  this.__updatedList = event.data.updatedList;
421
408
  }
422
409
  __listenEvents() {
423
- const { target } = this;
424
410
  this.__eventIds = [
425
- target.on_(LayoutEvent.REQUEST, this.layout, this),
426
- target.on_(LayoutEvent.AGAIN, this.layoutAgain, this),
427
- target.on_(WatchEvent.DATA, this.__onReceiveWatchData, this)
411
+ this.target.on_([
412
+ [LayoutEvent.REQUEST, this.layout, this],
413
+ [LayoutEvent.AGAIN, this.layoutAgain, this],
414
+ [WatchEvent.DATA, this.__onReceiveWatchData, this]
415
+ ])
428
416
  ];
429
417
  }
430
418
  __removeListenEvents() {
@@ -655,12 +643,13 @@ class Renderer {
655
643
  this.target.emitEvent(new RenderEvent(type, this.times, bounds, options));
656
644
  }
657
645
  __listenEvents() {
658
- const { target } = this;
659
646
  this.__eventIds = [
660
- target.on_(RenderEvent.REQUEST, this.update, this),
661
- target.on_(LayoutEvent.END, this.__onLayoutEnd, this),
662
- target.on_(RenderEvent.AGAIN, this.renderAgain, this),
663
- target.on_(ResizeEvent.RESIZE, this.__onResize, this)
647
+ this.target.on_([
648
+ [RenderEvent.REQUEST, this.update, this],
649
+ [LayoutEvent.END, this.__onLayoutEnd, this],
650
+ [RenderEvent.AGAIN, this.renderAgain, this],
651
+ [ResizeEvent.RESIZE, this.__onResize, this]
652
+ ])
664
653
  ];
665
654
  }
666
655
  __removeListenEvents() {
@@ -843,8 +832,10 @@ Object.assign(Creator, {
843
832
  Platform.layout = Layouter.fullLayout;
844
833
 
845
834
  function fillText(ui, canvas) {
846
- let row, data = ui.__.__textDrawData;
847
- const { rows, decorationY } = data;
835
+ const data = ui.__, { rows, decorationY } = data.__textDrawData;
836
+ if (data.__isPlacehold && data.placeholderColor)
837
+ canvas.fillStyle = data.placeholderColor;
838
+ let row;
848
839
  for (let i = 0, len = rows.length; i < len; i++) {
849
840
  row = rows[i];
850
841
  if (row.text)
@@ -853,7 +844,7 @@ function fillText(ui, canvas) {
853
844
  row.data.forEach(charData => { canvas.fillText(charData.char, charData.x, row.y); });
854
845
  }
855
846
  if (decorationY) {
856
- const { decorationColor, decorationHeight } = data;
847
+ const { decorationColor, decorationHeight } = data.__textDrawData;
857
848
  if (decorationColor)
858
849
  canvas.fillStyle = decorationColor;
859
850
  rows.forEach(row => decorationY.forEach(value => canvas.fillRect(row.x, row.y + value, row.width, decorationHeight)));
@@ -862,65 +853,73 @@ function fillText(ui, canvas) {
862
853
 
863
854
  function fill(fill, ui, canvas) {
864
855
  canvas.fillStyle = fill;
865
- ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
856
+ fillPathOrText(ui, canvas);
866
857
  }
867
858
  function fills(fills, ui, canvas) {
868
859
  let item;
869
- const { windingRule, __font } = ui.__;
870
860
  for (let i = 0, len = fills.length; i < len; i++) {
871
861
  item = fills[i];
872
- if (item.image && PaintImage.checkImage(ui, canvas, item, !__font))
873
- continue;
874
- if (item.style) {
875
- canvas.fillStyle = item.style;
876
- if (item.transform) {
877
- canvas.save();
878
- canvas.transform(item.transform);
879
- if (item.blendMode)
880
- canvas.blendMode = item.blendMode;
881
- __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
882
- canvas.restore();
862
+ if (item.image) {
863
+ if (PaintImage.checkImage(ui, canvas, item, !ui.__.__font))
864
+ continue;
865
+ if (!item.style) {
866
+ if (!i && item.image.isPlacehold)
867
+ ui.drawImagePlaceholder(canvas, item.image);
868
+ continue;
883
869
  }
884
- else {
885
- if (item.blendMode) {
886
- canvas.saveBlendMode(item.blendMode);
887
- __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
888
- canvas.restoreBlendMode();
889
- }
890
- else {
891
- __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
892
- }
870
+ }
871
+ canvas.fillStyle = item.style;
872
+ if (item.transform) {
873
+ canvas.save();
874
+ canvas.transform(item.transform);
875
+ if (item.blendMode)
876
+ canvas.blendMode = item.blendMode;
877
+ fillPathOrText(ui, canvas);
878
+ canvas.restore();
879
+ }
880
+ else {
881
+ if (item.blendMode) {
882
+ canvas.saveBlendMode(item.blendMode);
883
+ fillPathOrText(ui, canvas);
884
+ canvas.restoreBlendMode();
893
885
  }
886
+ else
887
+ fillPathOrText(ui, canvas);
894
888
  }
895
889
  }
896
890
  }
891
+ function fillPathOrText(ui, canvas) {
892
+ ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
893
+ }
894
+
895
+ const Paint = {};
897
896
 
898
897
  function strokeText(stroke, ui, canvas) {
899
- const { strokeAlign } = ui.__;
900
- const isStrokes = typeof stroke !== 'string';
901
- switch (strokeAlign) {
898
+ switch (ui.__.strokeAlign) {
902
899
  case 'center':
903
- canvas.setStroke(isStrokes ? undefined : stroke, ui.__.strokeWidth, ui.__);
904
- isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
900
+ drawCenter$1(stroke, 1, ui, canvas);
905
901
  break;
906
902
  case 'inside':
907
- drawAlignStroke('inside', stroke, isStrokes, ui, canvas);
903
+ drawAlign(stroke, 'inside', ui, canvas);
908
904
  break;
909
905
  case 'outside':
910
- drawAlignStroke('outside', stroke, isStrokes, ui, canvas);
906
+ ui.__.__fillAfterStroke ? drawCenter$1(stroke, 2, ui, canvas) : drawAlign(stroke, 'outside', ui, canvas);
911
907
  break;
912
908
  }
913
909
  }
914
- function drawAlignStroke(align, stroke, isStrokes, ui, canvas) {
915
- const { __strokeWidth, __font } = ui.__;
910
+ function drawCenter$1(stroke, strokeWidthScale, ui, canvas) {
911
+ const data = ui.__;
912
+ canvas.setStroke(!data.__isStrokes && stroke, data.strokeWidth * strokeWidthScale, data);
913
+ data.__isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
914
+ }
915
+ function drawAlign(stroke, align, ui, canvas) {
916
916
  const out = canvas.getSameCanvas(true, true);
917
- out.setStroke(isStrokes ? undefined : stroke, __strokeWidth * 2, ui.__);
918
- out.font = __font;
919
- isStrokes ? drawStrokesStyle(stroke, true, ui, out) : drawTextStroke(ui, out);
917
+ out.font = ui.__.__font;
918
+ drawCenter$1(stroke, 2, ui, out);
920
919
  out.blendMode = align === 'outside' ? 'destination-out' : 'destination-in';
921
920
  fillText(ui, out);
922
921
  out.blendMode = 'normal';
923
- if (ui.__worldFlipped)
922
+ if (ui.__worldFlipped || Platform$1.fullImageShadow)
924
923
  canvas.copyWorldByReset(out, ui.__nowWorld);
925
924
  else
926
925
  canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
@@ -962,90 +961,60 @@ function drawStrokesStyle(strokes, isText, ui, canvas) {
962
961
  }
963
962
 
964
963
  function stroke(stroke, ui, canvas) {
965
- const options = ui.__;
966
- const { __strokeWidth, strokeAlign, __font } = options;
967
- if (!__strokeWidth)
964
+ const data = ui.__;
965
+ if (!data.__strokeWidth)
968
966
  return;
969
- if (__font) {
967
+ if (data.__font) {
970
968
  strokeText(stroke, ui, canvas);
971
969
  }
972
970
  else {
973
- switch (strokeAlign) {
971
+ switch (data.strokeAlign) {
974
972
  case 'center':
975
- canvas.setStroke(stroke, __strokeWidth, options);
976
- canvas.stroke();
977
- if (options.__useArrow)
978
- strokeArrow(ui, canvas);
973
+ drawCenter(stroke, 1, ui, canvas);
979
974
  break;
980
975
  case 'inside':
981
- canvas.save();
982
- canvas.setStroke(stroke, __strokeWidth * 2, options);
983
- options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
984
- canvas.stroke();
985
- canvas.restore();
976
+ drawInside(stroke, ui, canvas);
986
977
  break;
987
978
  case 'outside':
988
- const out = canvas.getSameCanvas(true, true);
989
- out.setStroke(stroke, __strokeWidth * 2, options);
990
- ui.__drawRenderPath(out);
991
- out.stroke();
992
- options.windingRule ? out.clip(options.windingRule) : out.clip();
993
- out.clearWorld(ui.__layout.renderBounds);
994
- if (ui.__worldFlipped)
995
- canvas.copyWorldByReset(out, ui.__nowWorld);
996
- else
997
- canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
998
- out.recycle(ui.__nowWorld);
979
+ drawOutside(stroke, ui, canvas);
999
980
  break;
1000
981
  }
1001
982
  }
1002
983
  }
1003
984
  function strokes(strokes, ui, canvas) {
1004
- const options = ui.__;
1005
- const { __strokeWidth, strokeAlign, __font } = options;
1006
- if (!__strokeWidth)
1007
- return;
1008
- if (__font) {
1009
- strokeText(strokes, ui, canvas);
985
+ stroke(strokes, ui, canvas);
986
+ }
987
+ function drawCenter(stroke, strokeWidthScale, ui, canvas) {
988
+ const data = ui.__;
989
+ canvas.setStroke(!data.__isStrokes && stroke, data.__strokeWidth * strokeWidthScale, data);
990
+ data.__isStrokes ? drawStrokesStyle(stroke, false, ui, canvas) : canvas.stroke();
991
+ if (data.__useArrow)
992
+ Paint.strokeArrow(stroke, ui, canvas);
993
+ }
994
+ function drawInside(stroke, ui, canvas) {
995
+ const data = ui.__;
996
+ canvas.save();
997
+ data.windingRule ? canvas.clip(data.windingRule) : canvas.clip();
998
+ drawCenter(stroke, 2, ui, canvas);
999
+ canvas.restore();
1000
+ }
1001
+ function drawOutside(stroke, ui, canvas) {
1002
+ const data = ui.__;
1003
+ if (data.__fillAfterStroke) {
1004
+ drawCenter(stroke, 2, ui, canvas);
1010
1005
  }
1011
1006
  else {
1012
- switch (strokeAlign) {
1013
- case 'center':
1014
- canvas.setStroke(undefined, __strokeWidth, options);
1015
- drawStrokesStyle(strokes, false, ui, canvas);
1016
- if (options.__useArrow)
1017
- strokeArrow(ui, canvas);
1018
- break;
1019
- case 'inside':
1020
- canvas.save();
1021
- canvas.setStroke(undefined, __strokeWidth * 2, options);
1022
- options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
1023
- drawStrokesStyle(strokes, false, ui, canvas);
1024
- canvas.restore();
1025
- break;
1026
- case 'outside':
1027
- const { renderBounds } = ui.__layout;
1028
- const out = canvas.getSameCanvas(true, true);
1029
- ui.__drawRenderPath(out);
1030
- out.setStroke(undefined, __strokeWidth * 2, options);
1031
- drawStrokesStyle(strokes, false, ui, out);
1032
- options.windingRule ? out.clip(options.windingRule) : out.clip();
1033
- out.clearWorld(renderBounds);
1034
- if (ui.__worldFlipped)
1035
- canvas.copyWorldByReset(out, ui.__nowWorld);
1036
- else
1037
- canvas.copyWorldToInner(out, ui.__nowWorld, renderBounds);
1038
- out.recycle(ui.__nowWorld);
1039
- break;
1040
- }
1041
- }
1042
- }
1043
- function strokeArrow(ui, canvas) {
1044
- if (ui.__.dashPattern) {
1045
- canvas.beginPath();
1046
- ui.__drawPathByData(canvas, ui.__.__pathForArrow);
1047
- canvas.dashPattern = null;
1048
- canvas.stroke();
1007
+ const { renderBounds } = ui.__layout;
1008
+ const out = canvas.getSameCanvas(true, true);
1009
+ ui.__drawRenderPath(out);
1010
+ drawCenter(stroke, 2, ui, out);
1011
+ data.windingRule ? out.clip(data.windingRule) : out.clip();
1012
+ out.clearWorld(renderBounds);
1013
+ if (ui.__worldFlipped || Platform$1.fullImageShadow)
1014
+ canvas.copyWorldByReset(out, ui.__nowWorld);
1015
+ else
1016
+ canvas.copyWorldToInner(out, ui.__nowWorld, renderBounds);
1017
+ out.recycle(ui.__nowWorld);
1049
1018
  }
1050
1019
  }
1051
1020
 
@@ -1092,9 +1061,10 @@ function shape(ui, current, options) {
1092
1061
  }
1093
1062
 
1094
1063
  let recycleMap;
1064
+ const { stintSet } = DataHelper, { hasTransparent: hasTransparent$1 } = ColorConvert;
1095
1065
  function compute(attrName, ui) {
1096
1066
  const data = ui.__, leafPaints = [];
1097
- let paints = data.__input[attrName], hasOpacityPixel;
1067
+ let paints = data.__input[attrName], isAlphaPixel, isTransparent;
1098
1068
  if (!(paints instanceof Array))
1099
1069
  paints = [paints];
1100
1070
  recycleMap = PaintImage.recycleImage(attrName, data);
@@ -1104,35 +1074,62 @@ function compute(attrName, ui) {
1104
1074
  leafPaints.push(item);
1105
1075
  }
1106
1076
  data['_' + attrName] = leafPaints.length ? leafPaints : undefined;
1107
- if (leafPaints.length && leafPaints[0].image)
1108
- hasOpacityPixel = leafPaints[0].image.hasOpacityPixel;
1109
- attrName === 'fill' ? data.__pixelFill = hasOpacityPixel : data.__pixelStroke = hasOpacityPixel;
1077
+ if (leafPaints.length) {
1078
+ if (leafPaints.every(item => item.isTransparent)) {
1079
+ if (leafPaints.some(item => item.image))
1080
+ isAlphaPixel = true;
1081
+ isTransparent = true;
1082
+ }
1083
+ }
1084
+ if (attrName === 'fill') {
1085
+ stintSet(data, '__isAlphaPixelFill', isAlphaPixel);
1086
+ stintSet(data, '__isTransparentFill', isTransparent);
1087
+ }
1088
+ else {
1089
+ stintSet(data, '__isAlphaPixelStroke', isAlphaPixel);
1090
+ stintSet(data, '__isTransparentStroke', isTransparent);
1091
+ }
1110
1092
  }
1111
1093
  function getLeafPaint(attrName, paint, ui) {
1112
1094
  if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
1113
1095
  return undefined;
1096
+ let data;
1114
1097
  const { boxBounds } = ui.__layout;
1115
1098
  switch (paint.type) {
1116
- case 'solid':
1117
- let { type, blendMode, color, opacity } = paint;
1118
- return { type, blendMode, style: ColorConvert.string(color, opacity) };
1119
1099
  case 'image':
1120
- return PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
1100
+ data = PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
1101
+ break;
1121
1102
  case 'linear':
1122
- return PaintGradient.linearGradient(paint, boxBounds);
1103
+ data = PaintGradient.linearGradient(paint, boxBounds);
1104
+ break;
1123
1105
  case 'radial':
1124
- return PaintGradient.radialGradient(paint, boxBounds);
1106
+ data = PaintGradient.radialGradient(paint, boxBounds);
1107
+ break;
1125
1108
  case 'angular':
1126
- return PaintGradient.conicGradient(paint, boxBounds);
1109
+ data = PaintGradient.conicGradient(paint, boxBounds);
1110
+ break;
1111
+ case 'solid':
1112
+ const { type, blendMode, color, opacity } = paint;
1113
+ data = { type, blendMode, style: ColorConvert.string(color, opacity) };
1114
+ break;
1127
1115
  default:
1128
- return paint.r !== undefined ? { type: 'solid', style: ColorConvert.string(paint) } : undefined;
1116
+ if (paint.r !== undefined)
1117
+ data = { type: 'solid', style: ColorConvert.string(paint) };
1118
+ }
1119
+ if (data) {
1120
+ if (typeof data.style === 'string' && hasTransparent$1(data.style))
1121
+ data.isTransparent = true;
1122
+ if (paint.blendMode)
1123
+ data.blendMode = paint.blendMode;
1129
1124
  }
1125
+ return data;
1130
1126
  }
1131
1127
 
1132
1128
  const PaintModule = {
1133
1129
  compute,
1134
1130
  fill,
1135
1131
  fills,
1132
+ fillPathOrText,
1136
1133
  fillText,
1137
1134
  stroke,
1138
1135
  strokes,
@@ -1191,12 +1188,10 @@ function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, al
1191
1188
 
1192
1189
  const { get: get$2, translate } = MatrixHelper;
1193
1190
  const tempBox = new Bounds();
1194
- const tempPoint = {};
1195
1191
  const tempScaleData = {};
1192
+ const tempImage = {};
1196
1193
  function createData(leafPaint, image, paint, box) {
1197
- const { blendMode, changeful, sync } = paint;
1198
- if (blendMode)
1199
- leafPaint.blendMode = blendMode;
1194
+ const { changeful, sync } = paint;
1200
1195
  if (changeful)
1201
1196
  leafPaint.changeful = changeful;
1202
1197
  if (sync)
@@ -1204,38 +1199,38 @@ function createData(leafPaint, image, paint, box) {
1204
1199
  leafPaint.data = getPatternData(paint, box, image);
1205
1200
  }
1206
1201
  function getPatternData(paint, box, image) {
1207
- let { width, height } = image;
1208
1202
  if (paint.padding)
1209
1203
  box = tempBox.set(box).shrink(paint.padding);
1210
1204
  if (paint.mode === 'strench')
1211
1205
  paint.mode = 'stretch';
1206
+ let { width, height } = image;
1212
1207
  const { opacity, mode, align, offset, scale, size, rotation, repeat, filters } = paint;
1213
1208
  const sameBox = box.width === width && box.height === height;
1214
1209
  const data = { mode };
1215
1210
  const swapSize = align !== 'center' && (rotation || 0) % 180 === 90;
1216
- const swapWidth = swapSize ? height : width, swapHeight = swapSize ? width : height;
1217
- let x = 0, y = 0, scaleX, scaleY;
1211
+ BoundsHelper.set(tempImage, 0, 0, swapSize ? height : width, swapSize ? width : height);
1212
+ let scaleX, scaleY;
1218
1213
  if (!mode || mode === 'cover' || mode === 'fit') {
1219
1214
  if (!sameBox || rotation) {
1220
- const sw = box.width / swapWidth, sh = box.height / swapHeight;
1221
- scaleX = scaleY = mode === 'fit' ? Math.min(sw, sh) : Math.max(sw, sh);
1222
- x += (box.width - width * scaleX) / 2, y += (box.height - height * scaleY) / 2;
1215
+ scaleX = scaleY = BoundsHelper.getFitScale(box, tempImage, mode !== 'fit');
1216
+ BoundsHelper.put(box, image, align, scaleX, false, tempImage);
1217
+ BoundsHelper.scale(tempImage, scaleX, scaleY, true);
1223
1218
  }
1224
1219
  }
1225
- else if (scale || size) {
1226
- MathHelper.getScaleData(scale, size, image, tempScaleData);
1227
- scaleX = tempScaleData.scaleX;
1228
- scaleY = tempScaleData.scaleY;
1229
- }
1230
- if (align) {
1231
- const imageBounds = { x, y, width: swapWidth, height: swapHeight };
1232
- if (scaleX)
1233
- imageBounds.width *= scaleX, imageBounds.height *= scaleY;
1234
- AlignHelper.toPoint(align, imageBounds, box, tempPoint, true);
1235
- x += tempPoint.x, y += tempPoint.y;
1220
+ else {
1221
+ if (scale || size) {
1222
+ MathHelper.getScaleData(scale, size, image, tempScaleData);
1223
+ scaleX = tempScaleData.scaleX;
1224
+ scaleY = tempScaleData.scaleY;
1225
+ }
1226
+ if (align) {
1227
+ if (scaleX)
1228
+ BoundsHelper.scale(tempImage, scaleX, scaleY, true);
1229
+ AlignHelper.toPoint(align, tempImage, box, tempImage, true, true);
1230
+ }
1236
1231
  }
1237
1232
  if (offset)
1238
- x += offset.x, y += offset.y;
1233
+ PointHelper.move(tempImage, offset);
1239
1234
  switch (mode) {
1240
1235
  case 'stretch':
1241
1236
  if (!sameBox)
@@ -1243,12 +1238,12 @@ function getPatternData(paint, box, image) {
1243
1238
  break;
1244
1239
  case 'normal':
1245
1240
  case 'clip':
1246
- if (x || y || scaleX || rotation)
1247
- clipMode(data, box, x, y, scaleX, scaleY, rotation);
1241
+ if (tempImage.x || tempImage.y || scaleX || rotation)
1242
+ clipMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation);
1248
1243
  break;
1249
1244
  case 'repeat':
1250
1245
  if (!sameBox || scaleX || rotation)
1251
- repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, align);
1246
+ repeatMode(data, box, width, height, tempImage.x, tempImage.y, scaleX, scaleY, rotation, align);
1252
1247
  if (!repeat)
1253
1248
  data.repeat = 'repeat';
1254
1249
  break;
@@ -1256,7 +1251,7 @@ function getPatternData(paint, box, image) {
1256
1251
  case 'cover':
1257
1252
  default:
1258
1253
  if (scaleX)
1259
- fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation);
1254
+ fillOrFitMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation);
1260
1255
  }
1261
1256
  if (!data.transform) {
1262
1257
  if (box.x || box.y) {
@@ -1289,6 +1284,8 @@ function image(ui, attrName, paint, boxBounds, firstUse) {
1289
1284
  }
1290
1285
  else {
1291
1286
  leafPaint = { type: paint.type, image };
1287
+ if (image.hasAlphaPixel)
1288
+ leafPaint.isTransparent = true;
1292
1289
  cache = image.use > 1 ? { leafPaint, paint, boxBounds: box.set(boxBounds) } : null;
1293
1290
  }
1294
1291
  if (firstUse || image.loading)
@@ -1313,7 +1310,7 @@ function image(ui, attrName, paint, boxBounds, firstUse) {
1313
1310
  ignoreRender(ui, false);
1314
1311
  if (!ui.destroyed) {
1315
1312
  if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds)) {
1316
- if (image.hasOpacityPixel)
1313
+ if (image.hasAlphaPixel)
1317
1314
  ui.__layout.hitCanvasChanged = true;
1318
1315
  ui.forceUpdate('surface');
1319
1316
  }
@@ -1325,6 +1322,17 @@ function image(ui, attrName, paint, boxBounds, firstUse) {
1325
1322
  onLoadError(ui, event, error);
1326
1323
  leafPaint.loadId = null;
1327
1324
  });
1325
+ if (ui.placeholderColor) {
1326
+ if (!ui.placeholderDelay)
1327
+ image.isPlacehold = true;
1328
+ else
1329
+ setTimeout(() => {
1330
+ if (!image.ready) {
1331
+ image.isPlacehold = true;
1332
+ ui.forceUpdate('surface');
1333
+ }
1334
+ }, ui.placeholderDelay);
1335
+ }
1328
1336
  }
1329
1337
  return leafPaint;
1330
1338
  }
@@ -1530,32 +1538,33 @@ const PaintImageModule = {
1530
1538
  repeatMode
1531
1539
  };
1532
1540
 
1533
- const { toPoint: toPoint$2 } = AroundHelper;
1541
+ const { toPoint: toPoint$2 } = AroundHelper, { hasTransparent } = ColorConvert;
1534
1542
  const realFrom$2 = {};
1535
1543
  const realTo$2 = {};
1536
1544
  function linearGradient(paint, box) {
1537
- let { from, to, type, blendMode, opacity } = paint;
1545
+ let { from, to, type, opacity } = paint;
1538
1546
  toPoint$2(from || 'top', box, realFrom$2);
1539
1547
  toPoint$2(to || 'bottom', box, realTo$2);
1540
1548
  const style = Platform.canvas.createLinearGradient(realFrom$2.x, realFrom$2.y, realTo$2.x, realTo$2.y);
1541
- applyStops(style, paint.stops, opacity);
1542
1549
  const data = { type, style };
1543
- if (blendMode)
1544
- data.blendMode = blendMode;
1550
+ applyStops(data, style, paint.stops, opacity);
1545
1551
  return data;
1546
1552
  }
1547
- function applyStops(gradient, stops, opacity) {
1553
+ function applyStops(data, gradient, stops, opacity) {
1548
1554
  if (stops) {
1549
- let stop;
1555
+ let stop, color, offset, isTransparent;
1550
1556
  for (let i = 0, len = stops.length; i < len; i++) {
1551
1557
  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
- }
1558
+ if (typeof stop === 'string')
1559
+ offset = i / (len - 1), color = ColorConvert.string(stop, opacity);
1560
+ else
1561
+ offset = stop.offset, color = ColorConvert.string(stop.color, opacity);
1562
+ gradient.addColorStop(offset, color);
1563
+ if (!isTransparent && hasTransparent(color))
1564
+ isTransparent = true;
1558
1565
  }
1566
+ if (isTransparent)
1567
+ data.isTransparent = true;
1559
1568
  }
1560
1569
  }
1561
1570
 
@@ -1565,17 +1574,15 @@ const { toPoint: toPoint$1 } = AroundHelper;
1565
1574
  const realFrom$1 = {};
1566
1575
  const realTo$1 = {};
1567
1576
  function radialGradient(paint, box) {
1568
- let { from, to, type, opacity, blendMode, stretch } = paint;
1577
+ let { from, to, type, opacity, stretch } = paint;
1569
1578
  toPoint$1(from || 'center', box, realFrom$1);
1570
1579
  toPoint$1(to || 'bottom', box, realTo$1);
1571
1580
  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
1581
  const data = { type, style };
1582
+ applyStops(data, style, paint.stops, opacity);
1574
1583
  const transform = getTransform(box, realFrom$1, realTo$1, stretch, true);
1575
1584
  if (transform)
1576
1585
  data.transform = transform;
1577
- if (blendMode)
1578
- data.blendMode = blendMode;
1579
1586
  return data;
1580
1587
  }
1581
1588
  function getTransform(box, from, to, stretch, rotate90) {
@@ -1601,17 +1608,15 @@ const { toPoint } = AroundHelper;
1601
1608
  const realFrom = {};
1602
1609
  const realTo = {};
1603
1610
  function conicGradient(paint, box) {
1604
- let { from, to, type, opacity, blendMode, stretch } = paint;
1611
+ let { from, to, type, opacity, stretch } = paint;
1605
1612
  toPoint(from || 'center', box, realFrom);
1606
1613
  toPoint(to || 'bottom', box, realTo);
1607
1614
  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
1615
  const data = { type, style };
1616
+ applyStops(data, style, paint.stops, opacity);
1610
1617
  const transform = getTransform(box, realFrom, realTo, stretch || 1, Platform.conicGradientRotate90);
1611
1618
  if (transform)
1612
1619
  data.transform = transform;
1613
- if (blendMode)
1614
- data.blendMode = blendMode;
1615
1620
  return data;
1616
1621
  }
1617
1622
 
@@ -1944,6 +1949,8 @@ function createRows(drawData, content, style) {
1944
1949
  lastCharType = null;
1945
1950
  startCharSize = charWidth = charSize = wordWidth = rowWidth = 0;
1946
1951
  word = { data: [] }, row = { words: [] };
1952
+ if (__letterSpacing)
1953
+ content = [...content];
1947
1954
  for (let i = 0, len = content.length; i < len; i++) {
1948
1955
  char = content[i];
1949
1956
  if (char === '\n') {
@@ -2350,7 +2357,7 @@ const ColorConvertModule = {
2350
2357
 
2351
2358
  Object.assign(TextConvert, TextConvertModule);
2352
2359
  Object.assign(ColorConvert, ColorConvertModule);
2353
- Object.assign(Paint, PaintModule);
2360
+ Object.assign(Paint$1, PaintModule);
2354
2361
  Object.assign(PaintImage, PaintImageModule);
2355
2362
  Object.assign(PaintGradient, PaintGradientModule);
2356
2363
  Object.assign(Effect, EffectModule);
@@ -2380,8 +2387,8 @@ const ExportModule = {
2380
2387
  const fileType = FileHelper$1.fileType(filename);
2381
2388
  const isDownload = filename.includes('.');
2382
2389
  options = FileHelper$1.getExportOptions(options);
2383
- const { toURL } = Platform$1;
2384
- const { download } = Platform$1.origin;
2390
+ const { toURL } = Platform$2;
2391
+ const { download } = Platform$2.origin;
2385
2392
  if (fileType === 'json') {
2386
2393
  isDownload && download(toURL(JSON.stringify(leaf.toJSON(options.json)), 'text'), filename);
2387
2394
  result = { data: isDownload ? true : leaf.toJSON(options.json) };
@@ -2393,10 +2400,9 @@ const ExportModule = {
2393
2400
  else {
2394
2401
  let renderBounds, trimBounds, scaleX = 1, scaleY = 1;
2395
2402
  const { worldTransform, isLeafer, leafer, isFrame } = leaf;
2396
- const { slice, trim, padding, onCanvas } = options;
2403
+ const { slice, clip, trim, screenshot, padding, onCanvas } = options;
2397
2404
  const smooth = options.smooth === undefined ? (leafer ? leafer.config.smooth : true) : options.smooth;
2398
2405
  const contextSettings = options.contextSettings || (leafer ? leafer.config.contextSettings : undefined);
2399
- const screenshot = options.screenshot || leaf.isApp;
2400
2406
  const fill = (isLeafer && screenshot) ? (options.fill === undefined ? leaf.fill : options.fill) : options.fill;
2401
2407
  const needFill = FileHelper$1.isOpaqueImage(filename) || fill, matrix = new Matrix();
2402
2408
  if (screenshot) {
@@ -2432,12 +2438,9 @@ const ExportModule = {
2432
2438
  const scaleData = { scaleX: 1, scaleY: 1 };
2433
2439
  MathHelper$1.getScaleData(options.scale, options.size, renderBounds, scaleData);
2434
2440
  let pixelRatio = options.pixelRatio || 1;
2435
- if (leaf.isApp) {
2436
- scaleData.scaleX *= pixelRatio;
2437
- scaleData.scaleY *= pixelRatio;
2438
- pixelRatio = leaf.app.pixelRatio;
2439
- }
2440
- const { x, y, width, height } = new Bounds$1(renderBounds).scale(scaleData.scaleX, scaleData.scaleY);
2441
+ let { x, y, width, height } = new Bounds$1(renderBounds).scale(scaleData.scaleX, scaleData.scaleY);
2442
+ if (clip)
2443
+ x += clip.x, y += clip.y, width = clip.width, height = clip.height;
2441
2444
  const renderOptions = { matrix: matrix.scale(1 / scaleData.scaleX, 1 / scaleData.scaleY).invert().translate(-x, -y).withScale(1 / scaleX * scaleData.scaleX, 1 / scaleY * scaleData.scaleY) };
2442
2445
  let canvas = Creator$1.canvas({ width: Math.floor(width), height: Math.floor(height), pixelRatio, smooth, contextSettings });
2443
2446
  let sliceLeaf;
@@ -2488,7 +2491,7 @@ const ExportModule = {
2488
2491
  return addTask((success) => new Promise((resolve) => {
2489
2492
  const getResult = () => __awaiter(this, void 0, void 0, function* () {
2490
2493
  if (!Resource.isComplete)
2491
- return Platform$1.requestRender(getResult);
2494
+ return Platform$2.requestRender(getResult);
2492
2495
  const result = ExportModule.syncExport(leaf, filename, options);
2493
2496
  if (result.data instanceof Promise)
2494
2497
  result.data = yield result.data;
@@ -2533,7 +2536,7 @@ canvas.export = function (filename, options) {
2533
2536
  };
2534
2537
  canvas.toBlob = function (type, quality) {
2535
2538
  return new Promise((resolve) => {
2536
- Platform$1.origin.canvasToBolb(this.view, type, quality).then((blob) => {
2539
+ Platform$2.origin.canvasToBolb(this.view, type, quality).then((blob) => {
2537
2540
  resolve(blob);
2538
2541
  }).catch((e) => {
2539
2542
  debug.error(e);
@@ -2542,11 +2545,11 @@ canvas.toBlob = function (type, quality) {
2542
2545
  });
2543
2546
  };
2544
2547
  canvas.toDataURL = function (type, quality) {
2545
- return Platform$1.origin.canvasToDataURL(this.view, type, quality);
2548
+ return Platform$2.origin.canvasToDataURL(this.view, type, quality);
2546
2549
  };
2547
2550
  canvas.saveAs = function (filename, quality) {
2548
2551
  return new Promise((resolve) => {
2549
- Platform$1.origin.canvasSaveAs(this.view, filename, quality).then(() => {
2552
+ Platform$2.origin.canvasSaveAs(this.view, filename, quality).then(() => {
2550
2553
  resolve(true);
2551
2554
  }).catch((e) => {
2552
2555
  debug.error(e);
@@ -2571,4 +2574,3 @@ Object.assign(Creator, {
2571
2574
  });
2572
2575
 
2573
2576
  export { Layouter, LeaferCanvas, Picker, Renderer, Selector, Watcher, useCanvas };
2574
- //# sourceMappingURL=node.esm.js.map