اضافه شدن قابلیت مقایسه شماتیک
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
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);
|
||||
});
|
||||
مرجع در شماره جدید
مسدود کردن کاربر