task(A4.7): migrate rotate/scale/mirror tools to v2 (selection-based transforms)

This commit is contained in:
Agent Zero
2026-08-27 01:04:48 +02:00
parent 1d3d9bd191
commit 1d598daba1
2 changed files with 232 additions and 47 deletions
+80
View File
@@ -433,6 +433,86 @@ describe('A4.6 pilot: move/copy tools', () => {
});
});
describe('A4.7 pilot: transform tools', () => {
it('rotate dreht um Pivot des ersten Elements; ein undo stellt zurück', () => {
const { ydoc } = createInMemoryDoc();
const doc = new CADDocument(ydoc);
const rotEl = makeEl('r1');
doc.addElement(rotEl);
let selIds: string[] = ['r1'];
const bridge = {
getIds: () => selIds,
setIds: (ids: string[]) => { selIds = ids; },
hitTest: () => null,
};
const ctx = makeCtx({ doc, selection: bridge });
const rotate = coreModifyPlugin.tools!.find((t) => t.manifest.id === 'rotate')!;
// Basispunkt rechts vom Zentrum (0°-Richtung), Element x=10
rotate.handlers.down!(pe(60, 10), ctx);
// Referenzklick oben → Δwinkel ≈ +90° (CCW)
rotate.handlers.down!(pe(10, 60), ctx);
expect(doc.undo()).toBe(true);
expect(doc.getAllElements().length).toBe(1);
});
it('scale vergrößert width/height um Faktor dist(pivot,zweiteKlick)/dist(pivot,basis)', () => {
const { ydoc } = createInMemoryDoc();
const doc = new CADDocument(ydoc);
const sq = makeEl('s1');
sq.width = 40;
sq.height = 40;
sq.x = 0;
sq.y = 0;
doc.addElement(sq);
let selIds: string[] = ['s1'];
const bridge = {
getIds: () => selIds,
setIds: (ids: string[]) => { selIds = ids; },
hitTest: () => null,
};
const ctx = makeCtx({ doc, selection: bridge });
const scale = coreModifyPlugin.tools!.find((t) => t.manifest.id === 'scale')!;
// Basis bei Distanz 50 vom Pivot, Ziel bei 100 → Faktor 2
scale.handlers.down!(pe(50, 0), ctx);
scale.handlers.down!(pe(100, 0), ctx);
expect(doc.getElement('s1')!.width).toBeCloseTo(80); // 40×2
expect(doc.getElement('s1')!.height).toBeCloseTo(80);
expect(doc.undo()).toBe(true);
expect(doc.getElement('s1')!.width).toBeCloseTo(40);
});
it('mirror spiegelt Element an Achse basis→referenz', () => {
const { ydoc } = createInMemoryDoc();
const doc = new CADDocument(ydoc);
const el = makeEl('mi');
el.x = 30;
el.y = 0;
doc.addElement(el);
let selIds: string[] = ['mi'];
const bridge = {
getIds: () => selIds,
setIds: (ids: string[]) => { selIds = ids; },
hitTest: () => null,
};
const ctx = makeCtx({ doc, selection: bridge });
const mirror = coreModifyPlugin.tools!.find((t) => t.manifest.id === 'mirror')!;
// Spiegelachse = Y-Achse (basis (0,0)→ref (0,100)): Punkt (30,0)→(30,0)
mirror.handlers.down!(pe(0, 0), ctx);
mirror.handlers.down!(pe(0, 100), ctx);
const mirrored = doc.getElement('mi')!;
expect(mirrored.x).toBeLessThan(0); // jenseits der Achse
expect(Math.abs(mirrored.x)).toBeGreaterThanOrEqual(29); // ~spiegelsymmetrisch
expect(doc.undo()).toBe(true);
});
});
describe('A3 pilot: select tool', () => {
function makeBridge(elements: CADElement[]) {
let ids: string[] = [];