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