@grida/svg-editor 1.0.0-alpha.21 → 1.0.0-alpha.23
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/{dom-Dw2SPHgc.d.mts → dom-D-ZJO9aK.d.mts} +17 -1
- package/dist/{dom-DHaTIObb.mjs → dom-DVxR7PNh.mjs} +98 -45
- package/dist/{dom-CuK0LFUY.js → dom-Disackua.js} +103 -44
- package/dist/{dom-CQkWJNrK.d.ts → dom-Dl56kUW5.d.ts} +17 -1
- package/dist/dom.d.mts +2 -2
- package/dist/dom.d.ts +2 -2
- package/dist/dom.js +2 -1
- package/dist/dom.mjs +2 -2
- package/dist/{editor-CJ3ROm0G.mjs → editor-DCDQl18y.mjs} +1 -1
- package/dist/{editor-BlByfVyF.js → editor-DFvojUwn.js} +1 -1
- package/dist/index.js +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{model-DVwjrVYp.js → model-HEKGO-56.js} +18 -10
- package/dist/{model-C6jCFK_p.mjs → model-zMPCOVAr.mjs} +18 -10
- package/dist/presets.d.mts +1 -1
- package/dist/presets.d.ts +1 -1
- package/dist/presets.js +2 -2
- package/dist/presets.mjs +1 -1
- package/dist/react.d.mts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +2 -2
- package/dist/react.mjs +2 -2
- package/package.json +5 -5
|
@@ -198,6 +198,22 @@ declare function project_point_through_ctm(px: number, py: number, ctm: {
|
|
|
198
198
|
e: number;
|
|
199
199
|
f: number;
|
|
200
200
|
}, container_offset: readonly [number, number]): [number, number];
|
|
201
|
+
/**
|
|
202
|
+
* The matrix form of {@link project_point_through_ctm}: the full
|
|
203
|
+
* `local → container-px` affine for a CTM + container offset, as a
|
|
204
|
+
* `cmath.Transform`. Use when handing the transform to a downstream projector
|
|
205
|
+
* (e.g. HUD chrome) instead of projecting a single point.
|
|
206
|
+
*
|
|
207
|
+
* Pure function, no DOM types.
|
|
208
|
+
*/
|
|
209
|
+
declare function ctm_to_container_transform(ctm: {
|
|
210
|
+
a: number;
|
|
211
|
+
b: number;
|
|
212
|
+
c: number;
|
|
213
|
+
d: number;
|
|
214
|
+
e: number;
|
|
215
|
+
f: number;
|
|
216
|
+
}, container_offset: readonly [number, number]): cmath.Transform;
|
|
201
217
|
/**
|
|
202
218
|
* Inverse of the CTM's linear part applied to a delta vector. Drops
|
|
203
219
|
* translation. Used to convert a HUD-reported container-space drag delta
|
|
@@ -236,4 +252,4 @@ declare function inverse_project_rect(rect: {
|
|
|
236
252
|
f: number;
|
|
237
253
|
}, offset: readonly [number, number]): cmath.Rectangle | null;
|
|
238
254
|
//#endregion
|
|
239
|
-
export {
|
|
255
|
+
export { ctm_to_container_transform as a, project_delta_inverse_ctm as c, SnapOptions as d, attach_dom_surface as i, project_point_through_ctm as l, DomSurfaceHandle as n, install_font_load_geometry_bump as o, DomSurfaceOptions as r, inverse_project_rect as s, AttentionScope as t, DEFAULT_SNAP_OPTIONS as u };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { S as is_text_input_focused, a as paint, c as hit_shape_svg, d as NudgeDwellWatcher, f as TranslateOrchestrator, h as transform, i as TOOL_CURSOR, l as RotateOrchestrator, m as group, n as insertions, o as ResizeOrchestrator, s as resize_pipeline, t as PathModel, w as default_nudge_handler, x as array_shallow_equal } from "./model-
|
|
1
|
+
import { S as is_text_input_focused, a as paint, c as hit_shape_svg, d as NudgeDwellWatcher, f as TranslateOrchestrator, h as transform, i as TOOL_CURSOR, l as RotateOrchestrator, m as group, n as insertions, o as ResizeOrchestrator, s as resize_pipeline, t as PathModel, w as default_nudge_handler, x as array_shallow_equal } from "./model-zMPCOVAr.mjs";
|
|
2
2
|
import cmath from "@grida/cmath";
|
|
3
3
|
import { svg_parse } from "@grida/svg/parse";
|
|
4
4
|
import { SVGShapes } from "@grida/svg/pathdata";
|
|
@@ -1222,44 +1222,32 @@ function create_attention_tracker(container) {
|
|
|
1222
1222
|
}
|
|
1223
1223
|
//#endregion
|
|
1224
1224
|
//#region src/text-surface.ts
|
|
1225
|
-
const SVG_NS = "http://www.w3.org/2000/svg";
|
|
1226
1225
|
const XML_NS = "http://www.w3.org/XML/1998/namespace";
|
|
1227
1226
|
var SvgTextSurface = class {
|
|
1228
|
-
|
|
1227
|
+
/**
|
|
1228
|
+
* @param textEl the live text element to drive.
|
|
1229
|
+
* @param sink receives the caret + selection geometry (local space) on
|
|
1230
|
+
* every change; the host projects + forwards it to the HUD. Called with
|
|
1231
|
+
* `null` on dispose so the host clears the chrome.
|
|
1232
|
+
*/
|
|
1233
|
+
constructor(textEl, sink) {
|
|
1229
1234
|
this.prevXmlSpace = void 0;
|
|
1230
1235
|
this.prevPointerEvents = void 0;
|
|
1236
|
+
this.caret = null;
|
|
1237
|
+
this.selection = null;
|
|
1231
1238
|
this.last_caret_idx = -1;
|
|
1232
1239
|
this.last_caret_visible = false;
|
|
1233
1240
|
this.last_sel_start = -1;
|
|
1234
1241
|
this.last_sel_end = -1;
|
|
1235
1242
|
this.textEl = textEl;
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
while (mountAnchor.parentElement instanceof SVGElement && (mountAnchor.localName === "tspan" || mountAnchor.localName === "textPath")) mountAnchor = mountAnchor.parentElement;
|
|
1239
|
-
const parent = mountAnchor.parentNode;
|
|
1240
|
-
if (!parent) throw new Error("text element has no parent");
|
|
1241
|
-
const computedWhitespace = ownerDoc.defaultView?.getComputedStyle(textEl).whiteSpace;
|
|
1243
|
+
this.sink = sink;
|
|
1244
|
+
const computedWhitespace = textEl.ownerDocument.defaultView?.getComputedStyle(textEl).whiteSpace;
|
|
1242
1245
|
if (!(computedWhitespace === "pre" || computedWhitespace === "pre-wrap" || computedWhitespace === "break-spaces")) {
|
|
1243
1246
|
this.prevXmlSpace = textEl.getAttributeNS(XML_NS, "space");
|
|
1244
1247
|
textEl.setAttributeNS(XML_NS, "xml:space", "preserve");
|
|
1245
1248
|
}
|
|
1246
1249
|
this.prevPointerEvents = textEl.getAttribute("pointer-events");
|
|
1247
1250
|
textEl.setAttribute("pointer-events", "bounding-box");
|
|
1248
|
-
const selection = ownerDoc.createElementNS(SVG_NS, "rect");
|
|
1249
|
-
selection.setAttribute("fill", "#2563eb");
|
|
1250
|
-
selection.setAttribute("fill-opacity", "0.25");
|
|
1251
|
-
selection.setAttribute("pointer-events", "none");
|
|
1252
|
-
selection.setAttribute("data-svg-text-edit-selection", "");
|
|
1253
|
-
selection.style.display = "none";
|
|
1254
|
-
parent.insertBefore(selection, mountAnchor);
|
|
1255
|
-
this.selectionRect = selection;
|
|
1256
|
-
const caret = ownerDoc.createElementNS(SVG_NS, "rect");
|
|
1257
|
-
caret.setAttribute("fill", "#2563eb");
|
|
1258
|
-
caret.setAttribute("pointer-events", "none");
|
|
1259
|
-
caret.setAttribute("data-svg-text-edit-caret", "");
|
|
1260
|
-
caret.style.display = "none";
|
|
1261
|
-
parent.insertBefore(caret, mountAnchor.nextSibling);
|
|
1262
|
-
this.caretRect = caret;
|
|
1263
1251
|
}
|
|
1264
1252
|
setText(text) {
|
|
1265
1253
|
if (this.textEl.textContent !== text) this.textEl.textContent = text;
|
|
@@ -1268,38 +1256,43 @@ var SvgTextSurface = class {
|
|
|
1268
1256
|
if (index === this.last_caret_idx && visible === this.last_caret_visible) return;
|
|
1269
1257
|
this.last_caret_idx = index;
|
|
1270
1258
|
this.last_caret_visible = visible;
|
|
1271
|
-
if (!visible) {
|
|
1272
|
-
this.caretRect.style.display = "none";
|
|
1273
|
-
return;
|
|
1274
|
-
}
|
|
1275
1259
|
const m = this.metrics();
|
|
1276
1260
|
const x = this.charX(index);
|
|
1277
|
-
this.
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1261
|
+
this.caret = {
|
|
1262
|
+
top: [x, m.top],
|
|
1263
|
+
bottom: [x, m.top + m.height],
|
|
1264
|
+
visible
|
|
1265
|
+
};
|
|
1266
|
+
this.emit();
|
|
1282
1267
|
}
|
|
1283
1268
|
setSelection(start, end) {
|
|
1284
1269
|
if (start === this.last_sel_start && end === this.last_sel_end) return;
|
|
1285
1270
|
this.last_sel_start = start;
|
|
1286
1271
|
this.last_sel_end = end;
|
|
1287
1272
|
if (start === end) {
|
|
1288
|
-
this.
|
|
1273
|
+
this.selection = null;
|
|
1274
|
+
this.emit();
|
|
1289
1275
|
return;
|
|
1290
1276
|
}
|
|
1291
1277
|
const m = this.metrics();
|
|
1292
1278
|
const x1 = this.charX(start);
|
|
1293
1279
|
const x2 = this.charX(end);
|
|
1294
|
-
this.
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1280
|
+
this.selection = {
|
|
1281
|
+
x: Math.min(x1, x2),
|
|
1282
|
+
y: m.top,
|
|
1283
|
+
width: Math.abs(x2 - x1),
|
|
1284
|
+
height: m.height
|
|
1285
|
+
};
|
|
1286
|
+
this.emit();
|
|
1287
|
+
}
|
|
1288
|
+
emit() {
|
|
1289
|
+
this.sink({
|
|
1290
|
+
caret: this.caret,
|
|
1291
|
+
selection: this.selection
|
|
1292
|
+
});
|
|
1299
1293
|
}
|
|
1300
1294
|
dispose(keepEditMutations = false) {
|
|
1301
|
-
this.
|
|
1302
|
-
this.selectionRect.remove();
|
|
1295
|
+
this.sink(null);
|
|
1303
1296
|
if (this.prevXmlSpace !== void 0 && !keepEditMutations) if (this.prevXmlSpace === null) this.textEl.removeAttributeNS(XML_NS, "space");
|
|
1304
1297
|
else this.textEl.setAttributeNS(XML_NS, "xml:space", this.prevXmlSpace);
|
|
1305
1298
|
if (this.prevPointerEvents !== void 0) if (this.prevPointerEvents === null) this.textEl.removeAttribute("pointer-events");
|
|
@@ -1923,6 +1916,7 @@ var DomSurface = class DomSurface {
|
|
|
1923
1916
|
this.text_edit = null;
|
|
1924
1917
|
this.text_edit_target = null;
|
|
1925
1918
|
this.text_edit_original = "";
|
|
1919
|
+
this.text_edit_geom = null;
|
|
1926
1920
|
this.pending_text_insert = null;
|
|
1927
1921
|
this.vector_edit = null;
|
|
1928
1922
|
this.point_snap_guide = void 0;
|
|
@@ -2067,6 +2061,7 @@ var DomSurface = class DomSurface {
|
|
|
2067
2061
|
this.apply_camera_transform();
|
|
2068
2062
|
this.hud.setPixelGridTransform(this.camera.transform);
|
|
2069
2063
|
this.sync_surface_selection();
|
|
2064
|
+
if (this.text_edit_geom) this.push_text_edit_chrome(this.text_edit_geom);
|
|
2070
2065
|
this.redraw();
|
|
2071
2066
|
}));
|
|
2072
2067
|
this.render();
|
|
@@ -3192,7 +3187,7 @@ var DomSurface = class DomSurface {
|
|
|
3192
3187
|
mods: next
|
|
3193
3188
|
});
|
|
3194
3189
|
if ((prev.shift !== next.shift || prev.alt !== next.alt) && this.translate_orchestrator.has_active_session()) this.translate_orchestrator.redrive_modifiers(this.current_translate_modifiers());
|
|
3195
|
-
if (prev.shift !== next.shift && this.resize_orchestrator.has_active_session()) this.resize_orchestrator.redrive_modifiers(this.current_resize_modifiers());
|
|
3190
|
+
if ((prev.shift !== next.shift || prev.alt !== next.alt) && this.resize_orchestrator.has_active_session()) this.resize_orchestrator.redrive_modifiers(this.current_resize_modifiers());
|
|
3196
3191
|
if (prev.shift !== next.shift && this.rotate_orchestrator.has_active_session()) this.rotate_orchestrator.redrive_modifiers(this.current_rotate_modifiers());
|
|
3197
3192
|
let cursor_changed = response.cursorChanged;
|
|
3198
3193
|
let hover_changed = response.hoverChanged;
|
|
@@ -3690,8 +3685,10 @@ var DomSurface = class DomSurface {
|
|
|
3690
3685
|
/** Snapshot of HUD modifier state mapped to `ResizeModifiers`. Same
|
|
3691
3686
|
* pull-at-consume discipline as `current_translate_modifiers`. */
|
|
3692
3687
|
current_resize_modifiers() {
|
|
3688
|
+
const mods = this.hud.modifiers();
|
|
3693
3689
|
return {
|
|
3694
|
-
aspect_lock:
|
|
3690
|
+
aspect_lock: mods.shift ? "uniform" : "off",
|
|
3691
|
+
from_center: mods.alt,
|
|
3695
3692
|
force_disable_snap: false
|
|
3696
3693
|
};
|
|
3697
3694
|
}
|
|
@@ -4072,7 +4069,10 @@ var DomSurface = class DomSurface {
|
|
|
4072
4069
|
this.sync_surface_selection();
|
|
4073
4070
|
this.sync_cursor();
|
|
4074
4071
|
this.redraw();
|
|
4075
|
-
const text_surface = new SvgTextSurface(this.element_index.get(id) ?? el)
|
|
4072
|
+
const text_surface = new SvgTextSurface(this.element_index.get(id) ?? el, (geom) => {
|
|
4073
|
+
this.push_text_edit_chrome(geom);
|
|
4074
|
+
this.request_redraw();
|
|
4075
|
+
});
|
|
4076
4076
|
const is_mac = typeof navigator !== "undefined" && /Mac|iPod|iPhone|iPad/.test(navigator.userAgent);
|
|
4077
4077
|
let settled = false;
|
|
4078
4078
|
this.text_edit = createTextEditor({
|
|
@@ -4120,11 +4120,45 @@ var DomSurface = class DomSurface {
|
|
|
4120
4120
|
this.render();
|
|
4121
4121
|
this.sync_surface_selection();
|
|
4122
4122
|
this.sync_cursor();
|
|
4123
|
+
this.push_text_edit_chrome(null);
|
|
4123
4124
|
this.redraw();
|
|
4124
4125
|
this.text_edit = null;
|
|
4125
4126
|
this.text_edit_target = null;
|
|
4126
4127
|
}
|
|
4127
4128
|
/**
|
|
4129
|
+
* Project the active session's text-edit geometry (LOCAL svg user-space) and
|
|
4130
|
+
* push it to the HUD as text-edit chrome (caret + selection), or clear it on
|
|
4131
|
+
* `null`. The local→container-px transform comes from the live text
|
|
4132
|
+
* element's `getScreenCTM` (which folds in the camera's CSS transform on the
|
|
4133
|
+
* SVG root) minus the container offset — the same projection convention
|
|
4134
|
+
* `vector_of` / `container_box` use. The HUD keeps its own transform at
|
|
4135
|
+
* identity, so this per-chrome transform is the whole projection. Does NOT
|
|
4136
|
+
* redraw — callers own that.
|
|
4137
|
+
*/
|
|
4138
|
+
push_text_edit_chrome(geom) {
|
|
4139
|
+
this.text_edit_geom = geom;
|
|
4140
|
+
if (!geom) {
|
|
4141
|
+
this.hud.setTextEditChrome(null);
|
|
4142
|
+
return;
|
|
4143
|
+
}
|
|
4144
|
+
const ctm = (this.text_edit_target ? this.element_index.get(this.text_edit_target) : void 0)?.getScreenCTM?.() ?? null;
|
|
4145
|
+
if (!ctm) {
|
|
4146
|
+
this.hud.setTextEditChrome(null);
|
|
4147
|
+
return;
|
|
4148
|
+
}
|
|
4149
|
+
const input = {
|
|
4150
|
+
transform: ctm_to_container_transform(ctm, this.container_offset()),
|
|
4151
|
+
caret: geom.caret ? {
|
|
4152
|
+
top: geom.caret.top,
|
|
4153
|
+
bottom: geom.caret.bottom
|
|
4154
|
+
} : void 0,
|
|
4155
|
+
caretVisible: geom.caret?.visible ?? false,
|
|
4156
|
+
selectionRects: geom.selection ? [geom.selection] : void 0,
|
|
4157
|
+
style: { caretColor: "#000000" }
|
|
4158
|
+
};
|
|
4159
|
+
this.hud.setTextEditChrome(input);
|
|
4160
|
+
}
|
|
4161
|
+
/**
|
|
4128
4162
|
* Realize the result of a text content-edit session and exit. `result`
|
|
4129
4163
|
* is the text that should remain — the typed text on commit, the original
|
|
4130
4164
|
* on cancel. Implements the empty-equals-delete rule (design:
|
|
@@ -4943,6 +4977,25 @@ function project_point_through_ctm(px, py, ctm, container_offset) {
|
|
|
4943
4977
|
return [sx + container_offset[0], sy + container_offset[1]];
|
|
4944
4978
|
}
|
|
4945
4979
|
/**
|
|
4980
|
+
* The matrix form of {@link project_point_through_ctm}: the full
|
|
4981
|
+
* `local → container-px` affine for a CTM + container offset, as a
|
|
4982
|
+
* `cmath.Transform`. Use when handing the transform to a downstream projector
|
|
4983
|
+
* (e.g. HUD chrome) instead of projecting a single point.
|
|
4984
|
+
*
|
|
4985
|
+
* Pure function, no DOM types.
|
|
4986
|
+
*/
|
|
4987
|
+
function ctm_to_container_transform(ctm, container_offset) {
|
|
4988
|
+
return [[
|
|
4989
|
+
ctm.a,
|
|
4990
|
+
ctm.c,
|
|
4991
|
+
ctm.e + container_offset[0]
|
|
4992
|
+
], [
|
|
4993
|
+
ctm.b,
|
|
4994
|
+
ctm.d,
|
|
4995
|
+
ctm.f + container_offset[1]
|
|
4996
|
+
]];
|
|
4997
|
+
}
|
|
4998
|
+
/**
|
|
4946
4999
|
* Inverse of the CTM's linear part applied to a delta vector. Drops
|
|
4947
5000
|
* translation. Used to convert a HUD-reported container-space drag delta
|
|
4948
5001
|
* back to the path's local coord space for `PathModel.translateVertices`.
|
|
@@ -5218,4 +5271,4 @@ var SvgHitShapeDriver = class {
|
|
|
5218
5271
|
}
|
|
5219
5272
|
};
|
|
5220
5273
|
//#endregion
|
|
5221
|
-
export {
|
|
5274
|
+
export { project_delta_inverse_ctm as a, DEFAULT_SNAP_OPTIONS as c, inverse_project_rect as i, MemoizedGeometryProvider as l, ctm_to_container_transform as n, project_point_through_ctm as o, install_font_load_geometry_bump as r, Gestures as s, attach_dom_surface as t, Camera as u };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_model = require("./model-
|
|
1
|
+
const require_model = require("./model-HEKGO-56.js");
|
|
2
2
|
let _grida_cmath = require("@grida/cmath");
|
|
3
3
|
_grida_cmath = require_model.__toESM(_grida_cmath);
|
|
4
4
|
let _grida_svg_parse = require("@grida/svg/parse");
|
|
@@ -1224,44 +1224,32 @@ function create_attention_tracker(container) {
|
|
|
1224
1224
|
}
|
|
1225
1225
|
//#endregion
|
|
1226
1226
|
//#region src/text-surface.ts
|
|
1227
|
-
const SVG_NS = "http://www.w3.org/2000/svg";
|
|
1228
1227
|
const XML_NS = "http://www.w3.org/XML/1998/namespace";
|
|
1229
1228
|
var SvgTextSurface = class {
|
|
1230
|
-
|
|
1229
|
+
/**
|
|
1230
|
+
* @param textEl the live text element to drive.
|
|
1231
|
+
* @param sink receives the caret + selection geometry (local space) on
|
|
1232
|
+
* every change; the host projects + forwards it to the HUD. Called with
|
|
1233
|
+
* `null` on dispose so the host clears the chrome.
|
|
1234
|
+
*/
|
|
1235
|
+
constructor(textEl, sink) {
|
|
1231
1236
|
this.prevXmlSpace = void 0;
|
|
1232
1237
|
this.prevPointerEvents = void 0;
|
|
1238
|
+
this.caret = null;
|
|
1239
|
+
this.selection = null;
|
|
1233
1240
|
this.last_caret_idx = -1;
|
|
1234
1241
|
this.last_caret_visible = false;
|
|
1235
1242
|
this.last_sel_start = -1;
|
|
1236
1243
|
this.last_sel_end = -1;
|
|
1237
1244
|
this.textEl = textEl;
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
while (mountAnchor.parentElement instanceof SVGElement && (mountAnchor.localName === "tspan" || mountAnchor.localName === "textPath")) mountAnchor = mountAnchor.parentElement;
|
|
1241
|
-
const parent = mountAnchor.parentNode;
|
|
1242
|
-
if (!parent) throw new Error("text element has no parent");
|
|
1243
|
-
const computedWhitespace = ownerDoc.defaultView?.getComputedStyle(textEl).whiteSpace;
|
|
1245
|
+
this.sink = sink;
|
|
1246
|
+
const computedWhitespace = textEl.ownerDocument.defaultView?.getComputedStyle(textEl).whiteSpace;
|
|
1244
1247
|
if (!(computedWhitespace === "pre" || computedWhitespace === "pre-wrap" || computedWhitespace === "break-spaces")) {
|
|
1245
1248
|
this.prevXmlSpace = textEl.getAttributeNS(XML_NS, "space");
|
|
1246
1249
|
textEl.setAttributeNS(XML_NS, "xml:space", "preserve");
|
|
1247
1250
|
}
|
|
1248
1251
|
this.prevPointerEvents = textEl.getAttribute("pointer-events");
|
|
1249
1252
|
textEl.setAttribute("pointer-events", "bounding-box");
|
|
1250
|
-
const selection = ownerDoc.createElementNS(SVG_NS, "rect");
|
|
1251
|
-
selection.setAttribute("fill", "#2563eb");
|
|
1252
|
-
selection.setAttribute("fill-opacity", "0.25");
|
|
1253
|
-
selection.setAttribute("pointer-events", "none");
|
|
1254
|
-
selection.setAttribute("data-svg-text-edit-selection", "");
|
|
1255
|
-
selection.style.display = "none";
|
|
1256
|
-
parent.insertBefore(selection, mountAnchor);
|
|
1257
|
-
this.selectionRect = selection;
|
|
1258
|
-
const caret = ownerDoc.createElementNS(SVG_NS, "rect");
|
|
1259
|
-
caret.setAttribute("fill", "#2563eb");
|
|
1260
|
-
caret.setAttribute("pointer-events", "none");
|
|
1261
|
-
caret.setAttribute("data-svg-text-edit-caret", "");
|
|
1262
|
-
caret.style.display = "none";
|
|
1263
|
-
parent.insertBefore(caret, mountAnchor.nextSibling);
|
|
1264
|
-
this.caretRect = caret;
|
|
1265
1253
|
}
|
|
1266
1254
|
setText(text) {
|
|
1267
1255
|
if (this.textEl.textContent !== text) this.textEl.textContent = text;
|
|
@@ -1270,38 +1258,43 @@ var SvgTextSurface = class {
|
|
|
1270
1258
|
if (index === this.last_caret_idx && visible === this.last_caret_visible) return;
|
|
1271
1259
|
this.last_caret_idx = index;
|
|
1272
1260
|
this.last_caret_visible = visible;
|
|
1273
|
-
if (!visible) {
|
|
1274
|
-
this.caretRect.style.display = "none";
|
|
1275
|
-
return;
|
|
1276
|
-
}
|
|
1277
1261
|
const m = this.metrics();
|
|
1278
1262
|
const x = this.charX(index);
|
|
1279
|
-
this.
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1263
|
+
this.caret = {
|
|
1264
|
+
top: [x, m.top],
|
|
1265
|
+
bottom: [x, m.top + m.height],
|
|
1266
|
+
visible
|
|
1267
|
+
};
|
|
1268
|
+
this.emit();
|
|
1284
1269
|
}
|
|
1285
1270
|
setSelection(start, end) {
|
|
1286
1271
|
if (start === this.last_sel_start && end === this.last_sel_end) return;
|
|
1287
1272
|
this.last_sel_start = start;
|
|
1288
1273
|
this.last_sel_end = end;
|
|
1289
1274
|
if (start === end) {
|
|
1290
|
-
this.
|
|
1275
|
+
this.selection = null;
|
|
1276
|
+
this.emit();
|
|
1291
1277
|
return;
|
|
1292
1278
|
}
|
|
1293
1279
|
const m = this.metrics();
|
|
1294
1280
|
const x1 = this.charX(start);
|
|
1295
1281
|
const x2 = this.charX(end);
|
|
1296
|
-
this.
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1282
|
+
this.selection = {
|
|
1283
|
+
x: Math.min(x1, x2),
|
|
1284
|
+
y: m.top,
|
|
1285
|
+
width: Math.abs(x2 - x1),
|
|
1286
|
+
height: m.height
|
|
1287
|
+
};
|
|
1288
|
+
this.emit();
|
|
1289
|
+
}
|
|
1290
|
+
emit() {
|
|
1291
|
+
this.sink({
|
|
1292
|
+
caret: this.caret,
|
|
1293
|
+
selection: this.selection
|
|
1294
|
+
});
|
|
1301
1295
|
}
|
|
1302
1296
|
dispose(keepEditMutations = false) {
|
|
1303
|
-
this.
|
|
1304
|
-
this.selectionRect.remove();
|
|
1297
|
+
this.sink(null);
|
|
1305
1298
|
if (this.prevXmlSpace !== void 0 && !keepEditMutations) if (this.prevXmlSpace === null) this.textEl.removeAttributeNS(XML_NS, "space");
|
|
1306
1299
|
else this.textEl.setAttributeNS(XML_NS, "xml:space", this.prevXmlSpace);
|
|
1307
1300
|
if (this.prevPointerEvents !== void 0) if (this.prevPointerEvents === null) this.textEl.removeAttribute("pointer-events");
|
|
@@ -1925,6 +1918,7 @@ var DomSurface = class DomSurface {
|
|
|
1925
1918
|
this.text_edit = null;
|
|
1926
1919
|
this.text_edit_target = null;
|
|
1927
1920
|
this.text_edit_original = "";
|
|
1921
|
+
this.text_edit_geom = null;
|
|
1928
1922
|
this.pending_text_insert = null;
|
|
1929
1923
|
this.vector_edit = null;
|
|
1930
1924
|
this.point_snap_guide = void 0;
|
|
@@ -2069,6 +2063,7 @@ var DomSurface = class DomSurface {
|
|
|
2069
2063
|
this.apply_camera_transform();
|
|
2070
2064
|
this.hud.setPixelGridTransform(this.camera.transform);
|
|
2071
2065
|
this.sync_surface_selection();
|
|
2066
|
+
if (this.text_edit_geom) this.push_text_edit_chrome(this.text_edit_geom);
|
|
2072
2067
|
this.redraw();
|
|
2073
2068
|
}));
|
|
2074
2069
|
this.render();
|
|
@@ -3194,7 +3189,7 @@ var DomSurface = class DomSurface {
|
|
|
3194
3189
|
mods: next
|
|
3195
3190
|
});
|
|
3196
3191
|
if ((prev.shift !== next.shift || prev.alt !== next.alt) && this.translate_orchestrator.has_active_session()) this.translate_orchestrator.redrive_modifiers(this.current_translate_modifiers());
|
|
3197
|
-
if (prev.shift !== next.shift && this.resize_orchestrator.has_active_session()) this.resize_orchestrator.redrive_modifiers(this.current_resize_modifiers());
|
|
3192
|
+
if ((prev.shift !== next.shift || prev.alt !== next.alt) && this.resize_orchestrator.has_active_session()) this.resize_orchestrator.redrive_modifiers(this.current_resize_modifiers());
|
|
3198
3193
|
if (prev.shift !== next.shift && this.rotate_orchestrator.has_active_session()) this.rotate_orchestrator.redrive_modifiers(this.current_rotate_modifiers());
|
|
3199
3194
|
let cursor_changed = response.cursorChanged;
|
|
3200
3195
|
let hover_changed = response.hoverChanged;
|
|
@@ -3692,8 +3687,10 @@ var DomSurface = class DomSurface {
|
|
|
3692
3687
|
/** Snapshot of HUD modifier state mapped to `ResizeModifiers`. Same
|
|
3693
3688
|
* pull-at-consume discipline as `current_translate_modifiers`. */
|
|
3694
3689
|
current_resize_modifiers() {
|
|
3690
|
+
const mods = this.hud.modifiers();
|
|
3695
3691
|
return {
|
|
3696
|
-
aspect_lock:
|
|
3692
|
+
aspect_lock: mods.shift ? "uniform" : "off",
|
|
3693
|
+
from_center: mods.alt,
|
|
3697
3694
|
force_disable_snap: false
|
|
3698
3695
|
};
|
|
3699
3696
|
}
|
|
@@ -4074,7 +4071,10 @@ var DomSurface = class DomSurface {
|
|
|
4074
4071
|
this.sync_surface_selection();
|
|
4075
4072
|
this.sync_cursor();
|
|
4076
4073
|
this.redraw();
|
|
4077
|
-
const text_surface = new SvgTextSurface(this.element_index.get(id) ?? el)
|
|
4074
|
+
const text_surface = new SvgTextSurface(this.element_index.get(id) ?? el, (geom) => {
|
|
4075
|
+
this.push_text_edit_chrome(geom);
|
|
4076
|
+
this.request_redraw();
|
|
4077
|
+
});
|
|
4078
4078
|
const is_mac = typeof navigator !== "undefined" && /Mac|iPod|iPhone|iPad/.test(navigator.userAgent);
|
|
4079
4079
|
let settled = false;
|
|
4080
4080
|
this.text_edit = (0, _grida_text_editor_dom.createTextEditor)({
|
|
@@ -4122,11 +4122,45 @@ var DomSurface = class DomSurface {
|
|
|
4122
4122
|
this.render();
|
|
4123
4123
|
this.sync_surface_selection();
|
|
4124
4124
|
this.sync_cursor();
|
|
4125
|
+
this.push_text_edit_chrome(null);
|
|
4125
4126
|
this.redraw();
|
|
4126
4127
|
this.text_edit = null;
|
|
4127
4128
|
this.text_edit_target = null;
|
|
4128
4129
|
}
|
|
4129
4130
|
/**
|
|
4131
|
+
* Project the active session's text-edit geometry (LOCAL svg user-space) and
|
|
4132
|
+
* push it to the HUD as text-edit chrome (caret + selection), or clear it on
|
|
4133
|
+
* `null`. The local→container-px transform comes from the live text
|
|
4134
|
+
* element's `getScreenCTM` (which folds in the camera's CSS transform on the
|
|
4135
|
+
* SVG root) minus the container offset — the same projection convention
|
|
4136
|
+
* `vector_of` / `container_box` use. The HUD keeps its own transform at
|
|
4137
|
+
* identity, so this per-chrome transform is the whole projection. Does NOT
|
|
4138
|
+
* redraw — callers own that.
|
|
4139
|
+
*/
|
|
4140
|
+
push_text_edit_chrome(geom) {
|
|
4141
|
+
this.text_edit_geom = geom;
|
|
4142
|
+
if (!geom) {
|
|
4143
|
+
this.hud.setTextEditChrome(null);
|
|
4144
|
+
return;
|
|
4145
|
+
}
|
|
4146
|
+
const ctm = (this.text_edit_target ? this.element_index.get(this.text_edit_target) : void 0)?.getScreenCTM?.() ?? null;
|
|
4147
|
+
if (!ctm) {
|
|
4148
|
+
this.hud.setTextEditChrome(null);
|
|
4149
|
+
return;
|
|
4150
|
+
}
|
|
4151
|
+
const input = {
|
|
4152
|
+
transform: ctm_to_container_transform(ctm, this.container_offset()),
|
|
4153
|
+
caret: geom.caret ? {
|
|
4154
|
+
top: geom.caret.top,
|
|
4155
|
+
bottom: geom.caret.bottom
|
|
4156
|
+
} : void 0,
|
|
4157
|
+
caretVisible: geom.caret?.visible ?? false,
|
|
4158
|
+
selectionRects: geom.selection ? [geom.selection] : void 0,
|
|
4159
|
+
style: { caretColor: "#000000" }
|
|
4160
|
+
};
|
|
4161
|
+
this.hud.setTextEditChrome(input);
|
|
4162
|
+
}
|
|
4163
|
+
/**
|
|
4130
4164
|
* Realize the result of a text content-edit session and exit. `result`
|
|
4131
4165
|
* is the text that should remain — the typed text on commit, the original
|
|
4132
4166
|
* on cancel. Implements the empty-equals-delete rule (design:
|
|
@@ -4945,6 +4979,25 @@ function project_point_through_ctm(px, py, ctm, container_offset) {
|
|
|
4945
4979
|
return [sx + container_offset[0], sy + container_offset[1]];
|
|
4946
4980
|
}
|
|
4947
4981
|
/**
|
|
4982
|
+
* The matrix form of {@link project_point_through_ctm}: the full
|
|
4983
|
+
* `local → container-px` affine for a CTM + container offset, as a
|
|
4984
|
+
* `cmath.Transform`. Use when handing the transform to a downstream projector
|
|
4985
|
+
* (e.g. HUD chrome) instead of projecting a single point.
|
|
4986
|
+
*
|
|
4987
|
+
* Pure function, no DOM types.
|
|
4988
|
+
*/
|
|
4989
|
+
function ctm_to_container_transform(ctm, container_offset) {
|
|
4990
|
+
return [[
|
|
4991
|
+
ctm.a,
|
|
4992
|
+
ctm.c,
|
|
4993
|
+
ctm.e + container_offset[0]
|
|
4994
|
+
], [
|
|
4995
|
+
ctm.b,
|
|
4996
|
+
ctm.d,
|
|
4997
|
+
ctm.f + container_offset[1]
|
|
4998
|
+
]];
|
|
4999
|
+
}
|
|
5000
|
+
/**
|
|
4948
5001
|
* Inverse of the CTM's linear part applied to a delta vector. Drops
|
|
4949
5002
|
* translation. Used to convert a HUD-reported container-space drag delta
|
|
4950
5003
|
* back to the path's local coord space for `PathModel.translateVertices`.
|
|
@@ -5250,6 +5303,12 @@ Object.defineProperty(exports, "attach_dom_surface", {
|
|
|
5250
5303
|
return attach_dom_surface;
|
|
5251
5304
|
}
|
|
5252
5305
|
});
|
|
5306
|
+
Object.defineProperty(exports, "ctm_to_container_transform", {
|
|
5307
|
+
enumerable: true,
|
|
5308
|
+
get: function() {
|
|
5309
|
+
return ctm_to_container_transform;
|
|
5310
|
+
}
|
|
5311
|
+
});
|
|
5253
5312
|
Object.defineProperty(exports, "install_font_load_geometry_bump", {
|
|
5254
5313
|
enumerable: true,
|
|
5255
5314
|
get: function() {
|
|
@@ -196,6 +196,22 @@ declare function project_point_through_ctm(px: number, py: number, ctm: {
|
|
|
196
196
|
e: number;
|
|
197
197
|
f: number;
|
|
198
198
|
}, container_offset: readonly [number, number]): [number, number];
|
|
199
|
+
/**
|
|
200
|
+
* The matrix form of {@link project_point_through_ctm}: the full
|
|
201
|
+
* `local → container-px` affine for a CTM + container offset, as a
|
|
202
|
+
* `cmath.Transform`. Use when handing the transform to a downstream projector
|
|
203
|
+
* (e.g. HUD chrome) instead of projecting a single point.
|
|
204
|
+
*
|
|
205
|
+
* Pure function, no DOM types.
|
|
206
|
+
*/
|
|
207
|
+
declare function ctm_to_container_transform(ctm: {
|
|
208
|
+
a: number;
|
|
209
|
+
b: number;
|
|
210
|
+
c: number;
|
|
211
|
+
d: number;
|
|
212
|
+
e: number;
|
|
213
|
+
f: number;
|
|
214
|
+
}, container_offset: readonly [number, number]): cmath.Transform;
|
|
199
215
|
/**
|
|
200
216
|
* Inverse of the CTM's linear part applied to a delta vector. Drops
|
|
201
217
|
* translation. Used to convert a HUD-reported container-space drag delta
|
|
@@ -234,4 +250,4 @@ declare function inverse_project_rect(rect: {
|
|
|
234
250
|
f: number;
|
|
235
251
|
}, offset: readonly [number, number]): cmath.Rectangle | null;
|
|
236
252
|
//#endregion
|
|
237
|
-
export {
|
|
253
|
+
export { ctm_to_container_transform as a, project_delta_inverse_ctm as c, SnapOptions as d, attach_dom_surface as i, project_point_through_ctm as l, DomSurfaceHandle as n, install_font_load_geometry_bump as o, DomSurfaceOptions as r, inverse_project_rect as s, AttentionScope as t, DEFAULT_SNAP_OPTIONS as u };
|
package/dist/dom.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { C as BoundsResolver, E as CameraOptions, T as CameraConstraints, d as GestureContext, f as GestureId, g as MemoizedGeometryProvider, h as GeometrySignals, i as DomComputedResolver, m as GeometryProvider, p as Gestures, r as DomComputedPaint, u as GestureBinding, w as Camera } from "./editor-CcW4BVth.mjs";
|
|
2
|
-
import { a as
|
|
3
|
-
export { AttentionScope, type BoundsResolver, Camera, type CameraConstraints, type CameraOptions, DEFAULT_SNAP_OPTIONS, type DomComputedPaint, type DomComputedResolver, DomSurfaceHandle, DomSurfaceOptions, type GeometryProvider, type GeometrySignals, type GestureBinding, type GestureContext, type GestureId, Gestures, MemoizedGeometryProvider, type SnapOptions, attach_dom_surface, install_font_load_geometry_bump, inverse_project_rect, project_delta_inverse_ctm, project_point_through_ctm };
|
|
2
|
+
import { a as ctm_to_container_transform, c as project_delta_inverse_ctm, d as SnapOptions, i as attach_dom_surface, l as project_point_through_ctm, n as DomSurfaceHandle, o as install_font_load_geometry_bump, r as DomSurfaceOptions, s as inverse_project_rect, t as AttentionScope, u as DEFAULT_SNAP_OPTIONS } from "./dom-D-ZJO9aK.mjs";
|
|
3
|
+
export { AttentionScope, type BoundsResolver, Camera, type CameraConstraints, type CameraOptions, DEFAULT_SNAP_OPTIONS, type DomComputedPaint, type DomComputedResolver, DomSurfaceHandle, DomSurfaceOptions, type GeometryProvider, type GeometrySignals, type GestureBinding, type GestureContext, type GestureId, Gestures, MemoizedGeometryProvider, type SnapOptions, attach_dom_surface, ctm_to_container_transform, install_font_load_geometry_bump, inverse_project_rect, project_delta_inverse_ctm, project_point_through_ctm };
|
package/dist/dom.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { C as BoundsResolver, E as CameraOptions, T as CameraConstraints, d as GestureContext, f as GestureId, g as MemoizedGeometryProvider, h as GeometrySignals, i as DomComputedResolver, m as GeometryProvider, p as Gestures, r as DomComputedPaint, u as GestureBinding, w as Camera } from "./editor-CxqRhhzP.js";
|
|
2
|
-
import { a as
|
|
3
|
-
export { AttentionScope, type BoundsResolver, Camera, type CameraConstraints, type CameraOptions, DEFAULT_SNAP_OPTIONS, type DomComputedPaint, type DomComputedResolver, DomSurfaceHandle, DomSurfaceOptions, type GeometryProvider, type GeometrySignals, type GestureBinding, type GestureContext, type GestureId, Gestures, MemoizedGeometryProvider, type SnapOptions, attach_dom_surface, install_font_load_geometry_bump, inverse_project_rect, project_delta_inverse_ctm, project_point_through_ctm };
|
|
2
|
+
import { a as ctm_to_container_transform, c as project_delta_inverse_ctm, d as SnapOptions, i as attach_dom_surface, l as project_point_through_ctm, n as DomSurfaceHandle, o as install_font_load_geometry_bump, r as DomSurfaceOptions, s as inverse_project_rect, t as AttentionScope, u as DEFAULT_SNAP_OPTIONS } from "./dom-Dl56kUW5.js";
|
|
3
|
+
export { AttentionScope, type BoundsResolver, Camera, type CameraConstraints, type CameraOptions, DEFAULT_SNAP_OPTIONS, type DomComputedPaint, type DomComputedResolver, DomSurfaceHandle, DomSurfaceOptions, type GeometryProvider, type GeometrySignals, type GestureBinding, type GestureContext, type GestureId, Gestures, MemoizedGeometryProvider, type SnapOptions, attach_dom_surface, ctm_to_container_transform, install_font_load_geometry_bump, inverse_project_rect, project_delta_inverse_ctm, project_point_through_ctm };
|
package/dist/dom.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_dom = require("./dom-
|
|
2
|
+
const require_dom = require("./dom-Disackua.js");
|
|
3
3
|
exports.Camera = require_dom.Camera;
|
|
4
4
|
exports.DEFAULT_SNAP_OPTIONS = require_dom.DEFAULT_SNAP_OPTIONS;
|
|
5
5
|
exports.Gestures = require_dom.Gestures;
|
|
6
6
|
exports.MemoizedGeometryProvider = require_dom.MemoizedGeometryProvider;
|
|
7
7
|
exports.attach_dom_surface = require_dom.attach_dom_surface;
|
|
8
|
+
exports.ctm_to_container_transform = require_dom.ctm_to_container_transform;
|
|
8
9
|
exports.install_font_load_geometry_bump = require_dom.install_font_load_geometry_bump;
|
|
9
10
|
exports.inverse_project_rect = require_dom.inverse_project_rect;
|
|
10
11
|
exports.project_delta_inverse_ctm = require_dom.project_delta_inverse_ctm;
|
package/dist/dom.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
export { Camera, DEFAULT_SNAP_OPTIONS, Gestures, MemoizedGeometryProvider, attach_dom_surface, install_font_load_geometry_bump, inverse_project_rect, project_delta_inverse_ctm, project_point_through_ctm };
|
|
1
|
+
import { a as project_delta_inverse_ctm, c as DEFAULT_SNAP_OPTIONS, i as inverse_project_rect, l as MemoizedGeometryProvider, n as ctm_to_container_transform, o as project_point_through_ctm, r as install_font_load_geometry_bump, s as Gestures, t as attach_dom_surface, u as Camera } from "./dom-DVxR7PNh.mjs";
|
|
2
|
+
export { Camera, DEFAULT_SNAP_OPTIONS, Gestures, MemoizedGeometryProvider, attach_dom_surface, ctm_to_container_transform, install_font_load_geometry_bump, inverse_project_rect, project_delta_inverse_ctm, project_point_through_ctm };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as TOOL_SET, S as is_text_input_focused, T as registerDefaultCommands, _ as SVG_NS, a as paint, b as XMLNS_NS, g as subtree, h as transform, i as TOOL_CURSOR, m as group, n as insertions, p as translate_pipeline, r as DEFAULT_STYLE, s as resize_pipeline, u as rotate_pipeline, v as SvgDocument, x as array_shallow_equal, y as WELL_KNOWN_NS_PREFIXES } from "./model-
|
|
1
|
+
import { C as TOOL_SET, S as is_text_input_focused, T as registerDefaultCommands, _ as SVG_NS, a as paint, b as XMLNS_NS, g as subtree, h as transform, i as TOOL_CURSOR, m as group, n as insertions, p as translate_pipeline, r as DEFAULT_STYLE, s as resize_pipeline, u as rotate_pipeline, v as SvgDocument, x as array_shallow_equal, y as WELL_KNOWN_NS_PREFIXES } from "./model-zMPCOVAr.mjs";
|
|
2
2
|
import { HistoryImpl } from "@grida/history";
|
|
3
3
|
import { KeyCode, M, chunkKey, eventToChunk, getKeyboardOS, kb, keybindingsToKeyCodes } from "@grida/keybinding";
|
|
4
4
|
import cmath from "@grida/cmath";
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_model = require("./model-
|
|
3
|
-
const require_editor = require("./editor-
|
|
2
|
+
const require_model = require("./model-HEKGO-56.js");
|
|
3
|
+
const require_editor = require("./editor-DFvojUwn.js");
|
|
4
4
|
exports.DEFAULT_STYLE = require_model.DEFAULT_STYLE;
|
|
5
5
|
exports.PathModel = require_model.PathModel;
|
|
6
6
|
exports.TOOL_CURSOR = require_model.TOOL_CURSOR;
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { t as createSvgEditor } from "./editor-
|
|
2
|
-
import { i as TOOL_CURSOR, r as DEFAULT_STYLE, t as PathModel } from "./model-
|
|
1
|
+
import { t as createSvgEditor } from "./editor-DCDQl18y.mjs";
|
|
2
|
+
import { i as TOOL_CURSOR, r as DEFAULT_STYLE, t as PathModel } from "./model-zMPCOVAr.mjs";
|
|
3
3
|
export { DEFAULT_STYLE, PathModel, TOOL_CURSOR, createSvgEditor };
|
|
@@ -3518,9 +3518,12 @@ let resize_capability;
|
|
|
3518
3518
|
}
|
|
3519
3519
|
}
|
|
3520
3520
|
_resize_capability.origin_of_direction = origin_of_direction;
|
|
3521
|
-
function effective(baseline, dir, sx_gesture, sy_gesture) {
|
|
3521
|
+
function effective(baseline, dir, sx_gesture, sy_gesture, from_center = false) {
|
|
3522
3522
|
const bbox = baseline.bbox;
|
|
3523
|
-
const origin =
|
|
3523
|
+
const origin = from_center ? {
|
|
3524
|
+
x: bbox.x + bbox.width / 2,
|
|
3525
|
+
y: bbox.y + bbox.height / 2
|
|
3526
|
+
} : origin_of_direction(bbox, dir);
|
|
3524
3527
|
const c = constraint(baseline, dir, sx_gesture, sy_gesture);
|
|
3525
3528
|
const mask = direction_mask(dir);
|
|
3526
3529
|
const rect = {
|
|
@@ -3678,7 +3681,7 @@ let resize_pipeline;
|
|
|
3678
3681
|
for (const a of baseline.raw) doc.set_attr(id, a.name, a.value);
|
|
3679
3682
|
}
|
|
3680
3683
|
_intent.restore = restore;
|
|
3681
|
-
function compute_factors(baseline, dir, dx, dy, shift) {
|
|
3684
|
+
function compute_factors(baseline, dir, dx, dy, shift, from_center = false) {
|
|
3682
3685
|
const b = baseline.bbox;
|
|
3683
3686
|
let anchorX = 0;
|
|
3684
3687
|
let anchorY = 0;
|
|
@@ -3740,6 +3743,10 @@ let resize_pipeline;
|
|
|
3740
3743
|
affectsY = false;
|
|
3741
3744
|
break;
|
|
3742
3745
|
}
|
|
3746
|
+
if (from_center) {
|
|
3747
|
+
anchorX = b.x + b.width / 2;
|
|
3748
|
+
anchorY = b.y + b.height / 2;
|
|
3749
|
+
}
|
|
3743
3750
|
const newHX = baseHX + (affectsX ? dx : 0);
|
|
3744
3751
|
const newHY = baseHY + (affectsY ? dy : 0);
|
|
3745
3752
|
const denomX = baseHX - anchorX;
|
|
@@ -3962,7 +3969,7 @@ let resize_pipeline;
|
|
|
3962
3969
|
if (ctx.modifiers.aspect_lock !== "uniform") return { plan };
|
|
3963
3970
|
if (!resize_capability.is_corner(plan.direction)) return { plan };
|
|
3964
3971
|
const pbase = pipeline_baseline(plan);
|
|
3965
|
-
const locked = intent.compute_factors(pbase, plan.direction, plan.dx, plan.dy, true);
|
|
3972
|
+
const locked = intent.compute_factors(pbase, plan.direction, plan.dx, plan.dy, true, ctx.modifiers.from_center);
|
|
3966
3973
|
const bbox = pbase.bbox;
|
|
3967
3974
|
const Hx_base = corner_x_of(bbox, plan.direction);
|
|
3968
3975
|
const Hy_base = corner_y_of(bbox, plan.direction);
|
|
@@ -3982,8 +3989,8 @@ let resize_pipeline;
|
|
|
3982
3989
|
if (!ctx.snap_session) return { plan };
|
|
3983
3990
|
if (!ctx.options.snap_enabled) return { plan };
|
|
3984
3991
|
const pbase = pipeline_baseline(plan);
|
|
3985
|
-
const f = intent.compute_factors(pbase, plan.direction, plan.dx, plan.dy, false);
|
|
3986
|
-
const eff = resize_capability.effective(pbase, plan.direction, f.sx, f.sy);
|
|
3992
|
+
const f = intent.compute_factors(pbase, plan.direction, plan.dx, plan.dy, false, ctx.modifiers.from_center);
|
|
3993
|
+
const eff = resize_capability.effective(pbase, plan.direction, f.sx, f.sy, ctx.modifiers.from_center);
|
|
3987
3994
|
if (eff.no_op) return { plan };
|
|
3988
3995
|
const r = ctx.snap_session.snap_resize(eff.rect, {
|
|
3989
3996
|
x: eff.mask.x_edge,
|
|
@@ -4035,8 +4042,8 @@ let resize_pipeline;
|
|
|
4035
4042
|
const q = ctx.options.pixel_grid_quantum;
|
|
4036
4043
|
if (q === null || q <= 0) return { plan };
|
|
4037
4044
|
const pbase = pipeline_baseline(plan);
|
|
4038
|
-
const f = intent.compute_factors(pbase, plan.direction, plan.dx, plan.dy, false);
|
|
4039
|
-
const eff = resize_capability.effective(pbase, plan.direction, f.sx, f.sy);
|
|
4045
|
+
const f = intent.compute_factors(pbase, plan.direction, plan.dx, plan.dy, false, ctx.modifiers.from_center);
|
|
4046
|
+
const eff = resize_capability.effective(pbase, plan.direction, f.sx, f.sy, ctx.modifiers.from_center);
|
|
4040
4047
|
if (eff.no_op) return { plan };
|
|
4041
4048
|
const target_Hx = eff.mask.affects_x ? Math.round(eff.moving_corner.x / q) * q : eff.moving_corner.x;
|
|
4042
4049
|
const target_Hy = eff.mask.affects_y ? Math.round(eff.moving_corner.y / q) * q : eff.moving_corner.y;
|
|
@@ -4071,7 +4078,7 @@ let resize_pipeline;
|
|
|
4071
4078
|
}
|
|
4072
4079
|
_resize_pipeline.run = run;
|
|
4073
4080
|
function apply(doc, plan, phase = "commit") {
|
|
4074
|
-
const f = intent.compute_factors(plan.baseline, plan.direction, plan.dx, plan.dy, false);
|
|
4081
|
+
const f = intent.compute_factors(plan.baseline, plan.direction, plan.dx, plan.dy, false, plan.from_center ?? false);
|
|
4075
4082
|
const members = plan.members ?? [{
|
|
4076
4083
|
id: plan.id,
|
|
4077
4084
|
baseline: plan.baseline
|
|
@@ -4196,7 +4203,8 @@ var ResizeOrchestrator = class {
|
|
|
4196
4203
|
members: session.members,
|
|
4197
4204
|
direction: session.direction,
|
|
4198
4205
|
dx,
|
|
4199
|
-
dy
|
|
4206
|
+
dy,
|
|
4207
|
+
from_center: modifiers.from_center
|
|
4200
4208
|
};
|
|
4201
4209
|
const ctx = {
|
|
4202
4210
|
input: {
|
|
@@ -3484,9 +3484,12 @@ let resize_capability;
|
|
|
3484
3484
|
}
|
|
3485
3485
|
}
|
|
3486
3486
|
_resize_capability.origin_of_direction = origin_of_direction;
|
|
3487
|
-
function effective(baseline, dir, sx_gesture, sy_gesture) {
|
|
3487
|
+
function effective(baseline, dir, sx_gesture, sy_gesture, from_center = false) {
|
|
3488
3488
|
const bbox = baseline.bbox;
|
|
3489
|
-
const origin =
|
|
3489
|
+
const origin = from_center ? {
|
|
3490
|
+
x: bbox.x + bbox.width / 2,
|
|
3491
|
+
y: bbox.y + bbox.height / 2
|
|
3492
|
+
} : origin_of_direction(bbox, dir);
|
|
3490
3493
|
const c = constraint(baseline, dir, sx_gesture, sy_gesture);
|
|
3491
3494
|
const mask = direction_mask(dir);
|
|
3492
3495
|
const rect = {
|
|
@@ -3644,7 +3647,7 @@ let resize_pipeline;
|
|
|
3644
3647
|
for (const a of baseline.raw) doc.set_attr(id, a.name, a.value);
|
|
3645
3648
|
}
|
|
3646
3649
|
_intent.restore = restore;
|
|
3647
|
-
function compute_factors(baseline, dir, dx, dy, shift) {
|
|
3650
|
+
function compute_factors(baseline, dir, dx, dy, shift, from_center = false) {
|
|
3648
3651
|
const b = baseline.bbox;
|
|
3649
3652
|
let anchorX = 0;
|
|
3650
3653
|
let anchorY = 0;
|
|
@@ -3706,6 +3709,10 @@ let resize_pipeline;
|
|
|
3706
3709
|
affectsY = false;
|
|
3707
3710
|
break;
|
|
3708
3711
|
}
|
|
3712
|
+
if (from_center) {
|
|
3713
|
+
anchorX = b.x + b.width / 2;
|
|
3714
|
+
anchorY = b.y + b.height / 2;
|
|
3715
|
+
}
|
|
3709
3716
|
const newHX = baseHX + (affectsX ? dx : 0);
|
|
3710
3717
|
const newHY = baseHY + (affectsY ? dy : 0);
|
|
3711
3718
|
const denomX = baseHX - anchorX;
|
|
@@ -3928,7 +3935,7 @@ let resize_pipeline;
|
|
|
3928
3935
|
if (ctx.modifiers.aspect_lock !== "uniform") return { plan };
|
|
3929
3936
|
if (!resize_capability.is_corner(plan.direction)) return { plan };
|
|
3930
3937
|
const pbase = pipeline_baseline(plan);
|
|
3931
|
-
const locked = intent.compute_factors(pbase, plan.direction, plan.dx, plan.dy, true);
|
|
3938
|
+
const locked = intent.compute_factors(pbase, plan.direction, plan.dx, plan.dy, true, ctx.modifiers.from_center);
|
|
3932
3939
|
const bbox = pbase.bbox;
|
|
3933
3940
|
const Hx_base = corner_x_of(bbox, plan.direction);
|
|
3934
3941
|
const Hy_base = corner_y_of(bbox, plan.direction);
|
|
@@ -3948,8 +3955,8 @@ let resize_pipeline;
|
|
|
3948
3955
|
if (!ctx.snap_session) return { plan };
|
|
3949
3956
|
if (!ctx.options.snap_enabled) return { plan };
|
|
3950
3957
|
const pbase = pipeline_baseline(plan);
|
|
3951
|
-
const f = intent.compute_factors(pbase, plan.direction, plan.dx, plan.dy, false);
|
|
3952
|
-
const eff = resize_capability.effective(pbase, plan.direction, f.sx, f.sy);
|
|
3958
|
+
const f = intent.compute_factors(pbase, plan.direction, plan.dx, plan.dy, false, ctx.modifiers.from_center);
|
|
3959
|
+
const eff = resize_capability.effective(pbase, plan.direction, f.sx, f.sy, ctx.modifiers.from_center);
|
|
3953
3960
|
if (eff.no_op) return { plan };
|
|
3954
3961
|
const r = ctx.snap_session.snap_resize(eff.rect, {
|
|
3955
3962
|
x: eff.mask.x_edge,
|
|
@@ -4001,8 +4008,8 @@ let resize_pipeline;
|
|
|
4001
4008
|
const q = ctx.options.pixel_grid_quantum;
|
|
4002
4009
|
if (q === null || q <= 0) return { plan };
|
|
4003
4010
|
const pbase = pipeline_baseline(plan);
|
|
4004
|
-
const f = intent.compute_factors(pbase, plan.direction, plan.dx, plan.dy, false);
|
|
4005
|
-
const eff = resize_capability.effective(pbase, plan.direction, f.sx, f.sy);
|
|
4011
|
+
const f = intent.compute_factors(pbase, plan.direction, plan.dx, plan.dy, false, ctx.modifiers.from_center);
|
|
4012
|
+
const eff = resize_capability.effective(pbase, plan.direction, f.sx, f.sy, ctx.modifiers.from_center);
|
|
4006
4013
|
if (eff.no_op) return { plan };
|
|
4007
4014
|
const target_Hx = eff.mask.affects_x ? Math.round(eff.moving_corner.x / q) * q : eff.moving_corner.x;
|
|
4008
4015
|
const target_Hy = eff.mask.affects_y ? Math.round(eff.moving_corner.y / q) * q : eff.moving_corner.y;
|
|
@@ -4037,7 +4044,7 @@ let resize_pipeline;
|
|
|
4037
4044
|
}
|
|
4038
4045
|
_resize_pipeline.run = run;
|
|
4039
4046
|
function apply(doc, plan, phase = "commit") {
|
|
4040
|
-
const f = intent.compute_factors(plan.baseline, plan.direction, plan.dx, plan.dy, false);
|
|
4047
|
+
const f = intent.compute_factors(plan.baseline, plan.direction, plan.dx, plan.dy, false, plan.from_center ?? false);
|
|
4041
4048
|
const members = plan.members ?? [{
|
|
4042
4049
|
id: plan.id,
|
|
4043
4050
|
baseline: plan.baseline
|
|
@@ -4162,7 +4169,8 @@ var ResizeOrchestrator = class {
|
|
|
4162
4169
|
members: session.members,
|
|
4163
4170
|
direction: session.direction,
|
|
4164
4171
|
dx,
|
|
4165
|
-
dy
|
|
4172
|
+
dy,
|
|
4173
|
+
from_center: modifiers.from_center
|
|
4166
4174
|
};
|
|
4167
4175
|
const ctx = {
|
|
4168
4176
|
input: {
|
package/dist/presets.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { c as SvgEditor } from "./editor-CcW4BVth.mjs";
|
|
2
|
-
import { n as DomSurfaceHandle, r as DomSurfaceOptions } from "./dom-
|
|
2
|
+
import { n as DomSurfaceHandle, r as DomSurfaceOptions } from "./dom-D-ZJO9aK.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/presets/keynote.d.ts
|
|
5
5
|
declare namespace keynote_d_exports {
|
package/dist/presets.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { c as SvgEditor } from "./editor-CxqRhhzP.js";
|
|
2
|
-
import { n as DomSurfaceHandle, r as DomSurfaceOptions } from "./dom-
|
|
2
|
+
import { n as DomSurfaceHandle, r as DomSurfaceOptions } from "./dom-Dl56kUW5.js";
|
|
3
3
|
|
|
4
4
|
//#region \0rolldown/runtime.js
|
|
5
5
|
declare namespace keynote_d_exports {
|
package/dist/presets.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_model = require("./model-
|
|
3
|
-
const require_dom = require("./dom-
|
|
2
|
+
const require_model = require("./model-HEKGO-56.js");
|
|
3
|
+
const require_dom = require("./dom-Disackua.js");
|
|
4
4
|
//#region src/presets/keynote.ts
|
|
5
5
|
var keynote_exports = /* @__PURE__ */ require_model.__exportAll({ attach: () => attach });
|
|
6
6
|
/**
|
package/dist/presets.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __exportAll } from "./chunk-D7D4PA-g.mjs";
|
|
2
|
-
import { t as attach_dom_surface } from "./dom-
|
|
2
|
+
import { t as attach_dom_surface } from "./dom-DVxR7PNh.mjs";
|
|
3
3
|
//#region src/presets/keynote.ts
|
|
4
4
|
var keynote_exports = /* @__PURE__ */ __exportAll({ attach: () => attach });
|
|
5
5
|
/**
|
package/dist/react.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { A as EditorState, H as Mode, J as PickEvent, K as PaintPreviewSession, Q as Providers, U as NodeId, Y as PreviewSession, c as SvgEditor, j as EditorStyle, rt as Tool, t as Commands } from "./editor-CcW4BVth.mjs";
|
|
2
|
-
import { n as DomSurfaceHandle } from "./dom-
|
|
2
|
+
import { n as DomSurfaceHandle } from "./dom-D-ZJO9aK.mjs";
|
|
3
3
|
import cmath from "@grida/cmath";
|
|
4
4
|
import { ReactNode } from "react";
|
|
5
5
|
|
package/dist/react.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { A as EditorState, H as Mode, J as PickEvent, K as PaintPreviewSession, Q as Providers, U as NodeId, Y as PreviewSession, c as SvgEditor, j as EditorStyle, rt as Tool, t as Commands } from "./editor-CxqRhhzP.js";
|
|
2
|
-
import { n as DomSurfaceHandle } from "./dom-
|
|
2
|
+
import { n as DomSurfaceHandle } from "./dom-Dl56kUW5.js";
|
|
3
3
|
import cmath from "@grida/cmath";
|
|
4
4
|
import { ReactNode } from "react";
|
|
5
5
|
|
package/dist/react.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const require_editor = require("./editor-
|
|
4
|
-
const require_dom = require("./dom-
|
|
3
|
+
const require_editor = require("./editor-DFvojUwn.js");
|
|
4
|
+
const require_dom = require("./dom-Disackua.js");
|
|
5
5
|
let react = require("react");
|
|
6
6
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
7
7
|
//#region src/react.tsx
|
package/dist/react.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { t as createSvgEditor } from "./editor-
|
|
3
|
-
import { t as attach_dom_surface } from "./dom-
|
|
2
|
+
import { t as createSvgEditor } from "./editor-DCDQl18y.mjs";
|
|
3
|
+
import { t as attach_dom_surface } from "./dom-DVxR7PNh.mjs";
|
|
4
4
|
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useSyncExternalStore } from "react";
|
|
5
5
|
import { jsx } from "react/jsx-runtime";
|
|
6
6
|
//#region src/react.tsx
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@grida/svg-editor",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.23",
|
|
4
4
|
"description": "Headless SVG editor (experimental).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bezier",
|
|
@@ -59,13 +59,13 @@
|
|
|
59
59
|
},
|
|
60
60
|
"dependencies": {
|
|
61
61
|
"@grida/cmath": "0.2.3",
|
|
62
|
-
"@grida/
|
|
62
|
+
"@grida/color": "0.1.0",
|
|
63
63
|
"@grida/history": "0.1.2",
|
|
64
|
-
"@grida/hud": "0.2.3",
|
|
65
64
|
"@grida/vn": "0.1.0",
|
|
66
|
-
"@grida/svg": "0.2.0",
|
|
67
65
|
"@grida/text-editor": "0.1.2",
|
|
68
|
-
"@grida/
|
|
66
|
+
"@grida/hud": "0.3.0",
|
|
67
|
+
"@grida/keybinding": "0.2.1",
|
|
68
|
+
"@grida/svg": "0.2.0"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@types/react": "^19",
|