Files
altium-render-engine/frontend/interactions.test.js
T

47 خطوط
3.0 KiB
JavaScript

import { test } from 'node:test';
import assert from 'node:assert/strict';
import { bindCamera } from './interactions.js';
const close=(a,b)=>assert.ok(Math.abs(a-b)<1e-8,`${a} != ${b}`);
function setup(t) {
const saved={raf:globalThis.requestAnimationFrame,caf:globalThis.cancelAnimationFrame,observer:globalThis.ResizeObserver};
const frames=[];
globalThis.requestAnimationFrame=fn=>{frames.push(fn);return frames.length;};globalThis.cancelAnimationFrame=()=>{};
globalThis.ResizeObserver=class {observe(){}disconnect(){}};
t.after(()=>{globalThis.requestAnimationFrame=saved.raf;globalThis.cancelAnimationFrame=saved.caf;globalThis.ResizeObserver=saved.observer;});
function surface(left=100) {
const surface=new EventTarget();Object.assign(surface,{clientWidth:800,clientHeight:600,
getBoundingClientRect:()=>({left,top:20}),focus(){},setPointerCapture(){}});
const attributes={};return {surface,svg:{setAttribute:(k,v)=>attributes[k]=v},attributes};
}
return {surface,flush:()=>{for(const fn of frames.splice(0))fn();}};
}
function send(surface,type,values){const event=new Event(type,{cancelable:true});Object.assign(event,values);surface.dispatchEvent(event);return event;}
test('wheel zoom uses the pane offset and synchronizes world cameras',t=>{
const env=setup(t),a=env.surface(),b=env.surface(1000),bounds={x:0,y:-760,width:1150,height:760};
let second;const first=bindCamera(a.surface,a.svg,bounds,source=>second.apply(source.pose()));second=bindCamera(b.surface,b.svg,bounds);
const anchor=first.camera.world(250,200);
const event=send(a.surface,'wheel',{deltaY:-120,deltaMode:0,clientX:350,clientY:220});
assert.ok(event.defaultPrevented);
close(first.camera.world(250,200).x,anchor.x);close(first.camera.world(250,200).y,anchor.y);
close(first.pose().center.x,second.pose().center.x);close(first.camera.scale,second.camera.scale);
env.flush();assert.equal(a.attributes.viewBox,b.attributes.viewBox);first.destroy();second.destroy();
});
test('two-pointer pinch preserves the moving center without rasterizing',t=>{
const env=setup(t),{surface,svg}=env.surface();const view=bindCamera(surface,svg,{x:0,y:0,width:100,height:100});
send(surface,'pointerdown',{pointerId:1,button:0,clientX:200,clientY:200});
send(surface,'pointerdown',{pointerId:2,button:0,clientX:300,clientY:200});
const anchor=view.camera.world(150,180),scale=view.camera.scale;
send(surface,'pointermove',{pointerId:2,clientX:400,clientY:200});
close(view.camera.scale,scale*2);close(view.camera.world(200,180).x,anchor.x);close(view.camera.world(200,180).y,anchor.y);
view.destroy();
});
test('focus fits change bounds and detaching stops interaction',t=>{
const env=setup(t),{surface,svg}=env.surface();const view=bindCamera(surface,svg,{x:0,y:0,width:1000,height:1000});
view.focus({x:100,y:200,width:20,height:40});const center=view.pose().center;
close(center.x,110);close(center.y,220);view.destroy();const scale=view.camera.scale;
send(surface,'wheel',{deltaY:-120,deltaMode:0,clientX:200,clientY:200});close(view.camera.scale,scale);
});