modern-canvas 0.4.50 → 0.4.52

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/index.mjs CHANGED
@@ -7144,13 +7144,15 @@ ColorReplaceEffect = __decorateClass$J([
7144
7144
  ], ColorReplaceEffect);
7145
7145
 
7146
7146
  class CanvasContext extends Path2D {
7147
- textureTransform;
7148
7147
  fillStyle;
7149
7148
  strokeStyle;
7150
7149
  lineCap;
7151
7150
  lineJoin;
7152
7151
  lineWidth;
7153
7152
  miterLimit;
7153
+ // custom
7154
+ uvTransform;
7155
+ vertTransform;
7154
7156
  _defaultStyle = Texture2D.EMPTY;
7155
7157
  _draws = [];
7156
7158
  _toTexture(source) {
@@ -7172,7 +7174,8 @@ class CanvasContext extends Path2D {
7172
7174
  type: "stroke",
7173
7175
  path,
7174
7176
  texture,
7175
- textureTransform: this.textureTransform,
7177
+ uvTransform: this.uvTransform,
7178
+ vertTransform: this.vertTransform,
7176
7179
  style: {
7177
7180
  alignment: 0.5,
7178
7181
  cap: this.lineCap ?? "butt",
@@ -7201,7 +7204,8 @@ class CanvasContext extends Path2D {
7201
7204
  type: "fill",
7202
7205
  path,
7203
7206
  texture,
7204
- textureTransform: this.textureTransform
7207
+ uvTransform: this.uvTransform,
7208
+ vertTransform: this.vertTransform
7205
7209
  });
7206
7210
  super.reset();
7207
7211
  }
@@ -7209,7 +7213,8 @@ class CanvasContext extends Path2D {
7209
7213
  super.copy(source);
7210
7214
  this.strokeStyle = source.strokeStyle;
7211
7215
  this.fillStyle = source.fillStyle;
7212
- this.textureTransform = source.textureTransform;
7216
+ this.uvTransform = source.uvTransform;
7217
+ this.vertTransform = source.vertTransform;
7213
7218
  this.lineCap = source.lineCap;
7214
7219
  this.lineJoin = source.lineJoin;
7215
7220
  this.lineWidth = source.lineWidth;
@@ -7221,7 +7226,8 @@ class CanvasContext extends Path2D {
7221
7226
  super.reset();
7222
7227
  this.strokeStyle = void 0;
7223
7228
  this.fillStyle = void 0;
7224
- this.textureTransform = void 0;
7229
+ this.uvTransform = void 0;
7230
+ this.vertTransform = void 0;
7225
7231
  this.lineCap = void 0;
7226
7232
  this.lineJoin = void 0;
7227
7233
  this.lineWidth = void 0;
@@ -7229,8 +7235,9 @@ class CanvasContext extends Path2D {
7229
7235
  this._draws.length = 0;
7230
7236
  return this;
7231
7237
  }
7232
- buildUvs(start, vertices, uvs, texture, textureTransform) {
7238
+ buildUvs(start, vertices, uvs, texture, uvTransform) {
7233
7239
  if (texture) {
7240
+ const _uvTransform = uvTransform ? typeof uvTransform === "function" ? uvTransform : (x, y) => uvTransform.applyToPoint(x, y) : uvTransform;
7234
7241
  const w = texture.width;
7235
7242
  const h = texture.height;
7236
7243
  for (let len = vertices.length, i = start; i < len; i += 2) {
@@ -7238,8 +7245,8 @@ class CanvasContext extends Path2D {
7238
7245
  const y = vertices[i + 1];
7239
7246
  let uvX;
7240
7247
  let uvY;
7241
- if (textureTransform) {
7242
- [uvX, uvY] = textureTransform?.applyToPoint(x, y);
7248
+ if (_uvTransform) {
7249
+ [uvX, uvY] = _uvTransform(x, y);
7243
7250
  } else {
7244
7251
  [uvX, uvY] = [x / w, y / h];
7245
7252
  }
@@ -7253,59 +7260,35 @@ class CanvasContext extends Path2D {
7253
7260
  }
7254
7261
  toBatchables() {
7255
7262
  const batchables = [];
7256
- let vertices = [];
7257
- let indices = [];
7258
- let uvs = [];
7259
- let texture;
7260
- const push = (draw) => {
7261
- batchables.push({
7262
- vertices,
7263
- indices,
7264
- uvs,
7265
- texture,
7266
- type: draw.type,
7267
- disableWrapMode: draw.disableWrapMode
7268
- });
7269
- vertices = [];
7270
- indices = [];
7271
- uvs = [];
7272
- texture = void 0;
7273
- };
7274
7263
  for (let len = this._draws.length, i = 0; i < len; i++) {
7275
- const draw = this._draws[i];
7276
- const prev = this._draws[i - 1];
7277
- if (vertices.length && prev && prev?.type !== draw.type) {
7278
- push(prev);
7279
- }
7280
- const oldTexture = texture;
7281
- if (!oldTexture) {
7282
- texture = draw.texture;
7283
- }
7284
- if (vertices.length && oldTexture !== draw.texture && !oldTexture?.is(draw.texture)) {
7285
- push(draw);
7286
- texture = draw.texture;
7287
- }
7288
- const start = vertices.length;
7289
- if (draw.type === "fill") {
7290
- draw.path.fillTriangulate({
7264
+ const current = this._draws[i];
7265
+ const vertices = [];
7266
+ const indices = [];
7267
+ const uvs = [];
7268
+ if (current.type === "fill") {
7269
+ current.path.fillTriangulate({
7291
7270
  vertices,
7292
7271
  indices
7293
7272
  });
7294
- this.buildUvs(start, vertices, uvs, draw.texture, draw.textureTransform);
7295
7273
  } else {
7296
- draw.path.strokeTriangulate({
7274
+ current.path.strokeTriangulate({
7297
7275
  vertices,
7298
7276
  indices,
7299
- lineStyle: draw.style,
7277
+ lineStyle: current.style,
7300
7278
  flipAlignment: false,
7301
7279
  closed: true
7302
7280
  });
7303
- this.buildUvs(start, vertices, uvs, draw.texture, draw.textureTransform);
7304
7281
  }
7305
- }
7306
- const last = this._draws[this._draws.length - 1];
7307
- if (last && vertices.length) {
7308
- push(last);
7282
+ this.buildUvs(0, vertices, uvs, current.texture, current.uvTransform);
7283
+ batchables.push({
7284
+ vertices,
7285
+ indices,
7286
+ uvs,
7287
+ texture: current.texture,
7288
+ type: current.type,
7289
+ disableWrapMode: current.disableWrapMode,
7290
+ vertTransform: current.vertTransform
7291
+ });
7309
7292
  }
7310
7293
  return batchables;
7311
7294
  }
@@ -7384,11 +7367,6 @@ let CanvasItem = class extends TimelineNode {
7384
7367
  requestRelayout() {
7385
7368
  this._relayouting = true;
7386
7369
  this.requestUpdate();
7387
- this.forEachChild((node) => {
7388
- if (node instanceof CanvasItem) {
7389
- node.requestRelayout();
7390
- }
7391
- });
7392
7370
  }
7393
7371
  requestRepaint() {
7394
7372
  this._repainting = true;
@@ -9018,7 +8996,7 @@ class BaseElement2DFill extends CoreObject {
9018
8996
  _getDrawOptions() {
9019
8997
  let disableWrapMode = false;
9020
8998
  const { width, height } = this.parent.size;
9021
- const textureTransform = new Transform2D().scale(1 / width, 1 / height);
8999
+ const uvTransform = new Transform2D().scale(1 / width, 1 / height);
9022
9000
  if (this.cropRect) {
9023
9001
  const {
9024
9002
  left = 0,
@@ -9026,7 +9004,7 @@ class BaseElement2DFill extends CoreObject {
9026
9004
  right = 0,
9027
9005
  bottom = 0
9028
9006
  } = this.cropRect;
9029
- textureTransform.scale(
9007
+ uvTransform.scale(
9030
9008
  Math.abs(1 - (left + right)),
9031
9009
  Math.abs(1 - (top + bottom))
9032
9010
  ).translate(left, top);
@@ -9041,24 +9019,26 @@ class BaseElement2DFill extends CoreObject {
9041
9019
  // flip, TODO
9042
9020
  // alignment, TODO
9043
9021
  } = this.tile;
9044
- textureTransform.translate(-translateX / width, -translateY / height).scale(1 / scaleX, 1 / scaleY);
9022
+ uvTransform.translate(-translateX / width, -translateY / height).scale(1 / scaleX, 1 / scaleY);
9045
9023
  disableWrapMode = true;
9046
9024
  } else if (this.stretchRect) {
9047
9025
  const { left = 0, top = 0, right = 0, bottom = 0 } = this.stretchRect;
9048
- textureTransform.scale(
9026
+ uvTransform.scale(
9049
9027
  Math.abs(1 - (-left + -right)),
9050
9028
  Math.abs(1 - (-top + -bottom))
9051
9029
  ).translate(-left, -top);
9052
9030
  disableWrapMode = true;
9053
9031
  }
9054
- return { disableWrapMode, textureTransform };
9032
+ return { disableWrapMode, uvTransform };
9055
9033
  }
9056
9034
  draw() {
9057
9035
  const ctx = this.parent.context;
9058
- const { textureTransform, disableWrapMode } = this._getDrawOptions();
9059
- ctx.textureTransform = textureTransform;
9036
+ const { uvTransform, disableWrapMode } = this._getDrawOptions();
9037
+ ctx.uvTransform = uvTransform;
9060
9038
  ctx.fillStyle = this._texture ?? this.color;
9061
- ctx.fill({ disableWrapMode });
9039
+ ctx.fill({
9040
+ disableWrapMode
9041
+ });
9062
9042
  }
9063
9043
  }
9064
9044
  __decorateClass$u([
@@ -9158,14 +9138,14 @@ class BaseElement2DOutline extends BaseElement2DFill {
9158
9138
  }
9159
9139
  canDraw() {
9160
9140
  return Boolean(
9161
- this.width || super.canDraw()
9141
+ this.width || this.color || super.canDraw()
9162
9142
  );
9163
9143
  }
9164
9144
  draw() {
9165
9145
  const ctx = this.parent.context;
9166
- const { textureTransform, disableWrapMode } = this._getDrawOptions();
9146
+ const { uvTransform, disableWrapMode } = this._getDrawOptions();
9167
9147
  ctx.lineWidth = this.width || 1;
9168
- ctx.textureTransform = textureTransform;
9148
+ ctx.uvTransform = uvTransform;
9169
9149
  ctx.strokeStyle = this._texture ?? this.color;
9170
9150
  ctx.stroke({ disableWrapMode });
9171
9151
  }
@@ -9405,13 +9385,6 @@ class BaseElement2DText extends CoreObject {
9405
9385
  }
9406
9386
  updateMeasure() {
9407
9387
  this.measureResult = this.measure();
9408
- const textWidth = this.measureResult.boundingBox.width;
9409
- const textHeight = this.measureResult.boundingBox.height;
9410
- const { left, top, width, height = textHeight } = this.parent.style;
9411
- this.parent.position.x = left + Math.min(0, ((width || textWidth) - textWidth) / 2);
9412
- this.parent.position.y = top + Math.min(0, ((height || textHeight) - textHeight) / 2);
9413
- this.parent.size.width = textWidth;
9414
- this.parent.size.height = textHeight;
9415
9388
  return this;
9416
9389
  }
9417
9390
  canDraw() {
@@ -9420,15 +9393,24 @@ class BaseElement2DText extends CoreObject {
9420
9393
  );
9421
9394
  }
9422
9395
  draw() {
9423
- const ctx = this.parent.context;
9424
9396
  this.baseText.render({
9425
9397
  pixelRatio: this.texture.pixelRatio,
9426
9398
  view: this.texture.source
9427
9399
  });
9428
9400
  this.texture.requestUpload();
9429
- const { width, height } = this.parent.size;
9401
+ const textWidth = this.measureResult?.boundingBox.width ?? this.parent.size.width;
9402
+ const textHeight = this.measureResult?.boundingBox.height ?? this.parent.size.height;
9403
+ const ctx = this.parent.context;
9430
9404
  ctx.fillStyle = this.texture;
9431
- ctx.textureTransform = new Transform2D().scale(1 / width, 1 / height);
9405
+ ctx.uvTransform = new Transform2D().scale(1 / textWidth, 1 / textHeight);
9406
+ ctx.vertTransform = () => {
9407
+ const parent = this.parent;
9408
+ const origin = parent.getTransformOrigin();
9409
+ return new Transform2D().translate(-origin.x, -origin.y).scale(
9410
+ parent.globalScale.x > 0 ? 1 : -1,
9411
+ parent.globalScale.y > 0 ? 1 : -1
9412
+ ).translate(origin.x, origin.y);
9413
+ };
9432
9414
  ctx.fill();
9433
9415
  }
9434
9416
  }
@@ -9469,8 +9451,19 @@ let Node2D = class extends CanvasItem {
9469
9451
  super();
9470
9452
  this.setProperties(properties).append(nodes);
9471
9453
  }
9454
+ getTransformOrigin() {
9455
+ return new Vector2(0, 0);
9456
+ }
9457
+ getTransform(cb) {
9458
+ const origin = this.getTransformOrigin();
9459
+ const transform = new Transform2D();
9460
+ transform.translate(-origin.x, -origin.y).scale(this.scale.x, this.scale.y).skew(this.skew.x, this.skew.y).rotate(this.rotation);
9461
+ cb?.(transform);
9462
+ transform.translate(this.position.x, this.position.y).translate(origin.x, origin.y);
9463
+ return transform;
9464
+ }
9472
9465
  _updateTransform() {
9473
- this.transform.identity().scale(this.scale.x, this.scale.y).skew(this.skew.x, this.skew.y).rotate(this.rotation).translate(this.position.x, this.position.y);
9466
+ this.transform.copy(this.getTransform());
9474
9467
  }
9475
9468
  _updateGlobalTransform() {
9476
9469
  const parent = this.getParent();
@@ -9497,8 +9490,17 @@ let Node2D = class extends CanvasItem {
9497
9490
  this.globalSkew.y = Math.atan2(b, d) - this.globalRotation;
9498
9491
  this.requestRelayout();
9499
9492
  }
9500
- _transformVertices(vertices) {
9501
- const [a, c, tx, b, d, ty] = this.globalTransform.toArray();
9493
+ _transformVertices(vertices, vertTransform) {
9494
+ let a, c, tx, b, d, ty;
9495
+ if (vertTransform) {
9496
+ const globalTransform = this.globalTransform.clone();
9497
+ globalTransform.multiply(
9498
+ typeof vertTransform === "function" ? vertTransform?.() : vertTransform
9499
+ );
9500
+ [a, c, tx, b, d, ty] = globalTransform.toArray();
9501
+ } else {
9502
+ [a, c, tx, b, d, ty] = this.globalTransform.toArray();
9503
+ }
9502
9504
  const newVertices = vertices.slice();
9503
9505
  for (let len = vertices.length, i = 0; i < len; i += 2) {
9504
9506
  const x = vertices[i];
@@ -9514,7 +9516,7 @@ let Node2D = class extends CanvasItem {
9514
9516
  return super._relayout(batchables).map((batchable) => {
9515
9517
  return {
9516
9518
  ...batchable,
9517
- vertices: this._transformVertices(batchable.vertices)
9519
+ vertices: this._transformVertices(batchable.vertices, batchable.vertTransform)
9518
9520
  };
9519
9521
  });
9520
9522
  }
@@ -9721,14 +9723,17 @@ let BaseElement2D = class extends Node2D {
9721
9723
  }
9722
9724
  }
9723
9725
  }
9724
- _updateTransform() {
9726
+ getTransformOrigin() {
9725
9727
  const { width, height } = this.size;
9726
9728
  const [originX, originY] = parseCSSTransformOrigin(this.style.transformOrigin);
9727
- const offsetX = originX * width;
9728
- const offsetY = originY * height;
9729
- this.transform.identity().translate(-offsetX, -offsetY).scale(this.scale.x, this.scale.y).skew(this.skew.x, this.skew.y).rotate(this.rotation);
9730
- parseCSSTransform(this.style.transform ?? "", width, height, this.transform);
9731
- this.transform.translate(this.position.x, this.position.y).translate(offsetX, offsetY);
9729
+ return new Vector2(originX * width, originY * height);
9730
+ }
9731
+ getTransform(cb) {
9732
+ const { width, height } = this.size;
9733
+ return super.getTransform((transform) => {
9734
+ parseCSSTransform(this.style.transform ?? "", width, height, transform);
9735
+ cb?.(transform);
9736
+ });
9732
9737
  }
9733
9738
  _updateGlobalTransform() {
9734
9739
  super._updateGlobalTransform();
@@ -10520,7 +10525,7 @@ let Image2D = class extends Element2D {
10520
10525
  const sy = 1 / h;
10521
10526
  const tx = left * width * sx;
10522
10527
  const ty = top * height * sy;
10523
- this.context.textureTransform = new Transform2D().scale(sx, sy).translate(tx, ty);
10528
+ this.context.uvTransform = new Transform2D().scale(sx, sy).translate(tx, ty);
10524
10529
  this.shape.draw();
10525
10530
  this.context.fill();
10526
10531
  }
@@ -10560,7 +10565,7 @@ class TextureRect2D extends Element2D {
10560
10565
  if (this.texture?.valid) {
10561
10566
  const { width, height } = this.size;
10562
10567
  this.context.fillStyle = this.texture;
10563
- this.context.textureTransform = new Transform2D().scale(
10568
+ this.context.uvTransform = new Transform2D().scale(
10564
10569
  1 / width,
10565
10570
  1 / height
10566
10571
  );
@@ -10779,15 +10784,10 @@ let Text2D = class extends TextureRect2D {
10779
10784
  }
10780
10785
  _drawContent() {
10781
10786
  if (!this.split) {
10782
- const onText2DRender = this.children?.find((child) => "onText2DRender" in child)?.onText2DRender;
10783
- if (onText2DRender) {
10784
- onText2DRender();
10785
- } else {
10786
- this.base.render({
10787
- pixelRatio: this.texture.pixelRatio,
10788
- view: this.texture.source
10789
- });
10790
- }
10787
+ this.base.render({
10788
+ pixelRatio: this.texture.pixelRatio,
10789
+ view: this.texture.source
10790
+ });
10791
10791
  this.texture.requestUpload();
10792
10792
  super._drawContent();
10793
10793
  }
@@ -12475,7 +12475,7 @@ let AudioWaveform = class extends Element2D {
12475
12475
  const src = this._src;
12476
12476
  if (src?.valid) {
12477
12477
  this.context.fillStyle = src;
12478
- this.context.textureTransform = new Transform2D().scale(
12478
+ this.context.uvTransform = new Transform2D().scale(
12479
12479
  1 / this.style.width,
12480
12480
  1 / this.style.height
12481
12481
  );
@@ -12749,7 +12749,7 @@ let Ruler = class extends Control {
12749
12749
  const texture = this.texture;
12750
12750
  if (texture?.valid) {
12751
12751
  this.context.fillStyle = texture;
12752
- this.context.textureTransform = new Transform2D().scale(
12752
+ this.context.uvTransform = new Transform2D().scale(
12753
12753
  1 / this.size.width,
12754
12754
  1 / this.size.height
12755
12755
  );
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "modern-canvas",
3
3
  "type": "module",
4
- "version": "0.4.50",
4
+ "version": "0.4.52",
5
5
  "packageManager": "pnpm@9.15.1",
6
6
  "description": "A JavaScript WebGL rendering engine.",
7
7
  "author": "wxm",
@@ -71,17 +71,17 @@
71
71
  "earcut": "^3.0.1",
72
72
  "modern-font": "^0.4.1",
73
73
  "modern-idoc": "^0.6.9",
74
- "modern-path2d": "^1.3.2",
74
+ "modern-path2d": "^1.3.3",
75
75
  "modern-text": "^1.4.2",
76
76
  "yoga-layout": "^3.2.1"
77
77
  },
78
78
  "devDependencies": {
79
79
  "@antfu/eslint-config": "^4.13.2",
80
80
  "@types/earcut": "^3.0.0",
81
- "@types/node": "^22.15.23",
81
+ "@types/node": "^22.15.29",
82
82
  "bumpp": "^10.1.1",
83
83
  "conventional-changelog-cli": "^5.0.0",
84
- "eslint": "^9.27.0",
84
+ "eslint": "^9.28.0",
85
85
  "lint-staged": "^16.1.0",
86
86
  "lottie-web": "^5.13.0",
87
87
  "modern-gif": "^2.0.4",
@@ -89,7 +89,7 @@
89
89
  "typescript": "^5.8.3",
90
90
  "unbuild": "^3.5.0",
91
91
  "vite": "^6.3.5",
92
- "vitest": "^3.1.4"
92
+ "vitest": "^3.2.0"
93
93
  },
94
94
  "simple-git-hooks": {
95
95
  "pre-commit": "pnpm lint-staged"