task(A4.7): migrate rotate/scale/mirror tools to v2 (selection-based transforms)
This commit is contained in:
@@ -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[] = [];
|
||||
|
||||
Reference in New Issue
Block a user