modern-text 0.3.1 → 0.3.2

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
@@ -79,16 +79,17 @@ function drawPath(options) {
79
79
  function setupView(ctx, pixelRatio, boundingBox) {
80
80
  const { left, top, width, height } = boundingBox;
81
81
  const view = ctx.canvas;
82
- view.dataset.viewbox = String(`${left} ${top} ${width} ${height}`);
82
+ view.dataset.viewBox = String(`${left} ${top} ${width} ${height}`);
83
83
  view.dataset.pixelRatio = String(pixelRatio);
84
- const canvasWidth = width + left;
85
- const canvasHeight = height + top;
84
+ const canvasWidth = width + Math.abs(left);
85
+ const canvasHeight = height + Math.abs(top);
86
86
  view.width = Math.max(1, Math.ceil(canvasWidth * pixelRatio));
87
87
  view.height = Math.max(1, Math.ceil(canvasHeight * pixelRatio));
88
88
  view.style.width = `${canvasWidth}px`;
89
89
  view.style.height = `${canvasHeight}px`;
90
- ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
90
+ ctx.clearRect(0, 0, view.width, view.height);
91
91
  ctx.scale(pixelRatio, pixelRatio);
92
+ ctx.translate(-Math.min(0, left), -Math.min(0, top));
92
93
  }
93
94
 
94
95
  function uploadColors(ctx, text) {
@@ -150,7 +151,6 @@ class Character {
150
151
  __publicField$3(this, "lineBox", new BoundingBox());
151
152
  __publicField$3(this, "inlineBox", new BoundingBox());
152
153
  __publicField$3(this, "glyphBox");
153
- __publicField$3(this, "center");
154
154
  __publicField$3(this, "underlinePosition", 0);
155
155
  __publicField$3(this, "underlineThickness", 0);
156
156
  __publicField$3(this, "yStrikeoutPosition", 0);
@@ -159,6 +159,9 @@ class Character {
159
159
  __publicField$3(this, "centerDiviation", 0);
160
160
  __publicField$3(this, "path", new Path2D());
161
161
  }
162
+ get center() {
163
+ return this.glyphBox?.center;
164
+ }
162
165
  get computedStyle() {
163
166
  return this.parent.computedStyle;
164
167
  }
@@ -288,7 +291,6 @@ class Character {
288
291
  };
289
292
  this.path = path;
290
293
  this.glyphBox = this.getGlyphBoundingBox();
291
- this.center = this.glyphBox?.getCenterPoint();
292
294
  return this;
293
295
  }
294
296
  update() {
@@ -747,8 +749,8 @@ function getTransformMatrix(a, b, c, isVertical) {
747
749
  y: c.height / b.width
748
750
  };
749
751
  }
750
- const offset = c.getCenterPoint().add(
751
- a.getCenterPoint().sub(b.getCenterPoint()).scale(scale.x, scale.y)
752
+ const offset = c.center.add(
753
+ a.center.sub(b.center).scale(scale.x, scale.y)
752
754
  ).sub({
753
755
  x: a.width / 2 * scale.x,
754
756
  y: a.height / 2 * scale.y
@@ -1103,8 +1105,10 @@ class Text {
1103
1105
  __publicField(this, "needsUpdate", true);
1104
1106
  __publicField(this, "computedStyle", { ...defaultTextStyles });
1105
1107
  __publicField(this, "paragraphs", []);
1106
- __publicField(this, "boundingBox", new BoundingBox());
1108
+ __publicField(this, "lineBox", new BoundingBox());
1107
1109
  __publicField(this, "glyphBox", new BoundingBox());
1110
+ __publicField(this, "pathBox", new BoundingBox());
1111
+ __publicField(this, "boundingBox", new BoundingBox());
1108
1112
  __publicField(this, "parser", new Parser(this));
1109
1113
  __publicField(this, "measurer", new Measurer(this));
1110
1114
  __publicField(this, "plugins", /* @__PURE__ */ new Map());
@@ -1132,22 +1136,33 @@ class Text {
1132
1136
  this.computedStyle = { ...defaultTextStyles, ...this.style };
1133
1137
  const old = {
1134
1138
  paragraphs: this.paragraphs,
1135
- boundingBox: this.boundingBox,
1136
- glyphBox: this.glyphBox
1139
+ lineBox: this.lineBox,
1140
+ glyphBox: this.glyphBox,
1141
+ pathBox: this.pathBox,
1142
+ boundingBox: this.boundingBox
1137
1143
  };
1138
1144
  this.paragraphs = this.parser.parse();
1139
1145
  const result = this.measurer.measure(dom);
1140
1146
  this.paragraphs = result.paragraphs;
1141
- this.boundingBox = result.boundingBox;
1142
- const characters = this.characters;
1143
- characters.forEach((c) => c.update());
1147
+ this.lineBox = result.boundingBox;
1148
+ this.characters.forEach((c) => {
1149
+ c.update();
1150
+ });
1144
1151
  const plugins = [...this.plugins.values()];
1145
1152
  plugins.sort((a, b) => (a.updateOrder ?? 0) - (b.updateOrder ?? 0)).forEach((plugin) => {
1146
1153
  plugin.update?.(this);
1147
1154
  });
1155
+ this.updateGlyphBox().updatePathBox().updateBoundingBox();
1156
+ for (const key in old) {
1157
+ result[key] = this[key];
1158
+ this[key] = old[key];
1159
+ }
1160
+ return result;
1161
+ }
1162
+ updateGlyphBox() {
1148
1163
  const min = Vector2.MAX;
1149
1164
  const max = Vector2.MIN;
1150
- characters.forEach((c) => {
1165
+ this.characters.forEach((c) => {
1151
1166
  if (!c.getGlyphMinMax(min, max)) {
1152
1167
  const { inlineBox } = c;
1153
1168
  const a = new Vector2(inlineBox.left, inlineBox.top);
@@ -1156,37 +1171,47 @@ class Text {
1156
1171
  max.max(a, b);
1157
1172
  }
1158
1173
  });
1159
- this.glyphBox = new BoundingBox(min.x, min.y, max.x - min.x, max.y - min.y);
1160
- const dLeft = this.glyphBox.left - result.boundingBox.left;
1161
- const dRight = result.boundingBox.right - this.glyphBox.right;
1162
- const dTop = this.glyphBox.top - result.boundingBox.top;
1163
- const dBottom = result.boundingBox.bottom - this.glyphBox.bottom;
1164
- this.glyphBox = BoundingBox.from(
1174
+ this.glyphBox = new BoundingBox(
1175
+ min.x,
1176
+ min.y,
1177
+ max.x - min.x,
1178
+ max.y - min.y
1179
+ );
1180
+ return this;
1181
+ }
1182
+ updatePathBox() {
1183
+ const plugins = [...this.plugins.values()];
1184
+ this.pathBox = BoundingBox.from(
1165
1185
  this.glyphBox,
1166
1186
  ...plugins.map((plugin) => {
1167
- if (plugin.getBoundingBox) {
1168
- return plugin.getBoundingBox(this);
1169
- }
1170
- return getPathsBoundingBox(plugin.paths ?? []);
1187
+ return plugin.getBoundingBox ? plugin.getBoundingBox(this) : getPathsBoundingBox(plugin.paths ?? []);
1171
1188
  }).filter(Boolean)
1172
1189
  );
1173
- result.glyphBox = this.glyphBox;
1174
- result.boundingBox.width = this.glyphBox.width + dLeft + dRight;
1175
- result.boundingBox.height = this.glyphBox.height + dTop + dBottom;
1176
- this.paragraphs = old.paragraphs;
1177
- this.boundingBox = old.boundingBox;
1178
- this.glyphBox = old.glyphBox;
1179
- return result;
1190
+ return this;
1191
+ }
1192
+ updateBoundingBox() {
1193
+ const { lineBox, glyphBox, pathBox } = this;
1194
+ const left = pathBox.left + lineBox.left - glyphBox.left;
1195
+ const top = pathBox.top + lineBox.top - glyphBox.top;
1196
+ const right = pathBox.right + Math.max(0, lineBox.right - glyphBox.right);
1197
+ const bottom = pathBox.bottom + Math.max(0, lineBox.bottom - glyphBox.bottom);
1198
+ this.boundingBox = new BoundingBox(
1199
+ left,
1200
+ top,
1201
+ right - left,
1202
+ bottom - top
1203
+ );
1204
+ return this;
1180
1205
  }
1181
1206
  requestUpdate() {
1182
1207
  this.needsUpdate = true;
1183
1208
  return this;
1184
1209
  }
1185
1210
  update() {
1186
- const { paragraphs, boundingBox, glyphBox } = this.measure();
1187
- this.paragraphs = paragraphs;
1188
- this.boundingBox = boundingBox;
1189
- this.glyphBox = glyphBox;
1211
+ const result = this.measure();
1212
+ for (const key in result) {
1213
+ this[key] = result[key];
1214
+ }
1190
1215
  return this;
1191
1216
  }
1192
1217
  render(options) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "modern-text",
3
3
  "type": "module",
4
- "version": "0.3.1",
4
+ "version": "0.3.2",
5
5
  "packageManager": "pnpm@9.9.0",
6
6
  "description": "Measure and render text in a way that describes the DOM.",
7
7
  "author": "wxm",
@@ -58,7 +58,7 @@
58
58
  },
59
59
  "dependencies": {
60
60
  "modern-font": "^0.2.1",
61
- "modern-path2d": "^0.2.4"
61
+ "modern-path2d": "^0.2.5"
62
62
  },
63
63
  "devDependencies": {
64
64
  "@antfu/eslint-config": "^3.7.3",