summaryrefslogtreecommitdiff
path: root/tools/mq_editor
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-02-18 16:10:44 +0100
committerskal <pascal.massimino@gmail.com>2026-02-18 16:10:44 +0100
commit24a0b0aeb7d789918fd5fb1591a71f30afda1830 (patch)
treec53542c35da2894a2a4c87ff658ba0b8751c9574 /tools/mq_editor
parent7ed5b33fa581cf09af23de532c3c69bbaffedd54 (diff)
feat(mq_editor): drag anchor points P0/P3 with their companion handles
Moving P0 translates P1 rigidly (preserving relative offset). Moving P3 translates P2 rigidly. Handles P1/P2 remain independently draggable. handoff(Claude): bezier coupled anchor drag done
Diffstat (limited to 'tools/mq_editor')
-rw-r--r--tools/mq_editor/editor.js15
1 files changed, 13 insertions, 2 deletions
diff --git a/tools/mq_editor/editor.js b/tools/mq_editor/editor.js
index 301dcc5..868d3d5 100644
--- a/tools/mq_editor/editor.js
+++ b/tools/mq_editor/editor.js
@@ -23,7 +23,8 @@ class PartialEditor {
// Private state
this._selectedIndex = -1;
- this._dragPointIndex = -1;
+ this._dragPointIndex = -1;
+ this._dragCompanionOff = null; // {dt, dv} offset of companion handle relative to anchor
this._amp = { tMin: 0, tMax: 1, ampTop: 1 };
this._setupButtons();
@@ -489,7 +490,12 @@ class PartialEditor {
const curve = partial.ampCurve;
for (let i = 0; i < 4; ++i) {
if (Math.hypot(this._tToX(curve['t' + i]) - x, this._ampToY(curve['v' + i]) - y) <= 8) {
- this._dragPointIndex = i;
+ this._dragPointIndex = i;
+ this._dragCompanionOff = null;
+ if (i === 0)
+ this._dragCompanionOff = { dt: curve.t1 - curve.t0, dv: curve.v1 - curve.v0 };
+ else if (i === 3)
+ this._dragCompanionOff = { dt: curve.t2 - curve.t3, dv: curve.v2 - curve.v3 };
canvas.style.cursor = 'grabbing';
e.preventDefault();
return;
@@ -505,6 +511,11 @@ class PartialEditor {
const i = this._dragPointIndex;
curve['t' + i] = Math.max(0, Math.min(this.viewer ? this.viewer.t_max : 1e6, this._xToT(x)));
curve['v' + i] = Math.max(0, this._yToAmp(y));
+ if (this._dragCompanionOff) {
+ const off = this._dragCompanionOff;
+ if (i === 0) { curve.t1 = curve.t0 + off.dt; curve.v1 = curve.v0 + off.dv; }
+ else { curve.t2 = curve.t3 + off.dt; curve.v2 = curve.v3 + off.dv; }
+ }
this._renderAmpEditor();
if (this.viewer) this.viewer.render();
e.preventDefault();