modern-canvas 0.4.23 → 0.4.25

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
@@ -1,6 +1,6 @@
1
1
  import { colord, extend } from 'colord';
2
2
  import namesPlugin from 'colord/plugins/names';
3
- import { Path2D, Path2DSet, svgToDOM, svgToPath2DSet, Matrix3 as Matrix3$1, svgPathCommandsAddToPath2D } from 'modern-path2d';
3
+ import { Path2D, Path2DSet, svgToDOM, svgToPath2DSet, Matrix3 as Matrix3$1 } from 'modern-path2d';
4
4
  import { getDefaultStyle } from 'modern-idoc';
5
5
  import { Text, textDefaultStyle } from 'modern-text';
6
6
  import { loadYoga, BoxSizing, PositionType, Edge, Overflow, Gutter, Justify, Wrap, FlexDirection, Display, Direction, Align } from 'yoga-layout/load';
@@ -7075,7 +7075,7 @@ class CanvasContext extends Path2D {
7075
7075
  miterLimit;
7076
7076
  _defaultStyle = Texture2D.EMPTY;
7077
7077
  _draws = [];
7078
- stroke() {
7078
+ stroke(options) {
7079
7079
  let texture = this._defaultStyle;
7080
7080
  if (this.strokeStyle) {
7081
7081
  if (this.strokeStyle instanceof Texture2D) {
@@ -7086,6 +7086,7 @@ class CanvasContext extends Path2D {
7086
7086
  }
7087
7087
  if (this.curves.length) {
7088
7088
  this._draws.push({
7089
+ ...options,
7089
7090
  type: "stroke",
7090
7091
  path: new Path2D(this),
7091
7092
  texture,
@@ -7107,7 +7108,7 @@ class CanvasContext extends Path2D {
7107
7108
  strokeRect(x, y, width, height) {
7108
7109
  this.rect(x, y, width, height).stroke();
7109
7110
  }
7110
- fill() {
7111
+ fill(options) {
7111
7112
  let texture = this._defaultStyle;
7112
7113
  if (this.fillStyle) {
7113
7114
  if (this.fillStyle instanceof Texture2D) {
@@ -7117,6 +7118,7 @@ class CanvasContext extends Path2D {
7117
7118
  }
7118
7119
  }
7119
7120
  this._draws.push({
7121
+ ...options,
7120
7122
  type: "fill",
7121
7123
  path: new Path2D(this),
7122
7124
  texture,
@@ -7176,13 +7178,14 @@ class CanvasContext extends Path2D {
7176
7178
  let indices = [];
7177
7179
  let uvs = [];
7178
7180
  let texture;
7179
- const push = (type) => {
7181
+ const push = (draw) => {
7180
7182
  batchables.push({
7181
- type,
7182
7183
  vertices,
7183
7184
  indices,
7184
7185
  uvs,
7185
- texture
7186
+ texture,
7187
+ type: draw.type,
7188
+ disableWrapMode: draw.disableWrapMode
7186
7189
  });
7187
7190
  vertices = [];
7188
7191
  indices = [];
@@ -7193,14 +7196,14 @@ class CanvasContext extends Path2D {
7193
7196
  const draw = this._draws[i];
7194
7197
  const prev = this._draws[i - 1];
7195
7198
  if (vertices.length && prev && prev?.type !== draw.type) {
7196
- push(prev.type);
7199
+ push(prev);
7197
7200
  }
7198
7201
  const oldTexture = texture;
7199
7202
  if (!oldTexture) {
7200
7203
  texture = draw.texture;
7201
7204
  }
7202
7205
  if (vertices.length && oldTexture !== draw.texture && !oldTexture?.is(draw.texture)) {
7203
- push(draw.type);
7206
+ push(draw);
7204
7207
  texture = draw.texture;
7205
7208
  }
7206
7209
  const start = vertices.length;
@@ -7223,7 +7226,7 @@ class CanvasContext extends Path2D {
7223
7226
  }
7224
7227
  const last = this._draws[this._draws.length - 1];
7225
7228
  if (last && vertices.length) {
7226
- push(last.type);
7229
+ push(last);
7227
7230
  }
7228
7231
  return batchables;
7229
7232
  }
@@ -7251,7 +7254,6 @@ let CanvasItem = class extends TimelineNode {
7251
7254
  return this._globalOpacity ?? 1;
7252
7255
  }
7253
7256
  _modulate = new Color(4294967295);
7254
- _backgroundImage;
7255
7257
  // Batch render
7256
7258
  context = new CanvasContext();
7257
7259
  _resetContext = true;
@@ -8912,13 +8914,40 @@ class BaseElement2DFill extends CoreObject {
8912
8914
  draw() {
8913
8915
  const ctx = this.parent.context;
8914
8916
  if (this._image) {
8917
+ const { width: imageWidth, height: imageHeight } = this._image;
8915
8918
  const { width, height } = this.parent.size;
8916
- ctx.textureTransform = new Transform2D().scale(1 / width, 1 / height);
8919
+ const transform = new Transform2D();
8920
+ if (this.tile) {
8921
+ const {
8922
+ translateX = 0,
8923
+ translateY = 0,
8924
+ scaleX = 1,
8925
+ scaleY = 1
8926
+ // flip, TODO
8927
+ // alignment, TODO
8928
+ } = this.tile;
8929
+ transform.scale(1 / imageWidth, 1 / imageHeight).scale(1 / scaleX, 1 / scaleY).translate(-translateX / imageWidth, -translateY / imageHeight);
8930
+ } else if (this.stretch) {
8931
+ const { left = 0, top = 0, right = 0, bottom = 0 } = this.stretch.rect ?? {};
8932
+ const w = Math.abs(1 + (-left + -right)) * width;
8933
+ const h = Math.abs(1 + (-top + -bottom)) * height;
8934
+ const scaleX = 1 / w;
8935
+ const scaleY = 1 / h;
8936
+ const translateX = -left * width * scaleX;
8937
+ const translateY = -top * height * scaleY;
8938
+ transform.scale(scaleX, scaleY).translate(translateX, translateY);
8939
+ } else {
8940
+ transform.scale(1 / width, 1 / height);
8941
+ }
8942
+ ctx.textureTransform = transform;
8917
8943
  ctx.fillStyle = this._image;
8944
+ ctx.fill({
8945
+ disableWrapMode: true
8946
+ });
8918
8947
  } else {
8919
8948
  ctx.fillStyle = this.color;
8949
+ ctx.fill();
8920
8950
  }
8921
- ctx.fill();
8922
8951
  }
8923
8952
  }
8924
8953
  __decorateClass$s([
@@ -8936,6 +8965,9 @@ __decorateClass$s([
8936
8965
  __decorateClass$s([
8937
8966
  property()
8938
8967
  ], BaseElement2DFill.prototype, "tile");
8968
+ __decorateClass$s([
8969
+ property()
8970
+ ], BaseElement2DFill.prototype, "stretch");
8939
8971
 
8940
8972
  var __defProp$k = Object.defineProperty;
8941
8973
  var __decorateClass$r = (decorators, target, key, kind) => {
@@ -8987,14 +9019,27 @@ class BaseElement2DGeometry extends CoreObject {
8987
9019
  });
8988
9020
  }
8989
9021
  draw() {
9022
+ if (this._path2DSet.paths.length) {
9023
+ const ctx = this.parent.context;
9024
+ const { width, height } = this.parent.size;
9025
+ this._path2DSet.paths.forEach((path) => {
9026
+ ctx.addPath(path.clone().applyTransform(new Matrix3$1().scale(width, height)));
9027
+ });
9028
+ } else {
9029
+ this.drawRect();
9030
+ }
9031
+ }
9032
+ drawRect() {
8990
9033
  const ctx = this.parent.context;
8991
9034
  const { width, height } = this.parent.size;
8992
- this._path2DSet.paths.forEach((path) => {
8993
- svgPathCommandsAddToPath2D(
8994
- path.clone().applyTransform(new Matrix3$1().scale(width, height)).toCommands(),
8995
- ctx
8996
- );
8997
- });
9035
+ const { borderRadius } = this.parent.style;
9036
+ if (width && height) {
9037
+ if (borderRadius) {
9038
+ ctx.roundRect(0, 0, width, height, borderRadius);
9039
+ } else {
9040
+ ctx.rect(0, 0, width, height);
9041
+ }
9042
+ }
8998
9043
  }
8999
9044
  }
9000
9045
  __decorateClass$r([
@@ -9007,7 +9052,7 @@ __decorateClass$r([
9007
9052
  property({ default: [0, 0, 1, 1] })
9008
9053
  ], BaseElement2DGeometry.prototype, "viewBox");
9009
9054
  __decorateClass$r([
9010
- property({ default: [{ data: "M0,0L0,1L1,1L1,0Z" }] })
9055
+ property({ default: [] })
9011
9056
  ], BaseElement2DGeometry.prototype, "data");
9012
9057
 
9013
9058
  var __defProp$j = Object.defineProperty;
@@ -9173,7 +9218,7 @@ class BaseElement2DText extends CoreObject {
9173
9218
  measureDom;
9174
9219
  fonts;
9175
9220
  texture = new CanvasTexture();
9176
- text = new Text();
9221
+ baseText = new Text();
9177
9222
  measureResult;
9178
9223
  _updateProperty(key, value, oldValue, declaration) {
9179
9224
  super._updateProperty(key, value, oldValue, declaration);
@@ -9188,16 +9233,21 @@ class BaseElement2DText extends CoreObject {
9188
9233
  }
9189
9234
  }
9190
9235
  _updateText() {
9191
- this.text.style = this.parent.style.toJSON();
9192
- this.text.content = this.content ?? "";
9193
- this.text.effects = this.effects;
9194
- this.text.fonts = this.fonts;
9195
- this.text.measureDom = this.measureDom;
9196
- this.text.requestUpdate();
9236
+ this.baseText.style = {
9237
+ justifyContent: "center",
9238
+ alignItems: "center",
9239
+ textAlign: "center",
9240
+ ...this.parent.style.toJSON()
9241
+ };
9242
+ this.baseText.content = this.content ?? "";
9243
+ this.baseText.effects = this.effects;
9244
+ this.baseText.fonts = this.fonts;
9245
+ this.baseText.measureDom = this.measureDom;
9246
+ this.baseText.requestUpdate();
9197
9247
  }
9198
9248
  measure() {
9199
9249
  this._updateText();
9200
- return this.text.measure();
9250
+ return this.baseText.measure();
9201
9251
  }
9202
9252
  updateMeasure() {
9203
9253
  this.measureResult = this.measure();
@@ -9217,7 +9267,7 @@ class BaseElement2DText extends CoreObject {
9217
9267
  }
9218
9268
  draw() {
9219
9269
  const ctx = this.parent.context;
9220
- this.text.render({
9270
+ this.baseText.render({
9221
9271
  pixelRatio: this.texture.pixelRatio,
9222
9272
  view: this.texture.source
9223
9273
  });
@@ -9447,12 +9497,6 @@ let BaseElement2D = class extends Node2D {
9447
9497
  this.requestRelayout();
9448
9498
  break;
9449
9499
  /** draw */
9450
- case "backgroundColor":
9451
- this._updateBackgroundColor();
9452
- break;
9453
- case "backgroundImage":
9454
- this._updateBackgroundImage();
9455
- break;
9456
9500
  case "opacity":
9457
9501
  this.opacity = this.style.opacity;
9458
9502
  break;
@@ -9468,6 +9512,24 @@ let BaseElement2D = class extends Node2D {
9468
9512
  case "borderRadius":
9469
9513
  this.requestRedraw();
9470
9514
  break;
9515
+ case "backgroundColor":
9516
+ this.fill.color = this.style.backgroundColor;
9517
+ break;
9518
+ case "backgroundImage":
9519
+ this.fill.image = this.style.backgroundImage;
9520
+ break;
9521
+ case "borderStyle":
9522
+ case "outlineStyle":
9523
+ this.outline.style = value;
9524
+ break;
9525
+ case "borderWidth":
9526
+ case "outlineWidth":
9527
+ this.outline.width = value;
9528
+ break;
9529
+ case "borderColor":
9530
+ case "outlineColor":
9531
+ this.outline.color = value;
9532
+ break;
9471
9533
  }
9472
9534
  }
9473
9535
  _updateMaskImage() {
@@ -9487,18 +9549,6 @@ let BaseElement2D = class extends Node2D {
9487
9549
  }
9488
9550
  }
9489
9551
  }
9490
- _updateBackgroundColor() {
9491
- const backgroundColor = this.style.getComputedBackgroundColor();
9492
- if (this._originalBatchables.length) {
9493
- this.requestRepaint();
9494
- } else if (backgroundColor.a > 0) {
9495
- this.requestRedraw();
9496
- }
9497
- }
9498
- async _updateBackgroundImage() {
9499
- this._backgroundImage = await this.style.loadBackgroundImage();
9500
- this.requestRedraw();
9501
- }
9502
9552
  _updateTransform() {
9503
9553
  const { width, height } = this.size;
9504
9554
  const [originX, originY] = parseCSSTransformOrigin(this.style.transformOrigin);
@@ -9558,7 +9608,6 @@ let BaseElement2D = class extends Node2D {
9558
9608
  }
9559
9609
  _draw() {
9560
9610
  super._draw();
9561
- let flag = false;
9562
9611
  if (this.text.canDraw()) {
9563
9612
  this.text.updateMeasure();
9564
9613
  }
@@ -9566,81 +9615,26 @@ let BaseElement2D = class extends Node2D {
9566
9615
  this._tree?.log(this.name, "draw fill");
9567
9616
  this.geometry.draw();
9568
9617
  this.fill.draw();
9569
- flag = true;
9570
9618
  }
9571
9619
  if (this.outline.canDraw()) {
9572
9620
  this._tree?.log(this.name, "draw outline");
9573
9621
  this.geometry.draw();
9574
9622
  this.outline.draw();
9575
- flag = true;
9576
9623
  }
9577
9624
  if (this.text.canDraw()) {
9578
9625
  this._tree?.log(this.name, "draw text");
9579
- this._drawBoundingRect();
9626
+ this.geometry.drawRect();
9580
9627
  this.text.draw();
9581
- flag = true;
9582
- }
9583
- if (!flag) {
9584
- this._drawBackground();
9585
- this._drawContent();
9586
- this._drawBorder();
9587
- this._drawOutline();
9588
- }
9589
- }
9590
- _drawBackground() {
9591
- const texture = this._backgroundImage;
9592
- if (texture?.valid) {
9593
- const { width, height } = this.size;
9594
- this.context.fillStyle = texture;
9595
- this.context.textureTransform = new Transform2D().scale(
9596
- 1 / width,
9597
- 1 / height
9598
- );
9599
- this._fillBoundingRect();
9600
9628
  }
9629
+ this._drawContent();
9601
9630
  }
9602
9631
  _drawContent() {
9603
- this._fillBoundingRect();
9604
- }
9605
- _drawBorder() {
9606
- if (this.style.borderWidth && this.style.borderStyle !== "none") {
9607
- this.context.lineWidth = this.style.borderWidth;
9608
- this.context.strokeStyle = this.style.borderColor;
9609
- this._strokeBoundingRect();
9610
- }
9611
- }
9612
- _drawOutline() {
9613
- if (this.style.outlineWidth && this.style.outlineColor !== "none") {
9614
- this.context.lineWidth = this.style.outlineWidth;
9615
- this.context.strokeStyle = this.style.outlineColor;
9616
- this._strokeBoundingRect();
9617
- }
9618
- }
9619
- _drawBoundingRect() {
9620
- const { borderRadius } = this.style;
9621
- const { width, height } = this.size;
9622
- if (width && height) {
9623
- if (borderRadius) {
9624
- this.context.roundRect(0, 0, width, height, borderRadius);
9625
- } else {
9626
- this.context.rect(0, 0, width, height);
9627
- }
9628
- }
9629
- }
9630
- _fillBoundingRect() {
9631
- this._drawBoundingRect();
9632
- this.context.fill();
9633
- }
9634
- _strokeBoundingRect() {
9635
- this._drawBoundingRect();
9636
- this.context.stroke();
9637
9632
  }
9638
9633
  _repaint(batchables) {
9639
9634
  const colorMatrix = parseCSSFilter(this.style.filter);
9640
9635
  return super._repaint(batchables).map((batchable) => {
9641
9636
  return {
9642
9637
  ...batchable,
9643
- backgroundColor: this.style.getComputedBackgroundColor().abgr,
9644
9638
  colorMatrix: colorMatrix.toMatrix4().toArray(true),
9645
9639
  colorMatrixOffset: colorMatrix.toVector4().toArray()
9646
9640
  };
@@ -9758,11 +9752,11 @@ let Element2D = class extends BaseElement2D {
9758
9752
  break;
9759
9753
  case "width":
9760
9754
  this.size.width = Number(value);
9761
- this.requestRelayout();
9755
+ this.requestRedraw();
9762
9756
  break;
9763
9757
  case "height":
9764
9758
  this.size.height = Number(value);
9765
- this.requestRelayout();
9759
+ this.requestRedraw();
9766
9760
  break;
9767
9761
  }
9768
9762
  }
@@ -10343,7 +10337,8 @@ let Image2D = class extends Element2D {
10343
10337
  const tx = left * width * sx;
10344
10338
  const ty = top * height * sy;
10345
10339
  this.context.textureTransform = new Transform2D().scale(sx, sy).translate(tx, ty);
10346
- super._drawContent();
10340
+ this.geometry.drawRect();
10341
+ this.context.fill();
10347
10342
  }
10348
10343
  }
10349
10344
  _repaint(batchables) {
@@ -10385,7 +10380,8 @@ class TextureRect2D extends Element2D {
10385
10380
  1 / width,
10386
10381
  1 / height
10387
10382
  );
10388
- super._drawContent();
10383
+ this.geometry.drawRect();
10384
+ this.context.fill();
10389
10385
  }
10390
10386
  }
10391
10387
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "modern-canvas",
3
3
  "type": "module",
4
- "version": "0.4.23",
4
+ "version": "0.4.25",
5
5
  "packageManager": "pnpm@9.15.1",
6
6
  "description": "A JavaScript WebGL rendering engine.",
7
7
  "author": "wxm",
@@ -70,8 +70,8 @@
70
70
  "colord": "^2.9.3",
71
71
  "earcut": "^3.0.1",
72
72
  "modern-font": "^0.4.0",
73
- "modern-idoc": "^0.2.12",
74
- "modern-path2d": "^1.2.11",
73
+ "modern-idoc": "^0.2.13",
74
+ "modern-path2d": "^1.2.16",
75
75
  "modern-text": "^1.3.1",
76
76
  "yoga-layout": "^3.2.1"
77
77
  },