@overtone-art/canvas-editor-core 0.6.0 → 0.6.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.js CHANGED
@@ -294,6 +294,19 @@ var LayerManager = class {
294
294
  this.layers = this.layers.filter((l) => l.id !== group.id);
295
295
  this.syncZOrder();
296
296
  }
297
+ /**
298
+ * Move existing layer records under a group, and announce the new tree.
299
+ * Assigning `group.children` directly emits nothing, and the reorder that
300
+ * follows a grouping is a no-op whenever the group already sits where it
301
+ * belongs — leaving `layers:changed` describing a childless group, so a panel
302
+ * built on it renders the group with nothing inside.
303
+ */
304
+ adoptChildren(group, children) {
305
+ for (const child of children) child.parentId = group.id;
306
+ group.children = children;
307
+ this.emitChanged();
308
+ this.onPropertyChanged?.();
309
+ }
297
310
  /**
298
311
  * Re-attach child records to an enlivened group. `data[i]` describes
299
312
  * `group._objects[i]` — the order fabric serializes and restores them in. A
@@ -1948,6 +1961,7 @@ var MEASURE_WIDTH = 1e5;
1948
1961
  var PATH_SLACK = 0.06;
1949
1962
  var FALLBACK_LINE_HEIGHT = 1.16;
1950
1963
  var patches = /* @__PURE__ */ new WeakMap();
1964
+ var authoredCaching = /* @__PURE__ */ new WeakMap();
1951
1965
  function isCurvable(object) {
1952
1966
  return !!object && typeof object.text === "string";
1953
1967
  }
@@ -1979,11 +1993,29 @@ var TextCurveManager = class {
1979
1993
  this.layers = layers;
1980
1994
  this.history = history;
1981
1995
  this.events = events;
1996
+ this.canvas.on("text:changed", this.onTextChanged);
1982
1997
  }
1983
1998
  canvas;
1984
1999
  layers;
1985
2000
  history;
1986
2001
  events;
2002
+ /**
2003
+ * Typing on the canvas changes the run the paths were built for. Fabric drops
2004
+ * a glyph whose centre falls past the end of the path, so without rebuilding
2005
+ * here a longer replacement simply vanishes — select-all-and-retype rendered
2006
+ * an empty box — and a shorter one piles up on a path built for the old text.
2007
+ *
2008
+ * No history entry: fabric records the edit when editing exits, and one save
2009
+ * per keystroke would bury every earlier step under the typing.
2010
+ */
2011
+ onTextChanged = (event) => {
2012
+ const layer = event.target ? this.layers.findByObject(event.target) : void 0;
2013
+ if (!layer?.meta.curve) return;
2014
+ this.refresh(layer.id, false);
2015
+ };
2016
+ dispose() {
2017
+ this.canvas.off("text:changed", this.onTextChanged);
2018
+ }
1987
2019
  /** Curve parameters for a layer, or null when it is not curved text. */
1988
2020
  get(layerId) {
1989
2021
  const layer = this.layers.get(layerId);
@@ -2043,11 +2075,21 @@ var TextCurveManager = class {
2043
2075
  if (!curve) return false;
2044
2076
  return this.apply(layerId, curve, save);
2045
2077
  }
2046
- /** Rebuild every curved layer — used after a state restore. */
2078
+ /**
2079
+ * Rebuild every curved layer — used after a state restore.
2080
+ *
2081
+ * `getAll` is the canvas stack, so this walks each group's children too:
2082
+ * curved text inside a group would otherwise keep the path geometry it was
2083
+ * restored with, and stop tracking its own text, font and size.
2084
+ */
2047
2085
  refreshAll() {
2048
- for (const layer of this.layers.getAll()) {
2049
- if (layer.meta.curve) this.refresh(layer.id);
2050
- }
2086
+ const visit = (layers) => {
2087
+ for (const layer of layers) {
2088
+ if (layer.meta.curve) this.refresh(layer.id);
2089
+ if (layer.children.length > 0) visit(layer.children);
2090
+ }
2091
+ };
2092
+ visit(this.layers.getAll());
2051
2093
  }
2052
2094
  /**
2053
2095
  * Puts every line's path on the object as one shape, and hooks per-line
@@ -2058,6 +2100,8 @@ var TextCurveManager = class {
2058
2100
  * outside the layer's box — where object caching clips it away.
2059
2101
  */
2060
2102
  attach(text, curves) {
2103
+ if (!authoredCaching.has(text)) authoredCaching.set(text, text.objectCaching);
2104
+ text.set({ objectCaching: false });
2061
2105
  const paths = curves.map(toFabricPath);
2062
2106
  const union = paths.length === 1 ? paths[0] : toFabricPath({ data: curves.map((c) => c.data).join(" "), length: 0 });
2063
2107
  text.set({
@@ -2120,6 +2164,11 @@ var TextCurveManager = class {
2120
2164
  }
2121
2165
  detach(text, authoredWidth) {
2122
2166
  this.unpatchLineMeasure(text);
2167
+ const caching = authoredCaching.get(text);
2168
+ if (caching !== void 0) {
2169
+ text.set({ objectCaching: caching });
2170
+ authoredCaching.delete(text);
2171
+ }
2123
2172
  text.set({ path: null, pathStartOffset: 0 });
2124
2173
  if (authoredWidth !== void 0 && authoredWidth > 0) text.set({ width: authoredWidth });
2125
2174
  }
@@ -4520,8 +4569,7 @@ var CanvasEditor = class {
4520
4569
  }
4521
4570
  const group = new import_fabric19.Group(objects);
4522
4571
  const grouped = this.layers.add("group", group, name);
4523
- for (const child of children) child.parentId = grouped.id;
4524
- grouped.children = children;
4572
+ this.layers.adoptChildren(grouped, children);
4525
4573
  this.layers.reorder(grouped.id, insertIndex);
4526
4574
  this.layers.select(grouped.id);
4527
4575
  this.history.save();
@@ -5130,6 +5178,7 @@ var CanvasEditor = class {
5130
5178
  this.crop.dispose();
5131
5179
  this.history.dispose();
5132
5180
  this.patterns.dispose();
5181
+ this.curves.dispose();
5133
5182
  this.events.removeAllListeners();
5134
5183
  this.canvas.dispose();
5135
5184
  }