modern-canvas 0.8.5 → 0.8.6

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.cjs CHANGED
@@ -5126,21 +5126,26 @@ class GradientTexture extends Texture2D {
5126
5126
  if (!ctx) {
5127
5127
  throw new Error("Failed to parse linear gradient, get canvas context is null.");
5128
5128
  }
5129
- let { angle = 0, stops } = linearGradient;
5130
- angle -= Math.PI / 2;
5131
- const halfWidth = width / 2;
5132
- const halfHeight = height / 2;
5133
- const length = Math.sqrt(width * width + height * height) / 2;
5134
- const x0 = halfWidth + length * Math.cos(angle + Math.PI);
5135
- const y0 = halfHeight + length * Math.sin(angle + Math.PI);
5136
- const x1 = halfWidth + length * Math.cos(angle);
5137
- const y1 = halfHeight + length * Math.sin(angle);
5129
+ const { angle = 0, stops } = linearGradient;
5130
+ const w = width;
5131
+ const h = height;
5132
+ const cx = w / 2;
5133
+ const cy = h / 2;
5134
+ const canAng = angle * Math.PI / 180;
5135
+ const hypt = cy / Math.cos(canAng);
5136
+ const fromTopRight = cx - Math.sqrt(hypt * hypt - cy * cy);
5137
+ const diag = Math.sin(canAng) * fromTopRight;
5138
+ const len = hypt + diag;
5139
+ const x0 = cx + Math.cos(-Math.PI / 2 + canAng) * len;
5140
+ const y0 = cy + Math.sin(-Math.PI / 2 + canAng) * len;
5141
+ const x1 = cx + Math.cos(Math.PI / 2 + canAng) * len;
5142
+ const y1 = cy + Math.sin(Math.PI / 2 + canAng) * len;
5138
5143
  const gradient = ctx.createLinearGradient(x0, y0, x1, y1);
5139
5144
  stops.forEach((stop) => {
5140
5145
  gradient.addColorStop(stop.offset, stop.color);
5141
5146
  });
5142
5147
  ctx.fillStyle = gradient;
5143
- ctx.fillRect(0, 0, canvas.width, canvas.height);
5148
+ ctx.fillRect(0, 0, w, h);
5144
5149
  const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
5145
5150
  return {
5146
5151
  width: imageData.width,
@@ -9357,21 +9362,21 @@ exports.ZoomBlurEffect = __decorateClass$t([
9357
9362
  customNode("ZoomBlurEffect")
9358
9363
  ], exports.ZoomBlurEffect);
9359
9364
 
9360
- function getDrawOptions(fill, size) {
9365
+ function getDrawOptions(fill, box) {
9361
9366
  let disableWrapMode = false;
9362
- const { width, height } = size;
9363
- const uvTransform = new Transform2D().scale(1 / width, 1 / height);
9367
+ const { left = 0, top = 0, width, height } = box;
9368
+ const uvTransform = new Transform2D().translate(-left, -top).scale(1 / width, 1 / height);
9364
9369
  if (fill.cropRect) {
9365
9370
  const {
9366
- left = 0,
9367
- top = 0,
9371
+ left: left2 = 0,
9372
+ top: top2 = 0,
9368
9373
  right = 0,
9369
9374
  bottom = 0
9370
9375
  } = fill.cropRect;
9371
9376
  uvTransform.scale(
9372
- Math.abs(1 - (left + right)),
9373
- Math.abs(1 - (top + bottom))
9374
- ).translate(left, top);
9377
+ Math.abs(1 - (left2 + right)),
9378
+ Math.abs(1 - (top2 + bottom))
9379
+ ).translate(left2, top2);
9375
9380
  disableWrapMode = true;
9376
9381
  }
9377
9382
  if (fill.tile) {
@@ -9386,11 +9391,16 @@ function getDrawOptions(fill, size) {
9386
9391
  uvTransform.translate(-translateX / width, -translateY / height).scale(1 / scaleX, 1 / scaleY);
9387
9392
  disableWrapMode = true;
9388
9393
  } else if (fill.stretchRect) {
9389
- const { left = 0, top = 0, right = 0, bottom = 0 } = fill.stretchRect;
9394
+ const {
9395
+ left: left2 = 0,
9396
+ top: top2 = 0,
9397
+ right = 0,
9398
+ bottom = 0
9399
+ } = fill.stretchRect;
9390
9400
  uvTransform.scale(
9391
- Math.abs(1 - (-left + -right)),
9392
- Math.abs(1 - (-top + -bottom))
9393
- ).translate(-left, -top);
9401
+ Math.abs(1 - (-left2 + -right)),
9402
+ Math.abs(1 - (-top2 + -bottom))
9403
+ ).translate(-left2, -top2);
9394
9404
  disableWrapMode = true;
9395
9405
  }
9396
9406
  return { disableWrapMode, uvTransform };
@@ -9466,7 +9476,10 @@ class BaseElement2DFill extends CoreObject {
9466
9476
  const ctx = this.parent.context;
9467
9477
  const { uvTransform, disableWrapMode } = getDrawOptions(
9468
9478
  this,
9469
- this.parent.size
9479
+ {
9480
+ width: this.parent.size.width,
9481
+ height: this.parent.size.height
9482
+ }
9470
9483
  );
9471
9484
  ctx.uvTransform = uvTransform;
9472
9485
  ctx.fillStyle = this._texture ?? this.color;
@@ -9601,7 +9614,10 @@ class BaseElement2DOutline extends BaseElement2DFill {
9601
9614
  const ctx = this.parent.context;
9602
9615
  const { uvTransform, disableWrapMode } = getDrawOptions(
9603
9616
  this,
9604
- this.parent.size
9617
+ {
9618
+ width: this.parent.size.width,
9619
+ height: this.parent.size.height
9620
+ }
9605
9621
  );
9606
9622
  ctx.lineWidth = this.width || 1;
9607
9623
  ctx.uvTransform = uvTransform;
@@ -9825,7 +9841,7 @@ class BaseElement2DText extends CoreObject {
9825
9841
  }
9826
9842
  base = new modernText.Text();
9827
9843
  measureResult;
9828
- _textures = [];
9844
+ _textureMap = /* @__PURE__ */ new Map();
9829
9845
  setProperties(properties) {
9830
9846
  return super.setProperties(
9831
9847
  modernIdoc.isNone(properties) ? void 0 : modernIdoc.normalizeText(properties)
@@ -9835,30 +9851,72 @@ class BaseElement2DText extends CoreObject {
9835
9851
  super._updateProperty(key, value, oldValue, declaration);
9836
9852
  switch (key) {
9837
9853
  case "enabled":
9838
- case "content":
9839
9854
  case "effects":
9840
9855
  case "measureDom":
9841
9856
  case "fonts":
9842
9857
  this.parent.requestRedraw();
9843
9858
  break;
9844
9859
  case "fill":
9845
- this._updateTexture(0, value);
9846
- break;
9847
9860
  case "outline":
9848
- this._updateTexture(1, value);
9861
+ case "content":
9862
+ this._updateTextureMap();
9849
9863
  break;
9850
9864
  }
9851
9865
  }
9852
- async _updateTexture(index, fill) {
9853
- this._textures[index] = await this._loadTexture(fill);
9866
+ _update() {
9867
+ this.base.style = {
9868
+ justifyContent: "center",
9869
+ alignItems: "center",
9870
+ textAlign: "center",
9871
+ ...this.parent.style.toJSON()
9872
+ };
9873
+ this.base.update();
9874
+ }
9875
+ _updateTextureMap() {
9876
+ this._update();
9877
+ this._textureMap.clear();
9878
+ const pGlyphBoxs = [];
9879
+ this.base.paragraphs.forEach((p, pIndex) => {
9880
+ const fGlyphBoxs = [];
9881
+ p.fragments.forEach((f, fIndex) => {
9882
+ if (f.characters.length) {
9883
+ const fGlyphBox = modernPath2d.BoundingBox.from(
9884
+ ...f.characters.map((c) => c.compatibleGlyphBox)
9885
+ );
9886
+ this._updateTexture(`${pIndex}.${fIndex}.fill`, f.fill, fGlyphBox);
9887
+ this._updateTexture(`${pIndex}.${fIndex}.outline`, f.outline, fGlyphBox);
9888
+ fGlyphBoxs.push(fGlyphBox);
9889
+ }
9890
+ });
9891
+ if (fGlyphBoxs.length) {
9892
+ const pGlyphBox = modernPath2d.BoundingBox.from(...fGlyphBoxs);
9893
+ this._updateTexture(`${pIndex}.fill`, p.fill, pGlyphBox);
9894
+ this._updateTexture(`${pIndex}.outline`, p.outline, pGlyphBox);
9895
+ pGlyphBoxs.push(pGlyphBox);
9896
+ }
9897
+ });
9898
+ if (pGlyphBoxs.length) {
9899
+ const glyphBox = modernPath2d.BoundingBox.from(...pGlyphBoxs);
9900
+ this._updateTexture("fill", this.fill, glyphBox);
9901
+ this._updateTexture("outline", this.outline, glyphBox);
9902
+ }
9854
9903
  this.parent.requestRedraw();
9855
9904
  }
9856
- async _loadTexture(fill) {
9905
+ async _updateTexture(key, fill, box) {
9906
+ if (fill && Object.keys(fill).length > 0) {
9907
+ this._textureMap.set(key, {
9908
+ texture: await this._loadTexture(fill, box),
9909
+ box
9910
+ });
9911
+ this.parent.requestRedraw();
9912
+ }
9913
+ }
9914
+ async _loadTexture(fill, box) {
9857
9915
  if (fill.linearGradient || fill.radialGradient) {
9858
9916
  return new GradientTexture(
9859
9917
  fill.linearGradient ?? fill.radialGradient,
9860
- this.parent.size.width,
9861
- this.parent.size.height
9918
+ box.width,
9919
+ box.height
9862
9920
  );
9863
9921
  } else if (!modernIdoc.isNone(fill.image)) {
9864
9922
  this.parent.tree?.log(`load image ${fill.image}`);
@@ -9877,7 +9935,6 @@ class BaseElement2DText extends CoreObject {
9877
9935
  textAlign: "center",
9878
9936
  ...this.parent.style.toJSON()
9879
9937
  };
9880
- this.base.requestUpdate();
9881
9938
  return this.base.measure();
9882
9939
  }
9883
9940
  updateMeasure() {
@@ -9900,48 +9957,67 @@ class BaseElement2DText extends CoreObject {
9900
9957
  }
9901
9958
  draw() {
9902
9959
  const ctx = this.parent.context;
9903
- this.base.update();
9960
+ this._update();
9904
9961
  this.base.pathSets.forEach((pathSet) => {
9905
9962
  pathSet.paths.forEach((path) => {
9906
- if (path.style.stroke && !modernIdoc.isNone(path.style.stroke)) {
9907
- if (typeof path.style.stroke === "object") {
9908
- const outline = path.style.stroke;
9909
- if (outline.enabled !== false && (this._textures[0] || outline.color) && (outline.width === void 0 || outline.width)) {
9910
- const { uvTransform, disableWrapMode } = getDrawOptions(outline, this.parent.size);
9963
+ const meta = path.getMeta();
9964
+ if (meta instanceof modernText.Character) {
9965
+ const fIndex = meta.parent.index;
9966
+ const pIndex = meta.parent.parent.index;
9967
+ if (path.style.fill && !modernIdoc.isNone(path.style.fill)) {
9968
+ if (typeof path.style.fill === "object") {
9969
+ const fill = path.style.fill;
9970
+ const texture = this._textureMap.get(`${pIndex}.${fIndex}.fill`) ?? this._textureMap.get(`${pIndex}.fill`) ?? this._textureMap.get("fill");
9971
+ if (fill.enabled !== false && (texture || fill.color)) {
9972
+ const { uvTransform, disableWrapMode } = getDrawOptions(
9973
+ fill,
9974
+ texture?.box ?? {
9975
+ width: this.parent.size.width,
9976
+ height: this.parent.size.height
9977
+ }
9978
+ );
9979
+ ctx.addPath(path);
9980
+ ctx.style = { ...path.style };
9981
+ ctx.uvTransform = uvTransform;
9982
+ ctx.fillStyle = texture?.texture ?? fill.color;
9983
+ ctx.vertTransform = this._getVertTransform();
9984
+ ctx.fill({ disableWrapMode });
9985
+ }
9986
+ } else {
9911
9987
  ctx.addPath(path);
9912
9988
  ctx.style = { ...path.style };
9913
- ctx.lineWidth = outline.width || 1;
9914
- ctx.uvTransform = uvTransform;
9915
- ctx.strokeStyle = this._textures[0] ?? outline.color;
9916
- ctx.lineCap = outline.lineCap;
9917
- ctx.lineJoin = outline.lineJoin;
9918
9989
  ctx.vertTransform = this._getVertTransform();
9919
- ctx.stroke({ disableWrapMode });
9990
+ ctx.fill();
9920
9991
  }
9921
- } else {
9922
- ctx.addPath(path);
9923
- ctx.style = { ...path.style };
9924
- ctx.vertTransform = this._getVertTransform();
9925
- ctx.stroke();
9926
9992
  }
9927
- }
9928
- if (path.style.fill && !modernIdoc.isNone(path.style.fill)) {
9929
- if (typeof path.style.fill === "object") {
9930
- const fill = path.style.fill;
9931
- if (fill.enabled !== false && (this._textures[1] || fill.color)) {
9932
- const { uvTransform, disableWrapMode } = getDrawOptions(fill, this.parent.size);
9993
+ if (path.style.stroke && !modernIdoc.isNone(path.style.stroke)) {
9994
+ if (typeof path.style.stroke === "object") {
9995
+ const outline = path.style.stroke;
9996
+ const texture = this._textureMap.get(`${pIndex}.${fIndex}.outline`) ?? this._textureMap.get(`${pIndex}.outline`) ?? this._textureMap.get("outline");
9997
+ if (outline.enabled !== false && (texture || outline.color) && (outline.width === void 0 || outline.width)) {
9998
+ const { uvTransform, disableWrapMode } = getDrawOptions(
9999
+ outline,
10000
+ texture?.box ?? {
10001
+ width: this.parent.size.width,
10002
+ height: this.parent.size.height
10003
+ }
10004
+ );
10005
+ ctx.addPath(path);
10006
+ ctx.style = { ...path.style };
10007
+ ctx.lineWidth = outline.width || 1;
10008
+ ctx.uvTransform = uvTransform;
10009
+ ctx.strokeStyle = texture?.texture ?? outline.color;
10010
+ ctx.lineCap = outline.lineCap;
10011
+ ctx.lineJoin = outline.lineJoin;
10012
+ ctx.vertTransform = this._getVertTransform();
10013
+ ctx.stroke({ disableWrapMode });
10014
+ }
10015
+ } else {
9933
10016
  ctx.addPath(path);
9934
10017
  ctx.style = { ...path.style };
9935
- ctx.uvTransform = uvTransform;
9936
- ctx.fillStyle = this._textures[1] ?? fill.color;
9937
10018
  ctx.vertTransform = this._getVertTransform();
9938
- ctx.fill({ disableWrapMode });
10019
+ ctx.stroke();
9939
10020
  }
9940
- } else {
9941
- ctx.addPath(path);
9942
- ctx.style = { ...path.style };
9943
- ctx.vertTransform = this._getVertTransform();
9944
- ctx.fill();
9945
10021
  }
9946
10022
  }
9947
10023
  });
package/dist/index.d.cts CHANGED
@@ -2094,12 +2094,17 @@ declare class BaseElement2DText extends CoreObject {
2094
2094
  fonts: Text['fonts'];
2095
2095
  readonly base: Text;
2096
2096
  measureResult?: MeasureResult;
2097
- protected _textures: (Texture2D | undefined)[];
2097
+ protected _textureMap: Map<string, {
2098
+ texture: Texture2D | undefined;
2099
+ box: any;
2100
+ }>;
2098
2101
  constructor(parent: BaseElement2D);
2099
2102
  setProperties(properties?: Text$1): this;
2100
2103
  protected _updateProperty(key: string, value: any, oldValue: any, declaration?: PropertyDeclaration): void;
2101
- protected _updateTexture(index: number, fill: NormalizedFill): Promise<void>;
2102
- protected _loadTexture(fill: NormalizedFill): Promise<Texture2D | undefined>;
2104
+ protected _update(): void;
2105
+ protected _updateTextureMap(): void;
2106
+ protected _updateTexture(key: string, fill: NormalizedFill | undefined, box: any): Promise<void>;
2107
+ protected _loadTexture(fill: NormalizedFill, box: any): Promise<Texture2D | undefined>;
2103
2108
  setContent(content: TextContent): void;
2104
2109
  measure(): MeasureResult;
2105
2110
  updateMeasure(): this;
package/dist/index.d.mts CHANGED
@@ -2094,12 +2094,17 @@ declare class BaseElement2DText extends CoreObject {
2094
2094
  fonts: Text['fonts'];
2095
2095
  readonly base: Text;
2096
2096
  measureResult?: MeasureResult;
2097
- protected _textures: (Texture2D | undefined)[];
2097
+ protected _textureMap: Map<string, {
2098
+ texture: Texture2D | undefined;
2099
+ box: any;
2100
+ }>;
2098
2101
  constructor(parent: BaseElement2D);
2099
2102
  setProperties(properties?: Text$1): this;
2100
2103
  protected _updateProperty(key: string, value: any, oldValue: any, declaration?: PropertyDeclaration): void;
2101
- protected _updateTexture(index: number, fill: NormalizedFill): Promise<void>;
2102
- protected _loadTexture(fill: NormalizedFill): Promise<Texture2D | undefined>;
2104
+ protected _update(): void;
2105
+ protected _updateTextureMap(): void;
2106
+ protected _updateTexture(key: string, fill: NormalizedFill | undefined, box: any): Promise<void>;
2107
+ protected _loadTexture(fill: NormalizedFill, box: any): Promise<Texture2D | undefined>;
2103
2108
  setContent(content: TextContent): void;
2104
2109
  measure(): MeasureResult;
2105
2110
  updateMeasure(): this;
package/dist/index.d.ts CHANGED
@@ -2094,12 +2094,17 @@ declare class BaseElement2DText extends CoreObject {
2094
2094
  fonts: Text['fonts'];
2095
2095
  readonly base: Text;
2096
2096
  measureResult?: MeasureResult;
2097
- protected _textures: (Texture2D | undefined)[];
2097
+ protected _textureMap: Map<string, {
2098
+ texture: Texture2D | undefined;
2099
+ box: any;
2100
+ }>;
2098
2101
  constructor(parent: BaseElement2D);
2099
2102
  setProperties(properties?: Text$1): this;
2100
2103
  protected _updateProperty(key: string, value: any, oldValue: any, declaration?: PropertyDeclaration): void;
2101
- protected _updateTexture(index: number, fill: NormalizedFill): Promise<void>;
2102
- protected _loadTexture(fill: NormalizedFill): Promise<Texture2D | undefined>;
2104
+ protected _update(): void;
2105
+ protected _updateTextureMap(): void;
2106
+ protected _updateTexture(key: string, fill: NormalizedFill | undefined, box: any): Promise<void>;
2107
+ protected _loadTexture(fill: NormalizedFill, box: any): Promise<Texture2D | undefined>;
2103
2108
  setContent(content: TextContent): void;
2104
2109
  measure(): MeasureResult;
2105
2110
  updateMeasure(): this;