modern-canvas 0.8.5 → 0.8.7

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