@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.mjs CHANGED
@@ -209,6 +209,19 @@ var LayerManager = class {
209
209
  this.layers = this.layers.filter((l) => l.id !== group.id);
210
210
  this.syncZOrder();
211
211
  }
212
+ /**
213
+ * Move existing layer records under a group, and announce the new tree.
214
+ * Assigning `group.children` directly emits nothing, and the reorder that
215
+ * follows a grouping is a no-op whenever the group already sits where it
216
+ * belongs — leaving `layers:changed` describing a childless group, so a panel
217
+ * built on it renders the group with nothing inside.
218
+ */
219
+ adoptChildren(group, children) {
220
+ for (const child of children) child.parentId = group.id;
221
+ group.children = children;
222
+ this.emitChanged();
223
+ this.onPropertyChanged?.();
224
+ }
212
225
  /**
213
226
  * Re-attach child records to an enlivened group. `data[i]` describes
214
227
  * `group._objects[i]` — the order fabric serializes and restores them in. A
@@ -1863,6 +1876,7 @@ var MEASURE_WIDTH = 1e5;
1863
1876
  var PATH_SLACK = 0.06;
1864
1877
  var FALLBACK_LINE_HEIGHT = 1.16;
1865
1878
  var patches = /* @__PURE__ */ new WeakMap();
1879
+ var authoredCaching = /* @__PURE__ */ new WeakMap();
1866
1880
  function isCurvable(object) {
1867
1881
  return !!object && typeof object.text === "string";
1868
1882
  }
@@ -1894,11 +1908,29 @@ var TextCurveManager = class {
1894
1908
  this.layers = layers;
1895
1909
  this.history = history;
1896
1910
  this.events = events;
1911
+ this.canvas.on("text:changed", this.onTextChanged);
1897
1912
  }
1898
1913
  canvas;
1899
1914
  layers;
1900
1915
  history;
1901
1916
  events;
1917
+ /**
1918
+ * Typing on the canvas changes the run the paths were built for. Fabric drops
1919
+ * a glyph whose centre falls past the end of the path, so without rebuilding
1920
+ * here a longer replacement simply vanishes — select-all-and-retype rendered
1921
+ * an empty box — and a shorter one piles up on a path built for the old text.
1922
+ *
1923
+ * No history entry: fabric records the edit when editing exits, and one save
1924
+ * per keystroke would bury every earlier step under the typing.
1925
+ */
1926
+ onTextChanged = (event) => {
1927
+ const layer = event.target ? this.layers.findByObject(event.target) : void 0;
1928
+ if (!layer?.meta.curve) return;
1929
+ this.refresh(layer.id, false);
1930
+ };
1931
+ dispose() {
1932
+ this.canvas.off("text:changed", this.onTextChanged);
1933
+ }
1902
1934
  /** Curve parameters for a layer, or null when it is not curved text. */
1903
1935
  get(layerId) {
1904
1936
  const layer = this.layers.get(layerId);
@@ -1958,11 +1990,21 @@ var TextCurveManager = class {
1958
1990
  if (!curve) return false;
1959
1991
  return this.apply(layerId, curve, save);
1960
1992
  }
1961
- /** Rebuild every curved layer — used after a state restore. */
1993
+ /**
1994
+ * Rebuild every curved layer — used after a state restore.
1995
+ *
1996
+ * `getAll` is the canvas stack, so this walks each group's children too:
1997
+ * curved text inside a group would otherwise keep the path geometry it was
1998
+ * restored with, and stop tracking its own text, font and size.
1999
+ */
1962
2000
  refreshAll() {
1963
- for (const layer of this.layers.getAll()) {
1964
- if (layer.meta.curve) this.refresh(layer.id);
1965
- }
2001
+ const visit = (layers) => {
2002
+ for (const layer of layers) {
2003
+ if (layer.meta.curve) this.refresh(layer.id);
2004
+ if (layer.children.length > 0) visit(layer.children);
2005
+ }
2006
+ };
2007
+ visit(this.layers.getAll());
1966
2008
  }
1967
2009
  /**
1968
2010
  * Puts every line's path on the object as one shape, and hooks per-line
@@ -1973,6 +2015,8 @@ var TextCurveManager = class {
1973
2015
  * outside the layer's box — where object caching clips it away.
1974
2016
  */
1975
2017
  attach(text, curves) {
2018
+ if (!authoredCaching.has(text)) authoredCaching.set(text, text.objectCaching);
2019
+ text.set({ objectCaching: false });
1976
2020
  const paths = curves.map(toFabricPath);
1977
2021
  const union = paths.length === 1 ? paths[0] : toFabricPath({ data: curves.map((c) => c.data).join(" "), length: 0 });
1978
2022
  text.set({
@@ -2035,6 +2079,11 @@ var TextCurveManager = class {
2035
2079
  }
2036
2080
  detach(text, authoredWidth) {
2037
2081
  this.unpatchLineMeasure(text);
2082
+ const caching = authoredCaching.get(text);
2083
+ if (caching !== void 0) {
2084
+ text.set({ objectCaching: caching });
2085
+ authoredCaching.delete(text);
2086
+ }
2038
2087
  text.set({ path: null, pathStartOffset: 0 });
2039
2088
  if (authoredWidth !== void 0 && authoredWidth > 0) text.set({ width: authoredWidth });
2040
2089
  }
@@ -4184,8 +4233,7 @@ var CanvasEditor = class {
4184
4233
  }
4185
4234
  const group = new Group7(objects);
4186
4235
  const grouped = this.layers.add("group", group, name);
4187
- for (const child of children) child.parentId = grouped.id;
4188
- grouped.children = children;
4236
+ this.layers.adoptChildren(grouped, children);
4189
4237
  this.layers.reorder(grouped.id, insertIndex);
4190
4238
  this.layers.select(grouped.id);
4191
4239
  this.history.save();
@@ -4794,6 +4842,7 @@ var CanvasEditor = class {
4794
4842
  this.crop.dispose();
4795
4843
  this.history.dispose();
4796
4844
  this.patterns.dispose();
4845
+ this.curves.dispose();
4797
4846
  this.events.removeAllListeners();
4798
4847
  this.canvas.dispose();
4799
4848
  }