@leafer-draw/node 2.0.1 → 2.0.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
@@ -72,13 +72,19 @@ class LeaferCanvas extends core.LeaferCanvasBase {
72
72
  }
73
73
  }
74
74
 
75
- const {mineType: mineType, fileType: fileType} = core.FileHelper;
76
-
77
75
  Object.assign(core.Creator, {
78
76
  canvas: (options, manager) => new LeaferCanvas(options, manager),
79
77
  image: options => new core.LeaferImage(options)
80
78
  });
81
79
 
80
+ function loadContent(url_1) {
81
+ return __awaiter(this, arguments, void 0, function*(url, responseType = "text") {
82
+ const response = yield fetch(url);
83
+ if (!response.ok) throw new Error(`${response.status}`);
84
+ return yield response[responseType]();
85
+ });
86
+ }
87
+
82
88
  function useCanvas(canvasType, power) {
83
89
  core.Platform.canvasType = canvasType;
84
90
  if (!core.Platform.origin) {
@@ -98,28 +104,30 @@ function useCanvas(canvasType, power) {
98
104
  download(_url, _filename) {
99
105
  return undefined;
100
106
  },
101
- loadImage(src) {
107
+ loadImage(src, _crossOrigin, _leaferImage) {
102
108
  return loadImage(core.Platform.image.getRealURL(src));
103
- }
109
+ },
110
+ loadContent: loadContent
104
111
  };
105
112
  core.Platform.roundRectPatch = true;
106
113
  } else if (canvasType === "napi") {
107
114
  const {Canvas: Canvas, loadImage: loadImage} = power;
108
115
  core.Platform.origin = {
109
116
  createCanvas: (width, height, format) => new Canvas(width, height, format),
110
- canvasToDataURL: (canvas, type, quality) => canvas.toDataURL(mineType(type), quality),
117
+ canvasToDataURL: (canvas, type, quality) => canvas.toDataURL(core.FileHelper.mimeType(type), quality),
111
118
  canvasToBolb: (canvas, type, quality) => __awaiter(this, void 0, void 0, function*() {
112
- return canvas.toBuffer(mineType(type), quality);
119
+ return canvas.toBuffer(core.FileHelper.mimeType(type), quality);
113
120
  }),
114
121
  canvasSaveAs: (canvas, filename, quality) => __awaiter(this, void 0, void 0, function*() {
115
- return fs.writeFileSync(filename, canvas.toBuffer(mineType(fileType(filename)), quality));
122
+ return fs.writeFileSync(filename, canvas.toBuffer(core.FileHelper.mimeType(core.FileHelper.fileType(filename)), quality));
116
123
  }),
117
124
  download(_url, _filename) {
118
125
  return undefined;
119
126
  },
120
- loadImage(src) {
127
+ loadImage(src, _crossOrigin, _leaferImage) {
121
128
  return loadImage(core.Platform.image.getRealURL(src));
122
- }
129
+ },
130
+ loadContent: loadContent
123
131
  };
124
132
  }
125
133
  core.Platform.ellipseToCurve = true;
@@ -607,7 +615,7 @@ class Renderer {
607
615
  getCellList() {
608
616
  return undefined;
609
617
  }
610
- addBlock(block) {
618
+ addBlock(block, _leafList) {
611
619
  if (!this.updateBlocks) this.updateBlocks = [];
612
620
  this.updateBlocks.push(block);
613
621
  }
@@ -655,7 +663,8 @@ class Renderer {
655
663
  __onLayoutEnd(event) {
656
664
  if (event.data) event.data.map(item => {
657
665
  let empty;
658
- if (item.updatedList) item.updatedList.list.some(leaf => {
666
+ const {updatedList: updatedList} = item;
667
+ if (updatedList) updatedList.list.some(leaf => {
659
668
  empty = !leaf.__world.width || !leaf.__world.height;
660
669
  if (empty) {
661
670
  if (!leaf.isLeafer) debug$1.tip(leaf.innerName, ": empty");
@@ -663,7 +672,7 @@ class Renderer {
663
672
  }
664
673
  return empty;
665
674
  });
666
- this.addBlock(empty ? this.canvas.bounds : item.updatedBounds);
675
+ this.addBlock(empty ? this.canvas.bounds : item.updatedBounds, updatedList);
667
676
  });
668
677
  }
669
678
  emitRender(type, bounds, options) {
@@ -728,8 +737,8 @@ function fills(fills, ui, canvas, renderOptions) {
728
737
  canvas.save();
729
738
  if (item.transform) canvas.transform(item.transform);
730
739
  if (originPaint.scaleFixed) {
731
- const {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true);
732
- if (originPaint.scaleFixed === true || originPaint.scaleFixed === "zoom-in" && scaleX > 1 && scaleY > 1) canvas.scale(1 / scaleX, 1 / scaleY);
740
+ const {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true, originPaint.scaleFixed, false);
741
+ if (scaleX !== 1) canvas.scale(scaleX, scaleY);
733
742
  }
734
743
  if (originPaint.blendMode) canvas.blendMode = originPaint.blendMode;
735
744
  fillPathOrText(ui, canvas, renderOptions);
@@ -1003,11 +1012,14 @@ function compute(attrName, ui) {
1003
1012
  function getLeafPaint(attrName, paint, ui) {
1004
1013
  if (!core.isObject(paint) || paint.visible === false || paint.opacity === 0) return undefined;
1005
1014
  let leafPaint;
1006
- const {boxBounds: boxBounds} = ui.__layout;
1007
- switch (paint.type) {
1015
+ const {boxBounds: boxBounds} = ui.__layout, {type: type} = paint;
1016
+ switch (type) {
1008
1017
  case "image":
1018
+ case "film":
1019
+ case "video":
1009
1020
  if (!paint.url) return undefined;
1010
1021
  leafPaint = draw.PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
1022
+ if (type !== "image") draw.PaintImage[type](leafPaint);
1011
1023
  break;
1012
1024
 
1013
1025
  case "linear":
@@ -1023,7 +1035,7 @@ function getLeafPaint(attrName, paint, ui) {
1023
1035
  break;
1024
1036
 
1025
1037
  case "solid":
1026
- const {type: type, color: color, opacity: opacity} = paint;
1038
+ const {color: color, opacity: opacity} = paint;
1027
1039
  leafPaint = {
1028
1040
  type: type,
1029
1041
  style: draw.ColorConvert.string(color, opacity)
@@ -1067,7 +1079,7 @@ const {isSame: isSame} = core.BoundsHelper;
1067
1079
 
1068
1080
  function image(ui, attrName, paint, boxBounds, firstUse) {
1069
1081
  let leafPaint, event;
1070
- const image = core.ImageManager.get(paint);
1082
+ const image = core.ImageManager.get(paint, paint.type);
1071
1083
  if (cache && paint === cache.paint && isSame(boxBounds, cache.boxBounds)) {
1072
1084
  leafPaint = cache.leafPaint;
1073
1085
  } else {
@@ -1128,8 +1140,8 @@ function image(ui, attrName, paint, boxBounds, firstUse) {
1128
1140
  }
1129
1141
 
1130
1142
  function checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds) {
1131
- if (attrName === "fill" && !ui.__.__naturalWidth) {
1132
- const data = ui.__;
1143
+ const data = ui.__;
1144
+ if (attrName === "fill" && !data.__naturalWidth) {
1133
1145
  data.__naturalWidth = image.width / data.pixelRatio;
1134
1146
  data.__naturalHeight = image.height / data.pixelRatio;
1135
1147
  if (data.__autoSide) {
@@ -1141,7 +1153,13 @@ function checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds
1141
1153
  return false;
1142
1154
  }
1143
1155
  }
1144
- if (!leafPaint.data) draw.PaintImage.createData(leafPaint, image, paint, boxBounds);
1156
+ if (!leafPaint.data) {
1157
+ draw.PaintImage.createData(leafPaint, image, paint, boxBounds);
1158
+ const {transform: transform} = leafPaint.data, {opacity: opacity, blendMode: blendMode} = paint;
1159
+ const clip = transform && !transform.onlyScale || data.path || data.cornerRadius;
1160
+ if (clip || opacity && opacity < 1 || blendMode) leafPaint.complex = clip ? 2 : true;
1161
+ }
1162
+ if (paint.filter) draw.PaintImage.applyFilter(leafPaint, image, paint.filter, ui);
1145
1163
  return true;
1146
1164
  }
1147
1165
 
@@ -1184,7 +1202,7 @@ function getPatternData(paint, box, image) {
1184
1202
  if (paint.padding) box = tempBox.set(box).shrink(paint.padding);
1185
1203
  if (paint.mode === "strench") paint.mode = "stretch";
1186
1204
  const {width: width, height: height} = image;
1187
- const {opacity: opacity, mode: mode, align: align, offset: offset, scale: scale, size: size, rotation: rotation, skew: skew, clipSize: clipSize, repeat: repeat, gap: gap, filters: filters, interlace: interlace} = paint;
1205
+ const {mode: mode, align: align, offset: offset, scale: scale, size: size, rotation: rotation, skew: skew, clipSize: clipSize, repeat: repeat, gap: gap, interlace: interlace} = paint;
1188
1206
  const sameBox = box.width === width && box.height === height;
1189
1207
  const data = {
1190
1208
  mode: mode
@@ -1247,8 +1265,6 @@ function getPatternData(paint, box, image) {
1247
1265
  data.scaleX = scaleX;
1248
1266
  data.scaleY = scaleY;
1249
1267
  }
1250
- if (opacity && opacity < 1) data.opacity = opacity;
1251
- if (filters) data.filters = filters;
1252
1268
  if (repeat) data.repeat = core.isString(repeat) ? repeat === "x" ? "repeat-x" : "repeat-y" : "repeat";
1253
1269
  if (interlace) data.interlace = core.isNumber(interlace) || interlace.type === "percent" ? {
1254
1270
  type: "x",
@@ -1279,7 +1295,7 @@ const {get: get$2, set: set, rotateOfOuter: rotateOfOuter$1, translate: translat
1279
1295
 
1280
1296
  function stretchMode(data, box, scaleX, scaleY) {
1281
1297
  const transform = get$2(), {x: x, y: y} = box;
1282
- if (x || y) translate(transform, x, y); else transform.onlyScale = true;
1298
+ if (x || y) translate(transform, x, y); else if (scaleX > 0 && scaleY > 0) transform.onlyScale = true;
1283
1299
  scaleHelper(transform, scaleX, scaleY);
1284
1300
  data.transform = transform;
1285
1301
  }
@@ -1368,10 +1384,10 @@ function createPatternTask(paint, ui, canvas, renderOptions) {
1368
1384
  }
1369
1385
 
1370
1386
  function createPattern(paint, ui, canvas, renderOptions) {
1371
- let {scaleX: scaleX, scaleY: scaleY} = draw.PaintImage.getImageRenderScaleData(paint, ui, canvas, renderOptions), id = scaleX + "-" + scaleY;
1387
+ let {scaleX: scaleX, scaleY: scaleY} = draw.PaintImage.getImageRenderScaleData(paint, ui, canvas, renderOptions), id = paint.film ? paint.nowIndex : scaleX + "-" + scaleY;
1372
1388
  if (paint.patternId !== id && !ui.destroyed) {
1373
1389
  if (!(core.Platform.image.isLarge(paint.image, scaleX, scaleY) && !paint.data.repeat)) {
1374
- const {image: image, data: data} = paint, {transform: transform, gap: gap} = data, fixScale = draw.PaintImage.getPatternFixScale(paint, scaleX, scaleY);
1390
+ const {image: image, data: data} = paint, {opacity: opacity} = paint.originPaint, {transform: transform, gap: gap} = data, fixScale = draw.PaintImage.getPatternFixScale(paint, scaleX, scaleY);
1375
1391
  let imageMatrix, xGap, yGap, {width: width, height: height} = image;
1376
1392
  if (fixScale) scaleX *= fixScale, scaleY *= fixScale;
1377
1393
  width *= scaleX;
@@ -1387,7 +1403,7 @@ function createPattern(paint, ui, canvas, renderOptions) {
1387
1403
  if (transform) copy$1(imageMatrix, transform);
1388
1404
  scale(imageMatrix, 1 / scaleX, 1 / scaleY);
1389
1405
  }
1390
- const imageCanvas = image.getCanvas(width, height, data.opacity, data.filters, xGap, yGap, ui.leafer && ui.leafer.config.smooth, data.interlace);
1406
+ const imageCanvas = image.getCanvas(width, height, opacity, undefined, xGap, yGap, ui.leafer && ui.leafer.config.smooth, data.interlace);
1391
1407
  const pattern = image.getPattern(imageCanvas, data.repeat || (core.Platform.origin.noRepeat || "no-repeat"), imageMatrix, paint);
1392
1408
  paint.style = pattern;
1393
1409
  paint.patternId = id;
@@ -1408,15 +1424,15 @@ function getPatternFixScale(paint, imageScaleX, imageScaleY) {
1408
1424
  }
1409
1425
 
1410
1426
  function checkImage(paint, drawImage, ui, canvas, renderOptions) {
1411
- const {scaleX: scaleX, scaleY: scaleY} = draw.PaintImage.getImageRenderScaleData(paint, ui, canvas, renderOptions);
1427
+ const {scaleX: scaleX, scaleY: scaleY} = draw.PaintImage.getImageRenderScaleData(paint, ui, canvas, renderOptions), id = paint.film ? paint.nowIndex : scaleX + "-" + scaleY;
1412
1428
  const {image: image, data: data, originPaint: originPaint} = paint, {exporting: exporting, snapshot: snapshot} = renderOptions;
1413
- if (!data || paint.patternId === scaleX + "-" + scaleY && !exporting || snapshot) {
1429
+ if (!data || paint.patternId === id && !exporting || snapshot) {
1414
1430
  return false;
1415
1431
  } else {
1416
1432
  if (drawImage) {
1417
1433
  if (data.repeat) {
1418
1434
  drawImage = false;
1419
- } else if (!(originPaint.changeful || core.Platform.name === "miniapp" && core.ResizeEvent.isResizing(ui) || exporting)) {
1435
+ } else if (!(originPaint.changeful || paint.film || core.Platform.name === "miniapp" && core.ResizeEvent.isResizing(ui) || exporting)) {
1420
1436
  drawImage = core.Platform.image.isLarge(image, scaleX, scaleY) || image.width * scaleX > 8096 || image.height * scaleY > 8096;
1421
1437
  }
1422
1438
  }
@@ -1434,20 +1450,21 @@ function checkImage(paint, drawImage, ui, canvas, renderOptions) {
1434
1450
  }
1435
1451
  }
1436
1452
 
1437
- function drawImage(paint, _imageScaleX, _imageScaleY, ui, canvas, _renderOptions) {
1438
- const {data: data, image: image} = paint, {blendMode: blendMode} = paint.originPaint, {opacity: opacity, transform: transform} = data, view = image.getFull(data.filters), u = ui.__;
1439
- let {width: width, height: height} = image, clipUI;
1440
- if ((clipUI = transform && !transform.onlyScale || u.path || u.cornerRadius) || opacity || blendMode) {
1453
+ function drawImage(paint, imageScaleX, imageScaleY, ui, canvas, _renderOptions) {
1454
+ const {data: data, image: image, complex: complex} = paint;
1455
+ let {width: width, height: height} = image;
1456
+ if (complex) {
1457
+ const {blendMode: blendMode, opacity: opacity} = paint.originPaint, {transform: transform} = data;
1441
1458
  canvas.save();
1442
- clipUI && canvas.clipUI(ui);
1459
+ complex === 2 && canvas.clipUI(ui);
1443
1460
  blendMode && (canvas.blendMode = blendMode);
1444
1461
  opacity && (canvas.opacity *= opacity);
1445
1462
  transform && canvas.transform(transform);
1446
- canvas.drawImage(view, 0, 0, width, height);
1463
+ image.render(canvas, 0, 0, width, height, ui, paint, imageScaleX, imageScaleY);
1447
1464
  canvas.restore();
1448
1465
  } else {
1449
1466
  if (data.scaleX) width *= data.scaleX, height *= data.scaleY;
1450
- canvas.drawImage(view, 0, 0, width, height);
1467
+ image.render(canvas, 0, 0, width, height, ui, paint, imageScaleX, imageScaleY);
1451
1468
  }
1452
1469
  }
1453
1470
 
@@ -1477,6 +1494,7 @@ function recycleImage(attrName, data) {
1477
1494
  if (!recycleMap) recycleMap = {};
1478
1495
  recycleMap[url] = true;
1479
1496
  core.ImageManager.recyclePaint(paint);
1497
+ if (data.__willDestroy && image.parent) draw.PaintImage.recycleFilter(image, data.__leaf);
1480
1498
  if (image.loading) {
1481
1499
  if (!input) {
1482
1500
  input = data.__input && data.__input[attrName] || [];
@@ -2641,6 +2659,13 @@ draw.UI.prototype.syncExport = function(filename, options) {
2641
2659
  return draw.Export.syncExport(this, filename, options);
2642
2660
  };
2643
2661
 
2662
+ Object.defineProperty(exports, "LeaferFilm", {
2663
+ enumerable: true,
2664
+ get: function() {
2665
+ return core.LeaferFilm;
2666
+ }
2667
+ });
2668
+
2644
2669
  Object.defineProperty(exports, "LeaferImage", {
2645
2670
  enumerable: true,
2646
2671
  get: function() {
@@ -2648,6 +2673,13 @@ Object.defineProperty(exports, "LeaferImage", {
2648
2673
  }
2649
2674
  });
2650
2675
 
2676
+ Object.defineProperty(exports, "LeaferVideo", {
2677
+ enumerable: true,
2678
+ get: function() {
2679
+ return core.LeaferVideo;
2680
+ }
2681
+ });
2682
+
2651
2683
  exports.Layouter = Layouter;
2652
2684
 
2653
2685
  exports.LeaferCanvas = LeaferCanvas;
package/dist/node.esm.js CHANGED
@@ -1,8 +1,8 @@
1
- import { LeaferCanvasBase, Platform, canvasPatch, FileHelper, Creator, LeaferImage, defineKey, LeafList, DataHelper, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, LeafBoundsHelper, Bounds, isArray, Debug, LeafLevelList, LayoutEvent, Run, ImageManager, ResizeEvent, isObject, BoundsHelper, FourNumberHelper, Matrix, isUndefined, isString, ImageEvent, MatrixHelper, MathHelper, AlignHelper, PointHelper, isNumber, getMatrixData, AroundHelper, Direction4 } from "@leafer/core";
1
+ import { LeaferCanvasBase, Platform, canvasPatch, Creator, LeaferImage, defineKey, FileHelper, LeafList, DataHelper, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, LeafBoundsHelper, Bounds, isArray, Debug, LeafLevelList, LayoutEvent, Run, ImageManager, ResizeEvent, isObject, BoundsHelper, FourNumberHelper, Matrix, isUndefined, isString, ImageEvent, MatrixHelper, MathHelper, AlignHelper, PointHelper, isNumber, getMatrixData, AroundHelper, Direction4 } from "@leafer/core";
2
2
 
3
3
  export * from "@leafer/core";
4
4
 
5
- export { LeaferImage } from "@leafer/core";
5
+ export { LeaferFilm, LeaferImage, LeaferVideo } from "@leafer/core";
6
6
 
7
7
  import { writeFileSync } from "fs";
8
8
 
@@ -76,13 +76,19 @@ class LeaferCanvas extends LeaferCanvasBase {
76
76
  }
77
77
  }
78
78
 
79
- const {mineType: mineType, fileType: fileType} = FileHelper;
80
-
81
79
  Object.assign(Creator, {
82
80
  canvas: (options, manager) => new LeaferCanvas(options, manager),
83
81
  image: options => new LeaferImage(options)
84
82
  });
85
83
 
84
+ function loadContent(url_1) {
85
+ return __awaiter(this, arguments, void 0, function*(url, responseType = "text") {
86
+ const response = yield fetch(url);
87
+ if (!response.ok) throw new Error(`${response.status}`);
88
+ return yield response[responseType]();
89
+ });
90
+ }
91
+
86
92
  function useCanvas(canvasType, power) {
87
93
  Platform.canvasType = canvasType;
88
94
  if (!Platform.origin) {
@@ -102,28 +108,30 @@ function useCanvas(canvasType, power) {
102
108
  download(_url, _filename) {
103
109
  return undefined;
104
110
  },
105
- loadImage(src) {
111
+ loadImage(src, _crossOrigin, _leaferImage) {
106
112
  return loadImage(Platform.image.getRealURL(src));
107
- }
113
+ },
114
+ loadContent: loadContent
108
115
  };
109
116
  Platform.roundRectPatch = true;
110
117
  } else if (canvasType === "napi") {
111
118
  const {Canvas: Canvas, loadImage: loadImage} = power;
112
119
  Platform.origin = {
113
120
  createCanvas: (width, height, format) => new Canvas(width, height, format),
114
- canvasToDataURL: (canvas, type, quality) => canvas.toDataURL(mineType(type), quality),
121
+ canvasToDataURL: (canvas, type, quality) => canvas.toDataURL(FileHelper.mimeType(type), quality),
115
122
  canvasToBolb: (canvas, type, quality) => __awaiter(this, void 0, void 0, function*() {
116
- return canvas.toBuffer(mineType(type), quality);
123
+ return canvas.toBuffer(FileHelper.mimeType(type), quality);
117
124
  }),
118
125
  canvasSaveAs: (canvas, filename, quality) => __awaiter(this, void 0, void 0, function*() {
119
- return writeFileSync(filename, canvas.toBuffer(mineType(fileType(filename)), quality));
126
+ return writeFileSync(filename, canvas.toBuffer(FileHelper.mimeType(FileHelper.fileType(filename)), quality));
120
127
  }),
121
128
  download(_url, _filename) {
122
129
  return undefined;
123
130
  },
124
- loadImage(src) {
131
+ loadImage(src, _crossOrigin, _leaferImage) {
125
132
  return loadImage(Platform.image.getRealURL(src));
126
- }
133
+ },
134
+ loadContent: loadContent
127
135
  };
128
136
  }
129
137
  Platform.ellipseToCurve = true;
@@ -611,7 +619,7 @@ class Renderer {
611
619
  getCellList() {
612
620
  return undefined;
613
621
  }
614
- addBlock(block) {
622
+ addBlock(block, _leafList) {
615
623
  if (!this.updateBlocks) this.updateBlocks = [];
616
624
  this.updateBlocks.push(block);
617
625
  }
@@ -659,7 +667,8 @@ class Renderer {
659
667
  __onLayoutEnd(event) {
660
668
  if (event.data) event.data.map(item => {
661
669
  let empty;
662
- if (item.updatedList) item.updatedList.list.some(leaf => {
670
+ const {updatedList: updatedList} = item;
671
+ if (updatedList) updatedList.list.some(leaf => {
663
672
  empty = !leaf.__world.width || !leaf.__world.height;
664
673
  if (empty) {
665
674
  if (!leaf.isLeafer) debug$1.tip(leaf.innerName, ": empty");
@@ -667,7 +676,7 @@ class Renderer {
667
676
  }
668
677
  return empty;
669
678
  });
670
- this.addBlock(empty ? this.canvas.bounds : item.updatedBounds);
679
+ this.addBlock(empty ? this.canvas.bounds : item.updatedBounds, updatedList);
671
680
  });
672
681
  }
673
682
  emitRender(type, bounds, options) {
@@ -732,8 +741,8 @@ function fills(fills, ui, canvas, renderOptions) {
732
741
  canvas.save();
733
742
  if (item.transform) canvas.transform(item.transform);
734
743
  if (originPaint.scaleFixed) {
735
- const {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true);
736
- if (originPaint.scaleFixed === true || originPaint.scaleFixed === "zoom-in" && scaleX > 1 && scaleY > 1) canvas.scale(1 / scaleX, 1 / scaleY);
744
+ const {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true, originPaint.scaleFixed, false);
745
+ if (scaleX !== 1) canvas.scale(scaleX, scaleY);
737
746
  }
738
747
  if (originPaint.blendMode) canvas.blendMode = originPaint.blendMode;
739
748
  fillPathOrText(ui, canvas, renderOptions);
@@ -1007,11 +1016,14 @@ function compute(attrName, ui) {
1007
1016
  function getLeafPaint(attrName, paint, ui) {
1008
1017
  if (!isObject(paint) || paint.visible === false || paint.opacity === 0) return undefined;
1009
1018
  let leafPaint;
1010
- const {boxBounds: boxBounds} = ui.__layout;
1011
- switch (paint.type) {
1019
+ const {boxBounds: boxBounds} = ui.__layout, {type: type} = paint;
1020
+ switch (type) {
1012
1021
  case "image":
1022
+ case "film":
1023
+ case "video":
1013
1024
  if (!paint.url) return undefined;
1014
1025
  leafPaint = PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
1026
+ if (type !== "image") PaintImage[type](leafPaint);
1015
1027
  break;
1016
1028
 
1017
1029
  case "linear":
@@ -1027,7 +1039,7 @@ function getLeafPaint(attrName, paint, ui) {
1027
1039
  break;
1028
1040
 
1029
1041
  case "solid":
1030
- const {type: type, color: color, opacity: opacity} = paint;
1042
+ const {color: color, opacity: opacity} = paint;
1031
1043
  leafPaint = {
1032
1044
  type: type,
1033
1045
  style: ColorConvert.string(color, opacity)
@@ -1071,7 +1083,7 @@ const {isSame: isSame} = BoundsHelper;
1071
1083
 
1072
1084
  function image(ui, attrName, paint, boxBounds, firstUse) {
1073
1085
  let leafPaint, event;
1074
- const image = ImageManager.get(paint);
1086
+ const image = ImageManager.get(paint, paint.type);
1075
1087
  if (cache && paint === cache.paint && isSame(boxBounds, cache.boxBounds)) {
1076
1088
  leafPaint = cache.leafPaint;
1077
1089
  } else {
@@ -1132,8 +1144,8 @@ function image(ui, attrName, paint, boxBounds, firstUse) {
1132
1144
  }
1133
1145
 
1134
1146
  function checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds) {
1135
- if (attrName === "fill" && !ui.__.__naturalWidth) {
1136
- const data = ui.__;
1147
+ const data = ui.__;
1148
+ if (attrName === "fill" && !data.__naturalWidth) {
1137
1149
  data.__naturalWidth = image.width / data.pixelRatio;
1138
1150
  data.__naturalHeight = image.height / data.pixelRatio;
1139
1151
  if (data.__autoSide) {
@@ -1145,7 +1157,13 @@ function checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds
1145
1157
  return false;
1146
1158
  }
1147
1159
  }
1148
- if (!leafPaint.data) PaintImage.createData(leafPaint, image, paint, boxBounds);
1160
+ if (!leafPaint.data) {
1161
+ PaintImage.createData(leafPaint, image, paint, boxBounds);
1162
+ const {transform: transform} = leafPaint.data, {opacity: opacity, blendMode: blendMode} = paint;
1163
+ const clip = transform && !transform.onlyScale || data.path || data.cornerRadius;
1164
+ if (clip || opacity && opacity < 1 || blendMode) leafPaint.complex = clip ? 2 : true;
1165
+ }
1166
+ if (paint.filter) PaintImage.applyFilter(leafPaint, image, paint.filter, ui);
1149
1167
  return true;
1150
1168
  }
1151
1169
 
@@ -1188,7 +1206,7 @@ function getPatternData(paint, box, image) {
1188
1206
  if (paint.padding) box = tempBox.set(box).shrink(paint.padding);
1189
1207
  if (paint.mode === "strench") paint.mode = "stretch";
1190
1208
  const {width: width, height: height} = image;
1191
- const {opacity: opacity, mode: mode, align: align, offset: offset, scale: scale, size: size, rotation: rotation, skew: skew, clipSize: clipSize, repeat: repeat, gap: gap, filters: filters, interlace: interlace} = paint;
1209
+ const {mode: mode, align: align, offset: offset, scale: scale, size: size, rotation: rotation, skew: skew, clipSize: clipSize, repeat: repeat, gap: gap, interlace: interlace} = paint;
1192
1210
  const sameBox = box.width === width && box.height === height;
1193
1211
  const data = {
1194
1212
  mode: mode
@@ -1251,8 +1269,6 @@ function getPatternData(paint, box, image) {
1251
1269
  data.scaleX = scaleX;
1252
1270
  data.scaleY = scaleY;
1253
1271
  }
1254
- if (opacity && opacity < 1) data.opacity = opacity;
1255
- if (filters) data.filters = filters;
1256
1272
  if (repeat) data.repeat = isString(repeat) ? repeat === "x" ? "repeat-x" : "repeat-y" : "repeat";
1257
1273
  if (interlace) data.interlace = isNumber(interlace) || interlace.type === "percent" ? {
1258
1274
  type: "x",
@@ -1283,7 +1299,7 @@ const {get: get$2, set: set, rotateOfOuter: rotateOfOuter$1, translate: translat
1283
1299
 
1284
1300
  function stretchMode(data, box, scaleX, scaleY) {
1285
1301
  const transform = get$2(), {x: x, y: y} = box;
1286
- if (x || y) translate(transform, x, y); else transform.onlyScale = true;
1302
+ if (x || y) translate(transform, x, y); else if (scaleX > 0 && scaleY > 0) transform.onlyScale = true;
1287
1303
  scaleHelper(transform, scaleX, scaleY);
1288
1304
  data.transform = transform;
1289
1305
  }
@@ -1372,10 +1388,10 @@ function createPatternTask(paint, ui, canvas, renderOptions) {
1372
1388
  }
1373
1389
 
1374
1390
  function createPattern(paint, ui, canvas, renderOptions) {
1375
- let {scaleX: scaleX, scaleY: scaleY} = PaintImage.getImageRenderScaleData(paint, ui, canvas, renderOptions), id = scaleX + "-" + scaleY;
1391
+ let {scaleX: scaleX, scaleY: scaleY} = PaintImage.getImageRenderScaleData(paint, ui, canvas, renderOptions), id = paint.film ? paint.nowIndex : scaleX + "-" + scaleY;
1376
1392
  if (paint.patternId !== id && !ui.destroyed) {
1377
1393
  if (!(Platform.image.isLarge(paint.image, scaleX, scaleY) && !paint.data.repeat)) {
1378
- const {image: image, data: data} = paint, {transform: transform, gap: gap} = data, fixScale = PaintImage.getPatternFixScale(paint, scaleX, scaleY);
1394
+ const {image: image, data: data} = paint, {opacity: opacity} = paint.originPaint, {transform: transform, gap: gap} = data, fixScale = PaintImage.getPatternFixScale(paint, scaleX, scaleY);
1379
1395
  let imageMatrix, xGap, yGap, {width: width, height: height} = image;
1380
1396
  if (fixScale) scaleX *= fixScale, scaleY *= fixScale;
1381
1397
  width *= scaleX;
@@ -1391,7 +1407,7 @@ function createPattern(paint, ui, canvas, renderOptions) {
1391
1407
  if (transform) copy$1(imageMatrix, transform);
1392
1408
  scale(imageMatrix, 1 / scaleX, 1 / scaleY);
1393
1409
  }
1394
- const imageCanvas = image.getCanvas(width, height, data.opacity, data.filters, xGap, yGap, ui.leafer && ui.leafer.config.smooth, data.interlace);
1410
+ const imageCanvas = image.getCanvas(width, height, opacity, undefined, xGap, yGap, ui.leafer && ui.leafer.config.smooth, data.interlace);
1395
1411
  const pattern = image.getPattern(imageCanvas, data.repeat || (Platform.origin.noRepeat || "no-repeat"), imageMatrix, paint);
1396
1412
  paint.style = pattern;
1397
1413
  paint.patternId = id;
@@ -1412,15 +1428,15 @@ function getPatternFixScale(paint, imageScaleX, imageScaleY) {
1412
1428
  }
1413
1429
 
1414
1430
  function checkImage(paint, drawImage, ui, canvas, renderOptions) {
1415
- const {scaleX: scaleX, scaleY: scaleY} = PaintImage.getImageRenderScaleData(paint, ui, canvas, renderOptions);
1431
+ const {scaleX: scaleX, scaleY: scaleY} = PaintImage.getImageRenderScaleData(paint, ui, canvas, renderOptions), id = paint.film ? paint.nowIndex : scaleX + "-" + scaleY;
1416
1432
  const {image: image, data: data, originPaint: originPaint} = paint, {exporting: exporting, snapshot: snapshot} = renderOptions;
1417
- if (!data || paint.patternId === scaleX + "-" + scaleY && !exporting || snapshot) {
1433
+ if (!data || paint.patternId === id && !exporting || snapshot) {
1418
1434
  return false;
1419
1435
  } else {
1420
1436
  if (drawImage) {
1421
1437
  if (data.repeat) {
1422
1438
  drawImage = false;
1423
- } else if (!(originPaint.changeful || Platform.name === "miniapp" && ResizeEvent.isResizing(ui) || exporting)) {
1439
+ } else if (!(originPaint.changeful || paint.film || Platform.name === "miniapp" && ResizeEvent.isResizing(ui) || exporting)) {
1424
1440
  drawImage = Platform.image.isLarge(image, scaleX, scaleY) || image.width * scaleX > 8096 || image.height * scaleY > 8096;
1425
1441
  }
1426
1442
  }
@@ -1438,20 +1454,21 @@ function checkImage(paint, drawImage, ui, canvas, renderOptions) {
1438
1454
  }
1439
1455
  }
1440
1456
 
1441
- function drawImage(paint, _imageScaleX, _imageScaleY, ui, canvas, _renderOptions) {
1442
- const {data: data, image: image} = paint, {blendMode: blendMode} = paint.originPaint, {opacity: opacity, transform: transform} = data, view = image.getFull(data.filters), u = ui.__;
1443
- let {width: width, height: height} = image, clipUI;
1444
- if ((clipUI = transform && !transform.onlyScale || u.path || u.cornerRadius) || opacity || blendMode) {
1457
+ function drawImage(paint, imageScaleX, imageScaleY, ui, canvas, _renderOptions) {
1458
+ const {data: data, image: image, complex: complex} = paint;
1459
+ let {width: width, height: height} = image;
1460
+ if (complex) {
1461
+ const {blendMode: blendMode, opacity: opacity} = paint.originPaint, {transform: transform} = data;
1445
1462
  canvas.save();
1446
- clipUI && canvas.clipUI(ui);
1463
+ complex === 2 && canvas.clipUI(ui);
1447
1464
  blendMode && (canvas.blendMode = blendMode);
1448
1465
  opacity && (canvas.opacity *= opacity);
1449
1466
  transform && canvas.transform(transform);
1450
- canvas.drawImage(view, 0, 0, width, height);
1467
+ image.render(canvas, 0, 0, width, height, ui, paint, imageScaleX, imageScaleY);
1451
1468
  canvas.restore();
1452
1469
  } else {
1453
1470
  if (data.scaleX) width *= data.scaleX, height *= data.scaleY;
1454
- canvas.drawImage(view, 0, 0, width, height);
1471
+ image.render(canvas, 0, 0, width, height, ui, paint, imageScaleX, imageScaleY);
1455
1472
  }
1456
1473
  }
1457
1474
 
@@ -1481,6 +1498,7 @@ function recycleImage(attrName, data) {
1481
1498
  if (!recycleMap) recycleMap = {};
1482
1499
  recycleMap[url] = true;
1483
1500
  ImageManager.recyclePaint(paint);
1501
+ if (data.__willDestroy && image.parent) PaintImage.recycleFilter(image, data.__leaf);
1484
1502
  if (image.loading) {
1485
1503
  if (!input) {
1486
1504
  input = data.__input && data.__input[attrName] || [];