modern-canvas 0.8.4 → 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 +151 -69
- package/dist/index.d.cts +9 -4
- package/dist/index.d.mts +9 -4
- package/dist/index.d.ts +9 -4
- package/dist/index.js +38 -38
- package/dist/index.mjs +153 -71
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { defineProperty, EventEmitter, getDeclarations, parseColor, property, RawWeakMap as RawWeakMap$1, isGradient, isColorFillObject, clearUndef, idGenerator, normalizeFill, isNone, normalizeBackground, normalizeForeground, normalizeOutline, normalizeShadow, normalizeShape, getDefaultStyle, normalizeText, normalizeTextContent } from 'modern-idoc';
|
|
2
2
|
import { extend } from 'colord';
|
|
3
3
|
import namesPlugin from 'colord/plugins/names';
|
|
4
|
-
import { Path2D, Path2DSet, svgToDom, svgToPath2DSet, Matrix3 as Matrix3$1 } from 'modern-path2d';
|
|
5
|
-
import { Text } from 'modern-text';
|
|
4
|
+
import { Path2D, Path2DSet, svgToDom, svgToPath2DSet, Matrix3 as Matrix3$1, BoundingBox } from 'modern-path2d';
|
|
5
|
+
import { Text, Character } from 'modern-text';
|
|
6
6
|
|
|
7
7
|
const customNodes = /* @__PURE__ */ new Map();
|
|
8
8
|
function customNode(name, defaultProperties) {
|
|
@@ -5120,21 +5120,26 @@ class GradientTexture extends Texture2D {
|
|
|
5120
5120
|
if (!ctx) {
|
|
5121
5121
|
throw new Error("Failed to parse linear gradient, get canvas context is null.");
|
|
5122
5122
|
}
|
|
5123
|
-
|
|
5124
|
-
|
|
5125
|
-
const
|
|
5126
|
-
const
|
|
5127
|
-
const
|
|
5128
|
-
const
|
|
5129
|
-
const
|
|
5130
|
-
const
|
|
5131
|
-
const
|
|
5123
|
+
const { angle = 0, stops } = linearGradient;
|
|
5124
|
+
const w = width;
|
|
5125
|
+
const h = height;
|
|
5126
|
+
const cx = w / 2;
|
|
5127
|
+
const cy = h / 2;
|
|
5128
|
+
const canAng = angle * Math.PI / 180;
|
|
5129
|
+
const hypt = cy / Math.cos(canAng);
|
|
5130
|
+
const fromTopRight = cx - Math.sqrt(hypt * hypt - cy * cy);
|
|
5131
|
+
const diag = Math.sin(canAng) * fromTopRight;
|
|
5132
|
+
const len = hypt + diag;
|
|
5133
|
+
const x0 = cx + Math.cos(-Math.PI / 2 + canAng) * len;
|
|
5134
|
+
const y0 = cy + Math.sin(-Math.PI / 2 + canAng) * len;
|
|
5135
|
+
const x1 = cx + Math.cos(Math.PI / 2 + canAng) * len;
|
|
5136
|
+
const y1 = cy + Math.sin(Math.PI / 2 + canAng) * len;
|
|
5132
5137
|
const gradient = ctx.createLinearGradient(x0, y0, x1, y1);
|
|
5133
5138
|
stops.forEach((stop) => {
|
|
5134
5139
|
gradient.addColorStop(stop.offset, stop.color);
|
|
5135
5140
|
});
|
|
5136
5141
|
ctx.fillStyle = gradient;
|
|
5137
|
-
ctx.fillRect(0, 0,
|
|
5142
|
+
ctx.fillRect(0, 0, w, h);
|
|
5138
5143
|
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
|
5139
5144
|
return {
|
|
5140
5145
|
width: imageData.width,
|
|
@@ -9351,21 +9356,21 @@ ZoomBlurEffect = __decorateClass$t([
|
|
|
9351
9356
|
customNode("ZoomBlurEffect")
|
|
9352
9357
|
], ZoomBlurEffect);
|
|
9353
9358
|
|
|
9354
|
-
function getDrawOptions(fill,
|
|
9359
|
+
function getDrawOptions(fill, box) {
|
|
9355
9360
|
let disableWrapMode = false;
|
|
9356
|
-
const { width, height } =
|
|
9357
|
-
const uvTransform = new Transform2D().scale(1 / width, 1 / height);
|
|
9361
|
+
const { left = 0, top = 0, width, height } = box;
|
|
9362
|
+
const uvTransform = new Transform2D().translate(-left, -top).scale(1 / width, 1 / height);
|
|
9358
9363
|
if (fill.cropRect) {
|
|
9359
9364
|
const {
|
|
9360
|
-
left = 0,
|
|
9361
|
-
top = 0,
|
|
9365
|
+
left: left2 = 0,
|
|
9366
|
+
top: top2 = 0,
|
|
9362
9367
|
right = 0,
|
|
9363
9368
|
bottom = 0
|
|
9364
9369
|
} = fill.cropRect;
|
|
9365
9370
|
uvTransform.scale(
|
|
9366
|
-
Math.abs(1 - (
|
|
9367
|
-
Math.abs(1 - (
|
|
9368
|
-
).translate(
|
|
9371
|
+
Math.abs(1 - (left2 + right)),
|
|
9372
|
+
Math.abs(1 - (top2 + bottom))
|
|
9373
|
+
).translate(left2, top2);
|
|
9369
9374
|
disableWrapMode = true;
|
|
9370
9375
|
}
|
|
9371
9376
|
if (fill.tile) {
|
|
@@ -9380,11 +9385,16 @@ function getDrawOptions(fill, size) {
|
|
|
9380
9385
|
uvTransform.translate(-translateX / width, -translateY / height).scale(1 / scaleX, 1 / scaleY);
|
|
9381
9386
|
disableWrapMode = true;
|
|
9382
9387
|
} else if (fill.stretchRect) {
|
|
9383
|
-
const {
|
|
9388
|
+
const {
|
|
9389
|
+
left: left2 = 0,
|
|
9390
|
+
top: top2 = 0,
|
|
9391
|
+
right = 0,
|
|
9392
|
+
bottom = 0
|
|
9393
|
+
} = fill.stretchRect;
|
|
9384
9394
|
uvTransform.scale(
|
|
9385
|
-
Math.abs(1 - (-
|
|
9386
|
-
Math.abs(1 - (-
|
|
9387
|
-
).translate(-
|
|
9395
|
+
Math.abs(1 - (-left2 + -right)),
|
|
9396
|
+
Math.abs(1 - (-top2 + -bottom))
|
|
9397
|
+
).translate(-left2, -top2);
|
|
9388
9398
|
disableWrapMode = true;
|
|
9389
9399
|
}
|
|
9390
9400
|
return { disableWrapMode, uvTransform };
|
|
@@ -9460,7 +9470,10 @@ class BaseElement2DFill extends CoreObject {
|
|
|
9460
9470
|
const ctx = this.parent.context;
|
|
9461
9471
|
const { uvTransform, disableWrapMode } = getDrawOptions(
|
|
9462
9472
|
this,
|
|
9463
|
-
|
|
9473
|
+
{
|
|
9474
|
+
width: this.parent.size.width,
|
|
9475
|
+
height: this.parent.size.height
|
|
9476
|
+
}
|
|
9464
9477
|
);
|
|
9465
9478
|
ctx.uvTransform = uvTransform;
|
|
9466
9479
|
ctx.fillStyle = this._texture ?? this.color;
|
|
@@ -9595,7 +9608,10 @@ class BaseElement2DOutline extends BaseElement2DFill {
|
|
|
9595
9608
|
const ctx = this.parent.context;
|
|
9596
9609
|
const { uvTransform, disableWrapMode } = getDrawOptions(
|
|
9597
9610
|
this,
|
|
9598
|
-
|
|
9611
|
+
{
|
|
9612
|
+
width: this.parent.size.width,
|
|
9613
|
+
height: this.parent.size.height
|
|
9614
|
+
}
|
|
9599
9615
|
);
|
|
9600
9616
|
ctx.lineWidth = this.width || 1;
|
|
9601
9617
|
ctx.uvTransform = uvTransform;
|
|
@@ -9819,7 +9835,7 @@ class BaseElement2DText extends CoreObject {
|
|
|
9819
9835
|
}
|
|
9820
9836
|
base = new Text();
|
|
9821
9837
|
measureResult;
|
|
9822
|
-
|
|
9838
|
+
_textureMap = /* @__PURE__ */ new Map();
|
|
9823
9839
|
setProperties(properties) {
|
|
9824
9840
|
return super.setProperties(
|
|
9825
9841
|
isNone(properties) ? void 0 : normalizeText(properties)
|
|
@@ -9829,30 +9845,72 @@ class BaseElement2DText extends CoreObject {
|
|
|
9829
9845
|
super._updateProperty(key, value, oldValue, declaration);
|
|
9830
9846
|
switch (key) {
|
|
9831
9847
|
case "enabled":
|
|
9832
|
-
case "content":
|
|
9833
9848
|
case "effects":
|
|
9834
9849
|
case "measureDom":
|
|
9835
9850
|
case "fonts":
|
|
9836
9851
|
this.parent.requestRedraw();
|
|
9837
9852
|
break;
|
|
9838
9853
|
case "fill":
|
|
9839
|
-
this._updateTexture(0, value);
|
|
9840
|
-
break;
|
|
9841
9854
|
case "outline":
|
|
9842
|
-
|
|
9855
|
+
case "content":
|
|
9856
|
+
this._updateTextureMap();
|
|
9843
9857
|
break;
|
|
9844
9858
|
}
|
|
9845
9859
|
}
|
|
9846
|
-
|
|
9847
|
-
this.
|
|
9860
|
+
_update() {
|
|
9861
|
+
this.base.style = {
|
|
9862
|
+
justifyContent: "center",
|
|
9863
|
+
alignItems: "center",
|
|
9864
|
+
textAlign: "center",
|
|
9865
|
+
...this.parent.style.toJSON()
|
|
9866
|
+
};
|
|
9867
|
+
this.base.update();
|
|
9868
|
+
}
|
|
9869
|
+
_updateTextureMap() {
|
|
9870
|
+
this._update();
|
|
9871
|
+
this._textureMap.clear();
|
|
9872
|
+
const pGlyphBoxs = [];
|
|
9873
|
+
this.base.paragraphs.forEach((p, pIndex) => {
|
|
9874
|
+
const fGlyphBoxs = [];
|
|
9875
|
+
p.fragments.forEach((f, fIndex) => {
|
|
9876
|
+
if (f.characters.length) {
|
|
9877
|
+
const fGlyphBox = BoundingBox.from(
|
|
9878
|
+
...f.characters.map((c) => c.compatibleGlyphBox)
|
|
9879
|
+
);
|
|
9880
|
+
this._updateTexture(`${pIndex}.${fIndex}.fill`, f.fill, fGlyphBox);
|
|
9881
|
+
this._updateTexture(`${pIndex}.${fIndex}.outline`, f.outline, fGlyphBox);
|
|
9882
|
+
fGlyphBoxs.push(fGlyphBox);
|
|
9883
|
+
}
|
|
9884
|
+
});
|
|
9885
|
+
if (fGlyphBoxs.length) {
|
|
9886
|
+
const pGlyphBox = BoundingBox.from(...fGlyphBoxs);
|
|
9887
|
+
this._updateTexture(`${pIndex}.fill`, p.fill, pGlyphBox);
|
|
9888
|
+
this._updateTexture(`${pIndex}.outline`, p.outline, pGlyphBox);
|
|
9889
|
+
pGlyphBoxs.push(pGlyphBox);
|
|
9890
|
+
}
|
|
9891
|
+
});
|
|
9892
|
+
if (pGlyphBoxs.length) {
|
|
9893
|
+
const glyphBox = BoundingBox.from(...pGlyphBoxs);
|
|
9894
|
+
this._updateTexture("fill", this.fill, glyphBox);
|
|
9895
|
+
this._updateTexture("outline", this.outline, glyphBox);
|
|
9896
|
+
}
|
|
9848
9897
|
this.parent.requestRedraw();
|
|
9849
9898
|
}
|
|
9850
|
-
async
|
|
9899
|
+
async _updateTexture(key, fill, box) {
|
|
9900
|
+
if (fill && Object.keys(fill).length > 0) {
|
|
9901
|
+
this._textureMap.set(key, {
|
|
9902
|
+
texture: await this._loadTexture(fill, box),
|
|
9903
|
+
box
|
|
9904
|
+
});
|
|
9905
|
+
this.parent.requestRedraw();
|
|
9906
|
+
}
|
|
9907
|
+
}
|
|
9908
|
+
async _loadTexture(fill, box) {
|
|
9851
9909
|
if (fill.linearGradient || fill.radialGradient) {
|
|
9852
9910
|
return new GradientTexture(
|
|
9853
9911
|
fill.linearGradient ?? fill.radialGradient,
|
|
9854
|
-
|
|
9855
|
-
|
|
9912
|
+
box.width,
|
|
9913
|
+
box.height
|
|
9856
9914
|
);
|
|
9857
9915
|
} else if (!isNone(fill.image)) {
|
|
9858
9916
|
this.parent.tree?.log(`load image ${fill.image}`);
|
|
@@ -9871,7 +9929,6 @@ class BaseElement2DText extends CoreObject {
|
|
|
9871
9929
|
textAlign: "center",
|
|
9872
9930
|
...this.parent.style.toJSON()
|
|
9873
9931
|
};
|
|
9874
|
-
this.base.requestUpdate();
|
|
9875
9932
|
return this.base.measure();
|
|
9876
9933
|
}
|
|
9877
9934
|
updateMeasure() {
|
|
@@ -9885,57 +9942,76 @@ class BaseElement2DText extends CoreObject {
|
|
|
9885
9942
|
}
|
|
9886
9943
|
_getVertTransform() {
|
|
9887
9944
|
const parent = this.parent;
|
|
9888
|
-
if (parent.
|
|
9945
|
+
if (parent.scale.x > 0 && parent.scale.y > 0) {
|
|
9889
9946
|
return void 0;
|
|
9890
9947
|
}
|
|
9891
|
-
const scale = parent.
|
|
9948
|
+
const scale = parent.scale.x * parent.scale.y;
|
|
9892
9949
|
const origin = parent.getTransformOrigin();
|
|
9893
9950
|
return new Transform2D().translate(-origin.x, -origin.y).scale(scale > 0 ? 1 : -1, 1).translate(origin.x, origin.y);
|
|
9894
9951
|
}
|
|
9895
9952
|
draw() {
|
|
9896
9953
|
const ctx = this.parent.context;
|
|
9897
|
-
this.
|
|
9954
|
+
this._update();
|
|
9898
9955
|
this.base.pathSets.forEach((pathSet) => {
|
|
9899
9956
|
pathSet.paths.forEach((path) => {
|
|
9900
|
-
|
|
9901
|
-
|
|
9902
|
-
|
|
9903
|
-
|
|
9904
|
-
|
|
9957
|
+
const meta = path.getMeta();
|
|
9958
|
+
if (meta instanceof Character) {
|
|
9959
|
+
const fIndex = meta.parent.index;
|
|
9960
|
+
const pIndex = meta.parent.parent.index;
|
|
9961
|
+
if (path.style.fill && !isNone(path.style.fill)) {
|
|
9962
|
+
if (typeof path.style.fill === "object") {
|
|
9963
|
+
const fill = path.style.fill;
|
|
9964
|
+
const texture = this._textureMap.get(`${pIndex}.${fIndex}.fill`) ?? this._textureMap.get(`${pIndex}.fill`) ?? this._textureMap.get("fill");
|
|
9965
|
+
if (fill.enabled !== false && (texture || fill.color)) {
|
|
9966
|
+
const { uvTransform, disableWrapMode } = getDrawOptions(
|
|
9967
|
+
fill,
|
|
9968
|
+
texture?.box ?? {
|
|
9969
|
+
width: this.parent.size.width,
|
|
9970
|
+
height: this.parent.size.height
|
|
9971
|
+
}
|
|
9972
|
+
);
|
|
9973
|
+
ctx.addPath(path);
|
|
9974
|
+
ctx.style = { ...path.style };
|
|
9975
|
+
ctx.uvTransform = uvTransform;
|
|
9976
|
+
ctx.fillStyle = texture?.texture ?? fill.color;
|
|
9977
|
+
ctx.vertTransform = this._getVertTransform();
|
|
9978
|
+
ctx.fill({ disableWrapMode });
|
|
9979
|
+
}
|
|
9980
|
+
} else {
|
|
9905
9981
|
ctx.addPath(path);
|
|
9906
9982
|
ctx.style = { ...path.style };
|
|
9907
|
-
ctx.lineWidth = outline.width || 1;
|
|
9908
|
-
ctx.uvTransform = uvTransform;
|
|
9909
|
-
ctx.strokeStyle = this._textures[0] ?? outline.color;
|
|
9910
|
-
ctx.lineCap = outline.lineCap;
|
|
9911
|
-
ctx.lineJoin = outline.lineJoin;
|
|
9912
9983
|
ctx.vertTransform = this._getVertTransform();
|
|
9913
|
-
ctx.
|
|
9984
|
+
ctx.fill();
|
|
9914
9985
|
}
|
|
9915
|
-
} else {
|
|
9916
|
-
ctx.addPath(path);
|
|
9917
|
-
ctx.style = { ...path.style };
|
|
9918
|
-
ctx.vertTransform = this._getVertTransform();
|
|
9919
|
-
ctx.stroke();
|
|
9920
9986
|
}
|
|
9921
|
-
|
|
9922
|
-
|
|
9923
|
-
|
|
9924
|
-
|
|
9925
|
-
|
|
9926
|
-
|
|
9987
|
+
if (path.style.stroke && !isNone(path.style.stroke)) {
|
|
9988
|
+
if (typeof path.style.stroke === "object") {
|
|
9989
|
+
const outline = path.style.stroke;
|
|
9990
|
+
const texture = this._textureMap.get(`${pIndex}.${fIndex}.outline`) ?? this._textureMap.get(`${pIndex}.outline`) ?? this._textureMap.get("outline");
|
|
9991
|
+
if (outline.enabled !== false && (texture || outline.color) && (outline.width === void 0 || outline.width)) {
|
|
9992
|
+
const { uvTransform, disableWrapMode } = getDrawOptions(
|
|
9993
|
+
outline,
|
|
9994
|
+
texture?.box ?? {
|
|
9995
|
+
width: this.parent.size.width,
|
|
9996
|
+
height: this.parent.size.height
|
|
9997
|
+
}
|
|
9998
|
+
);
|
|
9999
|
+
ctx.addPath(path);
|
|
10000
|
+
ctx.style = { ...path.style };
|
|
10001
|
+
ctx.lineWidth = outline.width || 1;
|
|
10002
|
+
ctx.uvTransform = uvTransform;
|
|
10003
|
+
ctx.strokeStyle = texture?.texture ?? outline.color;
|
|
10004
|
+
ctx.lineCap = outline.lineCap;
|
|
10005
|
+
ctx.lineJoin = outline.lineJoin;
|
|
10006
|
+
ctx.vertTransform = this._getVertTransform();
|
|
10007
|
+
ctx.stroke({ disableWrapMode });
|
|
10008
|
+
}
|
|
10009
|
+
} else {
|
|
9927
10010
|
ctx.addPath(path);
|
|
9928
10011
|
ctx.style = { ...path.style };
|
|
9929
|
-
ctx.uvTransform = uvTransform;
|
|
9930
|
-
ctx.fillStyle = this._textures[1] ?? fill.color;
|
|
9931
10012
|
ctx.vertTransform = this._getVertTransform();
|
|
9932
|
-
ctx.
|
|
10013
|
+
ctx.stroke();
|
|
9933
10014
|
}
|
|
9934
|
-
} else {
|
|
9935
|
-
ctx.addPath(path);
|
|
9936
|
-
ctx.style = { ...path.style };
|
|
9937
|
-
ctx.vertTransform = this._getVertTransform();
|
|
9938
|
-
ctx.fill();
|
|
9939
10015
|
}
|
|
9940
10016
|
}
|
|
9941
10017
|
});
|
|
@@ -10069,16 +10145,22 @@ let BaseElement2D = class extends Node2D {
|
|
|
10069
10145
|
}
|
|
10070
10146
|
return this;
|
|
10071
10147
|
}
|
|
10072
|
-
_updateStyleProperty(key, value,
|
|
10148
|
+
_updateStyleProperty(key, value, oldValue, _declaration) {
|
|
10073
10149
|
switch (key) {
|
|
10074
10150
|
case "rotate":
|
|
10075
10151
|
this.rotation = this.style.rotate * DEG_TO_RAD;
|
|
10076
10152
|
break;
|
|
10077
10153
|
case "scaleX":
|
|
10078
10154
|
this.scale.x = this.style.scaleX;
|
|
10155
|
+
if (this.text.canDraw() && (value ^ oldValue) < 0) {
|
|
10156
|
+
this.requestRedraw();
|
|
10157
|
+
}
|
|
10079
10158
|
break;
|
|
10080
10159
|
case "scaleY":
|
|
10081
10160
|
this.scale.y = this.style.scaleY;
|
|
10161
|
+
if (this.text.canDraw() && (value ^ oldValue) < 0) {
|
|
10162
|
+
this.requestRedraw();
|
|
10163
|
+
}
|
|
10082
10164
|
break;
|
|
10083
10165
|
case "skewX":
|
|
10084
10166
|
this.skew.x = this.style.skewX;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "modern-canvas",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.8.
|
|
4
|
+
"version": "0.8.6",
|
|
5
5
|
"packageManager": "pnpm@9.15.1",
|
|
6
6
|
"description": "A JavaScript WebGL rendering engine.",
|
|
7
7
|
"author": "wxm",
|
|
@@ -75,8 +75,8 @@
|
|
|
75
75
|
"earcut": "^3.0.2",
|
|
76
76
|
"modern-font": "^0.4.1",
|
|
77
77
|
"modern-idoc": "^0.8.9",
|
|
78
|
-
"modern-path2d": "^1.4.
|
|
79
|
-
"modern-text": "^1.7.
|
|
78
|
+
"modern-path2d": "^1.4.9",
|
|
79
|
+
"modern-text": "^1.7.6"
|
|
80
80
|
},
|
|
81
81
|
"devDependencies": {
|
|
82
82
|
"@antfu/eslint-config": "^5.2.1",
|