@grida/svg-editor 1.0.0-alpha.22 → 1.0.0-alpha.24
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/README.md +6 -0
- package/dist/{dom-H4PvmPe3.js → dom-8wNtJcu9.js} +99 -42
- package/dist/{dom-CQkWJNrK.d.ts → dom-CYzYf9lz.d.ts} +18 -2
- package/dist/{dom-BIjCxCgx.mjs → dom-DE0Je0o1.mjs} +94 -43
- package/dist/{dom-Dw2SPHgc.d.mts → dom-DeHyTJ2i.d.mts} +18 -2
- package/dist/dom.d.mts +3 -3
- package/dist/dom.d.ts +3 -3
- package/dist/dom.js +2 -1
- package/dist/dom.mjs +2 -2
- package/dist/{editor-DCDQl18y.mjs → editor-CdSQ5BWb.mjs} +7 -1
- package/dist/{editor-CxqRhhzP.d.ts → editor-D4TvRpm6.d.ts} +15 -0
- package/dist/{editor-CcW4BVth.d.mts → editor-DsJweR76.d.mts} +15 -0
- package/dist/{editor-DFvojUwn.js → editor-YelJorw6.js} +7 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{model-zMPCOVAr.mjs → model-DcOLgMdU.mjs} +6 -0
- package/dist/{model-HEKGO-56.js → model-HVpmlF_I.js} +6 -0
- package/dist/presets.d.mts +2 -2
- package/dist/presets.d.ts +2 -2
- package/dist/presets.js +2 -2
- package/dist/presets.mjs +1 -1
- package/dist/react.d.mts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +2 -2
- package/dist/react.mjs +2 -2
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -636,6 +636,12 @@ editor.commands.{
|
|
|
636
636
|
opts?: { reuse_existing?: boolean },
|
|
637
637
|
): { gradient_id: string };
|
|
638
638
|
|
|
639
|
+
// opacity — typed, clamped sugar for set_property("opacity", …); one
|
|
640
|
+
// history step across the selection. `value` is clamped to [0, 1]. This
|
|
641
|
+
// is the command behind the digit → opacity shortcut; the digit
|
|
642
|
+
// keybindings are NOT shipped in the default keymap (host-wired).
|
|
643
|
+
set_opacity(value: number): void;
|
|
644
|
+
|
|
639
645
|
// transforms (atomic — the bundled HUD drives drag-resize-rotate internally)
|
|
640
646
|
translate(delta: { dx: number; dy: number }): void;
|
|
641
647
|
nudge(direction: "left" | "right" | "up" | "down", step?: number): void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_model = require("./model-
|
|
1
|
+
const require_model = require("./model-HVpmlF_I.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();
|
|
@@ -4076,7 +4071,10 @@ var DomSurface = class DomSurface {
|
|
|
4076
4071
|
this.sync_surface_selection();
|
|
4077
4072
|
this.sync_cursor();
|
|
4078
4073
|
this.redraw();
|
|
4079
|
-
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
|
+
});
|
|
4080
4078
|
const is_mac = typeof navigator !== "undefined" && /Mac|iPod|iPhone|iPad/.test(navigator.userAgent);
|
|
4081
4079
|
let settled = false;
|
|
4082
4080
|
this.text_edit = (0, _grida_text_editor_dom.createTextEditor)({
|
|
@@ -4124,11 +4122,45 @@ var DomSurface = class DomSurface {
|
|
|
4124
4122
|
this.render();
|
|
4125
4123
|
this.sync_surface_selection();
|
|
4126
4124
|
this.sync_cursor();
|
|
4125
|
+
this.push_text_edit_chrome(null);
|
|
4127
4126
|
this.redraw();
|
|
4128
4127
|
this.text_edit = null;
|
|
4129
4128
|
this.text_edit_target = null;
|
|
4130
4129
|
}
|
|
4131
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
|
+
/**
|
|
4132
4164
|
* Realize the result of a text content-edit session and exit. `result`
|
|
4133
4165
|
* is the text that should remain — the typed text on commit, the original
|
|
4134
4166
|
* on cancel. Implements the empty-equals-delete rule (design:
|
|
@@ -4947,6 +4979,25 @@ function project_point_through_ctm(px, py, ctm, container_offset) {
|
|
|
4947
4979
|
return [sx + container_offset[0], sy + container_offset[1]];
|
|
4948
4980
|
}
|
|
4949
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
|
+
/**
|
|
4950
5001
|
* Inverse of the CTM's linear part applied to a delta vector. Drops
|
|
4951
5002
|
* translation. Used to convert a HUD-reported container-space drag delta
|
|
4952
5003
|
* back to the path's local coord space for `PathModel.translateVertices`.
|
|
@@ -5252,6 +5303,12 @@ Object.defineProperty(exports, "attach_dom_surface", {
|
|
|
5252
5303
|
return attach_dom_surface;
|
|
5253
5304
|
}
|
|
5254
5305
|
});
|
|
5306
|
+
Object.defineProperty(exports, "ctm_to_container_transform", {
|
|
5307
|
+
enumerable: true,
|
|
5308
|
+
get: function() {
|
|
5309
|
+
return ctm_to_container_transform;
|
|
5310
|
+
}
|
|
5311
|
+
});
|
|
5255
5312
|
Object.defineProperty(exports, "install_font_load_geometry_bump", {
|
|
5256
5313
|
enumerable: true,
|
|
5257
5314
|
get: function() {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as SvgEditor, p as Gestures, s as SurfaceHandle, w as Camera } from "./editor-
|
|
1
|
+
import { c as SvgEditor, p as Gestures, s as SurfaceHandle, w as Camera } from "./editor-D4TvRpm6.js";
|
|
2
2
|
import cmath from "@grida/cmath";
|
|
3
3
|
//#region src/util/attention.d.ts
|
|
4
4
|
/** The runtime handle returned by `create_attention_tracker`. */
|
|
@@ -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 };
|
|
@@ -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-DcOLgMdU.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();
|
|
@@ -4074,7 +4069,10 @@ var DomSurface = class DomSurface {
|
|
|
4074
4069
|
this.sync_surface_selection();
|
|
4075
4070
|
this.sync_cursor();
|
|
4076
4071
|
this.redraw();
|
|
4077
|
-
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
|
+
});
|
|
4078
4076
|
const is_mac = typeof navigator !== "undefined" && /Mac|iPod|iPhone|iPad/.test(navigator.userAgent);
|
|
4079
4077
|
let settled = false;
|
|
4080
4078
|
this.text_edit = createTextEditor({
|
|
@@ -4122,11 +4120,45 @@ var DomSurface = class DomSurface {
|
|
|
4122
4120
|
this.render();
|
|
4123
4121
|
this.sync_surface_selection();
|
|
4124
4122
|
this.sync_cursor();
|
|
4123
|
+
this.push_text_edit_chrome(null);
|
|
4125
4124
|
this.redraw();
|
|
4126
4125
|
this.text_edit = null;
|
|
4127
4126
|
this.text_edit_target = null;
|
|
4128
4127
|
}
|
|
4129
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
|
+
/**
|
|
4130
4162
|
* Realize the result of a text content-edit session and exit. `result`
|
|
4131
4163
|
* is the text that should remain — the typed text on commit, the original
|
|
4132
4164
|
* on cancel. Implements the empty-equals-delete rule (design:
|
|
@@ -4945,6 +4977,25 @@ function project_point_through_ctm(px, py, ctm, container_offset) {
|
|
|
4945
4977
|
return [sx + container_offset[0], sy + container_offset[1]];
|
|
4946
4978
|
}
|
|
4947
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
|
+
/**
|
|
4948
4999
|
* Inverse of the CTM's linear part applied to a delta vector. Drops
|
|
4949
5000
|
* translation. Used to convert a HUD-reported container-space drag delta
|
|
4950
5001
|
* back to the path's local coord space for `PathModel.translateVertices`.
|
|
@@ -5220,4 +5271,4 @@ var SvgHitShapeDriver = class {
|
|
|
5220
5271
|
}
|
|
5221
5272
|
};
|
|
5222
5273
|
//#endregion
|
|
5223
|
-
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
|
-
import { c as SvgEditor, p as Gestures, s as SurfaceHandle, w as Camera } from "./editor-
|
|
1
|
+
import { c as SvgEditor, p as Gestures, s as SurfaceHandle, w as Camera } from "./editor-DsJweR76.mjs";
|
|
2
2
|
import cmath from "@grida/cmath";
|
|
3
3
|
import { guide } from "@grida/cmath/_snap";
|
|
4
4
|
|
|
@@ -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 };
|
package/dist/dom.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
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-
|
|
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 };
|
|
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-DsJweR76.mjs";
|
|
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-DeHyTJ2i.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
|
-
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-
|
|
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 };
|
|
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-D4TvRpm6.js";
|
|
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-CYzYf9lz.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-8wNtJcu9.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-DE0Je0o1.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-DcOLgMdU.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";
|
|
@@ -1489,6 +1489,11 @@ function _create_svg_editor_internal(opts) {
|
|
|
1489
1489
|
});
|
|
1490
1490
|
return { gradient_id };
|
|
1491
1491
|
}
|
|
1492
|
+
function set_opacity(value) {
|
|
1493
|
+
if (!Number.isFinite(value)) return;
|
|
1494
|
+
const clamped = cmath.clamp01(value);
|
|
1495
|
+
set_property("opacity", String(clamped));
|
|
1496
|
+
}
|
|
1492
1497
|
/** World→local delta projection shared by every one-shot translate
|
|
1493
1498
|
* writer (translate / nudge via `prepare_rpc`, align). Re-expresses a
|
|
1494
1499
|
* world-space delta in the frame the target's position attributes are
|
|
@@ -2539,6 +2544,7 @@ function _create_svg_editor_internal(opts) {
|
|
|
2539
2544
|
set_paint,
|
|
2540
2545
|
preview_paint,
|
|
2541
2546
|
set_paint_from_gradient,
|
|
2547
|
+
set_opacity,
|
|
2542
2548
|
translate,
|
|
2543
2549
|
nudge,
|
|
2544
2550
|
resize_to,
|
|
@@ -1816,6 +1816,21 @@ type Commands = {
|
|
|
1816
1816
|
}): {
|
|
1817
1817
|
gradient_id: string;
|
|
1818
1818
|
};
|
|
1819
|
+
/**
|
|
1820
|
+
* Set the `opacity` presentation property across the whole selection in
|
|
1821
|
+
* one history step. Typed, clamped sugar over `set_property("opacity", …)`
|
|
1822
|
+
* — `value` is clamped to `[0, 1]` (CSS clamps opacity to that range at
|
|
1823
|
+
* used-value time), so callers don't have to. A non-finite `value` is a
|
|
1824
|
+
* no-op, as is an empty selection. The write picks each member's winning
|
|
1825
|
+
* cascade carrier exactly like `set_property` (P1), and an in-flight
|
|
1826
|
+
* `preview_property("opacity")` session is superseded the same way a
|
|
1827
|
+
* discrete `set_property` write is.
|
|
1828
|
+
*
|
|
1829
|
+
* This is the editor-owned command behind the digit → opacity shortcut
|
|
1830
|
+
* (see `docs/keybindings.md` → Object Properties); the keybindings
|
|
1831
|
+
* themselves are intentionally not shipped in the default keymap.
|
|
1832
|
+
*/
|
|
1833
|
+
set_opacity(value: number): void;
|
|
1819
1834
|
translate(delta: {
|
|
1820
1835
|
dx: number;
|
|
1821
1836
|
dy: number;
|
|
@@ -1816,6 +1816,21 @@ type Commands = {
|
|
|
1816
1816
|
}): {
|
|
1817
1817
|
gradient_id: string;
|
|
1818
1818
|
};
|
|
1819
|
+
/**
|
|
1820
|
+
* Set the `opacity` presentation property across the whole selection in
|
|
1821
|
+
* one history step. Typed, clamped sugar over `set_property("opacity", …)`
|
|
1822
|
+
* — `value` is clamped to `[0, 1]` (CSS clamps opacity to that range at
|
|
1823
|
+
* used-value time), so callers don't have to. A non-finite `value` is a
|
|
1824
|
+
* no-op, as is an empty selection. The write picks each member's winning
|
|
1825
|
+
* cascade carrier exactly like `set_property` (P1), and an in-flight
|
|
1826
|
+
* `preview_property("opacity")` session is superseded the same way a
|
|
1827
|
+
* discrete `set_property` write is.
|
|
1828
|
+
*
|
|
1829
|
+
* This is the editor-owned command behind the digit → opacity shortcut
|
|
1830
|
+
* (see `docs/keybindings.md` → Object Properties); the keybindings
|
|
1831
|
+
* themselves are intentionally not shipped in the default keymap.
|
|
1832
|
+
*/
|
|
1833
|
+
set_opacity(value: number): void;
|
|
1819
1834
|
translate(delta: {
|
|
1820
1835
|
dx: number;
|
|
1821
1836
|
dy: number;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_model = require("./model-
|
|
1
|
+
const require_model = require("./model-HVpmlF_I.js");
|
|
2
2
|
let _grida_history = require("@grida/history");
|
|
3
3
|
let _grida_keybinding = require("@grida/keybinding");
|
|
4
4
|
let _grida_cmath = require("@grida/cmath");
|
|
@@ -1490,6 +1490,11 @@ function _create_svg_editor_internal(opts) {
|
|
|
1490
1490
|
});
|
|
1491
1491
|
return { gradient_id };
|
|
1492
1492
|
}
|
|
1493
|
+
function set_opacity(value) {
|
|
1494
|
+
if (!Number.isFinite(value)) return;
|
|
1495
|
+
const clamped = _grida_cmath.default.clamp01(value);
|
|
1496
|
+
set_property("opacity", String(clamped));
|
|
1497
|
+
}
|
|
1493
1498
|
/** World→local delta projection shared by every one-shot translate
|
|
1494
1499
|
* writer (translate / nudge via `prepare_rpc`, align). Re-expresses a
|
|
1495
1500
|
* world-space delta in the frame the target's position attributes are
|
|
@@ -2540,6 +2545,7 @@ function _create_svg_editor_internal(opts) {
|
|
|
2540
2545
|
set_paint,
|
|
2541
2546
|
preview_paint,
|
|
2542
2547
|
set_paint_from_gradient,
|
|
2548
|
+
set_opacity,
|
|
2543
2549
|
translate,
|
|
2544
2550
|
nudge,
|
|
2545
2551
|
resize_to,
|
package/dist/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { $ as RadialGradientDefinition, A as EditorState, B as LinearGradientDefinition, D as ClipboardProvider, F as GradientEntry, G as PaintFallback, H as Mode, I as GradientStop, K as PaintPreviewSession, L as InsertPreviewSession, M as FileIOProvider, N as FontResolver, O as Color, P as GradientDefinition, Q as Providers, R as InsertableTag, S as AlignDirection, U as NodeId, V as Matrix2D, W as Paint, X as PropertyValue, Y as PreviewSession, Z as Provenance, _ as PathModel, a as SelectMode, at as Vec2, b as Verb, c as SvgEditor, et as Rect, it as Unsubscribe, j as EditorStyle, k as DEFAULT_STYLE, l as createSvgEditor, n as CreateSvgEditorOptions, nt as TOOL_CURSOR, o as Surface, q as PaintValue, rt as Tool, s as SurfaceHandle, t as Commands, tt as ReorderDirection, v as PathSnapshot, x as VertexId, y as SegmentId, z as InvalidComputedValue } from "./editor-
|
|
1
|
+
import { $ as RadialGradientDefinition, A as EditorState, B as LinearGradientDefinition, D as ClipboardProvider, F as GradientEntry, G as PaintFallback, H as Mode, I as GradientStop, K as PaintPreviewSession, L as InsertPreviewSession, M as FileIOProvider, N as FontResolver, O as Color, P as GradientDefinition, Q as Providers, R as InsertableTag, S as AlignDirection, U as NodeId, V as Matrix2D, W as Paint, X as PropertyValue, Y as PreviewSession, Z as Provenance, _ as PathModel, a as SelectMode, at as Vec2, b as Verb, c as SvgEditor, et as Rect, it as Unsubscribe, j as EditorStyle, k as DEFAULT_STYLE, l as createSvgEditor, n as CreateSvgEditorOptions, nt as TOOL_CURSOR, o as Surface, q as PaintValue, rt as Tool, s as SurfaceHandle, t as Commands, tt as ReorderDirection, v as PathSnapshot, x as VertexId, y as SegmentId, z as InvalidComputedValue } from "./editor-DsJweR76.mjs";
|
|
2
2
|
export { type AlignDirection, type ClipboardProvider, type Color, type Commands, type CreateSvgEditorOptions, DEFAULT_STYLE, type EditorState, type EditorStyle, type FileIOProvider, type FontResolver, type GradientDefinition, type GradientEntry, type GradientStop, type InsertPreviewSession, type InsertableTag, type InvalidComputedValue, type LinearGradientDefinition, type Matrix2D, type Mode, type NodeId, type Paint, type PaintFallback, type PaintPreviewSession, type PaintValue, PathModel, type PathSnapshot, type PreviewSession, type PropertyValue, type Provenance, type Providers, type RadialGradientDefinition, type Rect, type ReorderDirection, type SegmentId, type SelectMode, type Surface, type SurfaceHandle, type SvgEditor, TOOL_CURSOR, type Tool, type Unsubscribe, type Vec2, type Verb, type VertexId, createSvgEditor };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { $ as RadialGradientDefinition, A as EditorState, B as LinearGradientDefinition, D as ClipboardProvider, F as GradientEntry, G as PaintFallback, H as Mode, I as GradientStop, K as PaintPreviewSession, L as InsertPreviewSession, M as FileIOProvider, N as FontResolver, O as Color, P as GradientDefinition, Q as Providers, R as InsertableTag, S as AlignDirection, U as NodeId, V as Matrix2D, W as Paint, X as PropertyValue, Y as PreviewSession, Z as Provenance, _ as PathModel, a as SelectMode, at as Vec2, b as Verb, c as SvgEditor, et as Rect, it as Unsubscribe, j as EditorStyle, k as DEFAULT_STYLE, l as createSvgEditor, n as CreateSvgEditorOptions, nt as TOOL_CURSOR, o as Surface, q as PaintValue, rt as Tool, s as SurfaceHandle, t as Commands, tt as ReorderDirection, v as PathSnapshot, x as VertexId, y as SegmentId, z as InvalidComputedValue } from "./editor-
|
|
1
|
+
import { $ as RadialGradientDefinition, A as EditorState, B as LinearGradientDefinition, D as ClipboardProvider, F as GradientEntry, G as PaintFallback, H as Mode, I as GradientStop, K as PaintPreviewSession, L as InsertPreviewSession, M as FileIOProvider, N as FontResolver, O as Color, P as GradientDefinition, Q as Providers, R as InsertableTag, S as AlignDirection, U as NodeId, V as Matrix2D, W as Paint, X as PropertyValue, Y as PreviewSession, Z as Provenance, _ as PathModel, a as SelectMode, at as Vec2, b as Verb, c as SvgEditor, et as Rect, it as Unsubscribe, j as EditorStyle, k as DEFAULT_STYLE, l as createSvgEditor, n as CreateSvgEditorOptions, nt as TOOL_CURSOR, o as Surface, q as PaintValue, rt as Tool, s as SurfaceHandle, t as Commands, tt as ReorderDirection, v as PathSnapshot, x as VertexId, y as SegmentId, z as InvalidComputedValue } from "./editor-D4TvRpm6.js";
|
|
2
2
|
export { type AlignDirection, type ClipboardProvider, type Color, type Commands, type CreateSvgEditorOptions, DEFAULT_STYLE, type EditorState, type EditorStyle, type FileIOProvider, type FontResolver, type GradientDefinition, type GradientEntry, type GradientStop, type InsertPreviewSession, type InsertableTag, type InvalidComputedValue, type LinearGradientDefinition, type Matrix2D, type Mode, type NodeId, type Paint, type PaintFallback, type PaintPreviewSession, type PaintValue, PathModel, type PathSnapshot, type PreviewSession, type PropertyValue, type Provenance, type Providers, type RadialGradientDefinition, type Rect, type ReorderDirection, type SegmentId, type SelectMode, type Surface, type SurfaceHandle, type SvgEditor, TOOL_CURSOR, type Tool, type Unsubscribe, type Vec2, type Verb, type VertexId, createSvgEditor };
|
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-HVpmlF_I.js");
|
|
3
|
+
const require_editor = require("./editor-YelJorw6.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-CdSQ5BWb.mjs";
|
|
2
|
+
import { i as TOOL_CURSOR, r as DEFAULT_STYLE, t as PathModel } from "./model-DcOLgMdU.mjs";
|
|
3
3
|
export { DEFAULT_STYLE, PathModel, TOOL_CURSOR, createSvgEditor };
|
|
@@ -92,6 +92,12 @@ function registerDefaultCommands(reg, editor) {
|
|
|
92
92
|
if (editor.state.selection.length === 0) return false;
|
|
93
93
|
return editor.commands.flatten_transform();
|
|
94
94
|
});
|
|
95
|
+
reg.register("selection.set_opacity", (args) => {
|
|
96
|
+
if (editor.state.mode !== "select") return false;
|
|
97
|
+
if (editor.state.selection.length === 0) return false;
|
|
98
|
+
editor.commands.set_opacity(args);
|
|
99
|
+
return true;
|
|
100
|
+
});
|
|
95
101
|
reg.register("selection.all", () => {
|
|
96
102
|
if (editor.state.mode !== "select") return false;
|
|
97
103
|
return editor.commands.select_all();
|
|
@@ -126,6 +126,12 @@ function registerDefaultCommands(reg, editor) {
|
|
|
126
126
|
if (editor.state.selection.length === 0) return false;
|
|
127
127
|
return editor.commands.flatten_transform();
|
|
128
128
|
});
|
|
129
|
+
reg.register("selection.set_opacity", (args) => {
|
|
130
|
+
if (editor.state.mode !== "select") return false;
|
|
131
|
+
if (editor.state.selection.length === 0) return false;
|
|
132
|
+
editor.commands.set_opacity(args);
|
|
133
|
+
return true;
|
|
134
|
+
});
|
|
129
135
|
reg.register("selection.all", () => {
|
|
130
136
|
if (editor.state.mode !== "select") return false;
|
|
131
137
|
return editor.commands.select_all();
|
package/dist/presets.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { c as SvgEditor } from "./editor-
|
|
2
|
-
import { n as DomSurfaceHandle, r as DomSurfaceOptions } from "./dom-
|
|
1
|
+
import { c as SvgEditor } from "./editor-DsJweR76.mjs";
|
|
2
|
+
import { n as DomSurfaceHandle, r as DomSurfaceOptions } from "./dom-DeHyTJ2i.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
|
-
import { c as SvgEditor } from "./editor-
|
|
2
|
-
import { n as DomSurfaceHandle, r as DomSurfaceOptions } from "./dom-
|
|
1
|
+
import { c as SvgEditor } from "./editor-D4TvRpm6.js";
|
|
2
|
+
import { n as DomSurfaceHandle, r as DomSurfaceOptions } from "./dom-CYzYf9lz.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-HVpmlF_I.js");
|
|
3
|
+
const require_dom = require("./dom-8wNtJcu9.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-DE0Je0o1.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
|
-
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-
|
|
2
|
-
import { n as DomSurfaceHandle } from "./dom-
|
|
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-DsJweR76.mjs";
|
|
2
|
+
import { n as DomSurfaceHandle } from "./dom-DeHyTJ2i.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
|
-
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-
|
|
2
|
-
import { n as DomSurfaceHandle } from "./dom-
|
|
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-D4TvRpm6.js";
|
|
2
|
+
import { n as DomSurfaceHandle } from "./dom-CYzYf9lz.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-YelJorw6.js");
|
|
4
|
+
const require_dom = require("./dom-8wNtJcu9.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-CdSQ5BWb.mjs";
|
|
3
|
+
import { t as attach_dom_surface } from "./dom-DE0Je0o1.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.24",
|
|
4
4
|
"description": "Headless SVG editor (experimental).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bezier",
|
|
@@ -60,12 +60,12 @@
|
|
|
60
60
|
"dependencies": {
|
|
61
61
|
"@grida/cmath": "0.2.3",
|
|
62
62
|
"@grida/color": "0.1.0",
|
|
63
|
+
"@grida/hud": "0.3.0",
|
|
63
64
|
"@grida/history": "0.1.2",
|
|
64
|
-
"@grida/keybinding": "0.2.
|
|
65
|
-
"@grida/hud": "0.2.4",
|
|
65
|
+
"@grida/keybinding": "0.2.2",
|
|
66
66
|
"@grida/svg": "0.2.0",
|
|
67
|
-
"@grida/
|
|
68
|
-
"@grida/
|
|
67
|
+
"@grida/vn": "0.1.0",
|
|
68
|
+
"@grida/text-editor": "0.1.2"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@types/react": "^19",
|