modern-text 0.2.17 → 0.2.18
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 +60 -50
- package/dist/index.d.cts +4 -2
- package/dist/index.d.mts +4 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.js +2 -2
- package/dist/index.mjs +61 -51
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -52,52 +52,27 @@ function parseCssLinearGradient(css, x, y, width, height) {
|
|
|
52
52
|
};
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
const _tempM2 = new modernPath2d.Matrix3();
|
|
57
|
-
function drawPath(options, isText = false) {
|
|
55
|
+
function drawPath(options) {
|
|
58
56
|
const { ctx, path, fontSize, clipRect } = options;
|
|
59
57
|
ctx.save();
|
|
60
58
|
ctx.beginPath();
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
...
|
|
64
|
-
fill: options.color ??
|
|
65
|
-
stroke: options.textStrokeColor ??
|
|
66
|
-
strokeWidth: options.textStrokeWidth ? options.textStrokeWidth * fontSize :
|
|
59
|
+
const pathStyle = path.style;
|
|
60
|
+
const style = {
|
|
61
|
+
...pathStyle,
|
|
62
|
+
fill: options.color ?? pathStyle.fill,
|
|
63
|
+
stroke: options.textStrokeColor ?? pathStyle.stroke,
|
|
64
|
+
strokeWidth: options.textStrokeWidth ? options.textStrokeWidth * fontSize : pathStyle.strokeWidth,
|
|
67
65
|
shadowOffsetX: (options.shadowOffsetX ?? 0) * fontSize,
|
|
68
66
|
shadowOffsetY: (options.shadowOffsetY ?? 0) * fontSize,
|
|
69
67
|
shadowBlur: (options.shadowBlur ?? 0) * fontSize,
|
|
70
68
|
shadowColor: options.shadowColor
|
|
71
69
|
};
|
|
72
|
-
const offsetX = (options.offsetX ?? 0) * fontSize;
|
|
73
|
-
const offsetY = (options.offsetY ?? 0) * fontSize;
|
|
74
|
-
const skewX = (options.skewX ?? 0) / 180 * Math.PI;
|
|
75
|
-
const skewY = (options.skewY ?? 0) / 180 * Math.PI;
|
|
76
|
-
if (offsetX || offsetY || skewX || skewY) {
|
|
77
|
-
_tempM1.makeTranslation(offsetX, offsetY);
|
|
78
|
-
_tempM2.set(1, Math.tan(skewX), 0, Math.tan(skewY), 1, 0, 0, 0, 1);
|
|
79
|
-
const [a, c, e, b, d, f] = _tempM1.multiply(_tempM2).transpose().elements;
|
|
80
|
-
ctx.transform(a, b, c, d, e, f);
|
|
81
|
-
}
|
|
82
70
|
if (clipRect) {
|
|
83
71
|
ctx.rect(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
|
|
84
72
|
ctx.clip();
|
|
85
73
|
ctx.beginPath();
|
|
86
74
|
}
|
|
87
|
-
|
|
88
|
-
const scale = path.style.strokeWidth / fontSize + 1;
|
|
89
|
-
const box = path.getBoundingBox();
|
|
90
|
-
ctx.translate(
|
|
91
|
-
box.left * (1 - scale) + box.width * (1 - scale) / 2,
|
|
92
|
-
box.top * (1 - scale) + box.height * (1 - scale) / 2
|
|
93
|
-
);
|
|
94
|
-
ctx.scale(scale, scale);
|
|
95
|
-
const clone = path.clone();
|
|
96
|
-
clone.style.strokeWidth /= scale * 2;
|
|
97
|
-
clone.drawTo(ctx);
|
|
98
|
-
} else {
|
|
99
|
-
path.drawTo(ctx);
|
|
100
|
-
}
|
|
75
|
+
path.drawTo(ctx, style);
|
|
101
76
|
ctx.restore();
|
|
102
77
|
}
|
|
103
78
|
|
|
@@ -416,7 +391,7 @@ class Character {
|
|
|
416
391
|
fontSize: this.computedStyle.fontSize,
|
|
417
392
|
color: this.computedStyle.color,
|
|
418
393
|
...config
|
|
419
|
-
}
|
|
394
|
+
});
|
|
420
395
|
}
|
|
421
396
|
}
|
|
422
397
|
|
|
@@ -497,21 +472,51 @@ class Deformer extends Feature {
|
|
|
497
472
|
}
|
|
498
473
|
}
|
|
499
474
|
|
|
475
|
+
const tempM1 = new modernPath2d.Matrix3();
|
|
476
|
+
const tempM2 = new modernPath2d.Matrix3();
|
|
477
|
+
const tempV1 = new modernPath2d.Vector2();
|
|
500
478
|
class Effector extends Feature {
|
|
479
|
+
getTransform2D(style) {
|
|
480
|
+
const { fontSize, renderBoundingBox } = this._text;
|
|
481
|
+
const offsetX = (style.offsetX ?? 0) * fontSize;
|
|
482
|
+
const offsetY = (style.offsetY ?? 0) * fontSize;
|
|
483
|
+
const PI_2 = Math.PI * 2;
|
|
484
|
+
const skewX = (style.skewX ?? 0) / 360 * PI_2;
|
|
485
|
+
const skewY = (style.skewY ?? 0) / 360 * PI_2;
|
|
486
|
+
const { left, top, width, height } = renderBoundingBox;
|
|
487
|
+
const centerX = left + width / 2;
|
|
488
|
+
const centerY = top + height / 2;
|
|
489
|
+
tempM1.identity();
|
|
490
|
+
tempM2.makeTranslation(offsetX, offsetY);
|
|
491
|
+
tempM1.multiply(tempM2);
|
|
492
|
+
tempM2.makeTranslation(centerX, centerY);
|
|
493
|
+
tempM1.multiply(tempM2);
|
|
494
|
+
tempM2.set(1, Math.tan(skewX), 0, Math.tan(skewY), 1, 0, 0, 0, 1);
|
|
495
|
+
tempM1.multiply(tempM2);
|
|
496
|
+
tempM2.makeTranslation(-centerX, -centerY);
|
|
497
|
+
tempM1.multiply(tempM2);
|
|
498
|
+
return tempM1.clone();
|
|
499
|
+
}
|
|
501
500
|
getBoundingBox() {
|
|
502
|
-
const { characters, effects } = this._text;
|
|
501
|
+
const { characters, effects, fontSize } = this._text;
|
|
503
502
|
const boxes = [];
|
|
504
503
|
characters.forEach((character) => {
|
|
505
|
-
|
|
506
|
-
effects?.forEach((effect) => {
|
|
507
|
-
const offsetX = (effect.offsetX ?? 0) * fontSize;
|
|
508
|
-
const offsetY = (effect.offsetY ?? 0) * fontSize;
|
|
509
|
-
const shadowOffsetX = (effect.shadowOffsetX ?? 0) * fontSize;
|
|
510
|
-
const shadowOffsetY = (effect.shadowOffsetY ?? 0) * fontSize;
|
|
511
|
-
const textStrokeWidth = Math.max(0.1, effect.textStrokeWidth ?? 0) * fontSize;
|
|
504
|
+
effects?.forEach((style) => {
|
|
512
505
|
const aabb = character.boundingBox.clone();
|
|
513
|
-
|
|
514
|
-
aabb.top
|
|
506
|
+
const m = this.getTransform2D(style);
|
|
507
|
+
tempV1.set(aabb.left, aabb.top);
|
|
508
|
+
tempV1.applyMatrix3(m);
|
|
509
|
+
aabb.left = tempV1.x;
|
|
510
|
+
aabb.top = tempV1.y;
|
|
511
|
+
tempV1.set(aabb.right, aabb.bottom);
|
|
512
|
+
tempV1.applyMatrix3(m);
|
|
513
|
+
aabb.width = tempV1.x - aabb.left;
|
|
514
|
+
aabb.height = tempV1.y - aabb.top;
|
|
515
|
+
const shadowOffsetX = (style.shadowOffsetX ?? 0) * fontSize;
|
|
516
|
+
const shadowOffsetY = (style.shadowOffsetY ?? 0) * fontSize;
|
|
517
|
+
const textStrokeWidth = Math.max(0.1, style.textStrokeWidth ?? 0) * fontSize;
|
|
518
|
+
aabb.left += shadowOffsetX - textStrokeWidth;
|
|
519
|
+
aabb.top += shadowOffsetY - textStrokeWidth;
|
|
515
520
|
aabb.width += textStrokeWidth * 2;
|
|
516
521
|
aabb.height += textStrokeWidth * 2;
|
|
517
522
|
boxes.push(aabb);
|
|
@@ -521,15 +526,17 @@ class Effector extends Feature {
|
|
|
521
526
|
}
|
|
522
527
|
draw(options) {
|
|
523
528
|
const { ctx } = options;
|
|
524
|
-
const { effects, characters,
|
|
529
|
+
const { effects, characters, renderBoundingBox } = this._text;
|
|
525
530
|
if (effects) {
|
|
526
|
-
effects.forEach((
|
|
527
|
-
uploadColor(
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
+
effects.forEach((style) => {
|
|
532
|
+
uploadColor(style, renderBoundingBox, ctx);
|
|
533
|
+
ctx.save();
|
|
534
|
+
const [a, c, e, b, d, f] = this.getTransform2D(style).transpose().elements;
|
|
535
|
+
ctx.transform(a, b, c, d, e, f);
|
|
536
|
+
characters.forEach((character) => {
|
|
531
537
|
character.drawTo(ctx, style);
|
|
532
538
|
});
|
|
539
|
+
ctx.restore();
|
|
533
540
|
});
|
|
534
541
|
}
|
|
535
542
|
return this;
|
|
@@ -1046,6 +1053,9 @@ class Text {
|
|
|
1046
1053
|
this.deformation = deformation;
|
|
1047
1054
|
this.measureDom = measureDom;
|
|
1048
1055
|
}
|
|
1056
|
+
get fontSize() {
|
|
1057
|
+
return this.computedStyle.fontSize;
|
|
1058
|
+
}
|
|
1049
1059
|
get characters() {
|
|
1050
1060
|
return this.paragraphs.flatMap((p) => p.fragments.flatMap((f) => f.characters));
|
|
1051
1061
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BoundingBox, Path2D, VectorLike, Vector2 } from 'modern-path2d';
|
|
1
|
+
import { BoundingBox, Path2D, VectorLike, Vector2, Matrix3 } from 'modern-path2d';
|
|
2
2
|
import { Sfnt, GlyphPathCommand } from 'modern-font';
|
|
3
3
|
export * from 'modern-font';
|
|
4
4
|
|
|
@@ -78,7 +78,7 @@ interface DrawShapePathsOptions extends Partial<TextEffect> {
|
|
|
78
78
|
fontSize: number;
|
|
79
79
|
clipRect?: BoundingBox;
|
|
80
80
|
}
|
|
81
|
-
declare function drawPath(options: DrawShapePathsOptions
|
|
81
|
+
declare function drawPath(options: DrawShapePathsOptions): void;
|
|
82
82
|
|
|
83
83
|
declare class Fragment {
|
|
84
84
|
content: string;
|
|
@@ -195,6 +195,7 @@ declare class Text {
|
|
|
195
195
|
effector: Effector;
|
|
196
196
|
highlighter: Highlighter;
|
|
197
197
|
renderer2D: Renderer2D;
|
|
198
|
+
get fontSize(): number;
|
|
198
199
|
get characters(): Character[];
|
|
199
200
|
constructor(options?: TextOptions);
|
|
200
201
|
measure(dom?: HTMLElement | undefined): MeasuredResult;
|
|
@@ -216,6 +217,7 @@ interface EffectOptions {
|
|
|
216
217
|
ctx: CanvasRenderingContext2D;
|
|
217
218
|
}
|
|
218
219
|
declare class Effector extends Feature {
|
|
220
|
+
getTransform2D(style: TextEffect): Matrix3;
|
|
219
221
|
getBoundingBox(): BoundingBox;
|
|
220
222
|
draw(options: EffectOptions): this;
|
|
221
223
|
}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BoundingBox, Path2D, VectorLike, Vector2 } from 'modern-path2d';
|
|
1
|
+
import { BoundingBox, Path2D, VectorLike, Vector2, Matrix3 } from 'modern-path2d';
|
|
2
2
|
import { Sfnt, GlyphPathCommand } from 'modern-font';
|
|
3
3
|
export * from 'modern-font';
|
|
4
4
|
|
|
@@ -78,7 +78,7 @@ interface DrawShapePathsOptions extends Partial<TextEffect> {
|
|
|
78
78
|
fontSize: number;
|
|
79
79
|
clipRect?: BoundingBox;
|
|
80
80
|
}
|
|
81
|
-
declare function drawPath(options: DrawShapePathsOptions
|
|
81
|
+
declare function drawPath(options: DrawShapePathsOptions): void;
|
|
82
82
|
|
|
83
83
|
declare class Fragment {
|
|
84
84
|
content: string;
|
|
@@ -195,6 +195,7 @@ declare class Text {
|
|
|
195
195
|
effector: Effector;
|
|
196
196
|
highlighter: Highlighter;
|
|
197
197
|
renderer2D: Renderer2D;
|
|
198
|
+
get fontSize(): number;
|
|
198
199
|
get characters(): Character[];
|
|
199
200
|
constructor(options?: TextOptions);
|
|
200
201
|
measure(dom?: HTMLElement | undefined): MeasuredResult;
|
|
@@ -216,6 +217,7 @@ interface EffectOptions {
|
|
|
216
217
|
ctx: CanvasRenderingContext2D;
|
|
217
218
|
}
|
|
218
219
|
declare class Effector extends Feature {
|
|
220
|
+
getTransform2D(style: TextEffect): Matrix3;
|
|
219
221
|
getBoundingBox(): BoundingBox;
|
|
220
222
|
draw(options: EffectOptions): this;
|
|
221
223
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BoundingBox, Path2D, VectorLike, Vector2 } from 'modern-path2d';
|
|
1
|
+
import { BoundingBox, Path2D, VectorLike, Vector2, Matrix3 } from 'modern-path2d';
|
|
2
2
|
import { Sfnt, GlyphPathCommand } from 'modern-font';
|
|
3
3
|
export * from 'modern-font';
|
|
4
4
|
|
|
@@ -78,7 +78,7 @@ interface DrawShapePathsOptions extends Partial<TextEffect> {
|
|
|
78
78
|
fontSize: number;
|
|
79
79
|
clipRect?: BoundingBox;
|
|
80
80
|
}
|
|
81
|
-
declare function drawPath(options: DrawShapePathsOptions
|
|
81
|
+
declare function drawPath(options: DrawShapePathsOptions): void;
|
|
82
82
|
|
|
83
83
|
declare class Fragment {
|
|
84
84
|
content: string;
|
|
@@ -195,6 +195,7 @@ declare class Text {
|
|
|
195
195
|
effector: Effector;
|
|
196
196
|
highlighter: Highlighter;
|
|
197
197
|
renderer2D: Renderer2D;
|
|
198
|
+
get fontSize(): number;
|
|
198
199
|
get characters(): Character[];
|
|
199
200
|
constructor(options?: TextOptions);
|
|
200
201
|
measure(dom?: HTMLElement | undefined): MeasuredResult;
|
|
@@ -216,6 +217,7 @@ interface EffectOptions {
|
|
|
216
217
|
ctx: CanvasRenderingContext2D;
|
|
217
218
|
}
|
|
218
219
|
declare class Effector extends Feature {
|
|
220
|
+
getTransform2D(style: TextEffect): Matrix3;
|
|
219
221
|
getBoundingBox(): BoundingBox;
|
|
220
222
|
draw(options: EffectOptions): this;
|
|
221
223
|
}
|