Fix family map fullscreen jitter and long recording playback
This commit is contained in:
+21
-6
@@ -10,9 +10,24 @@ class FamilyMap {
|
||||
viewport.addEventListener('pointermove',e=>{if(!this.drag)return;viewport.scrollLeft=this.drag.left+this.drag.x-e.clientX;viewport.scrollTop=this.drag.top+this.drag.y-e.clientY;});
|
||||
const release=()=>{this.drag=null;viewport.classList.remove('panning');};
|
||||
viewport.addEventListener('pointerup',release);viewport.addEventListener('pointercancel',release);viewport.addEventListener('lostpointercapture',release);
|
||||
this.resize=new ResizeObserver(()=>{if(this.autoFit)this.fit();else this.applyScale();});this.resize.observe(viewport);
|
||||
this.resizeFrame=0;this.resizeSize='';
|
||||
this.resize=new ResizeObserver(()=>this.scheduleResize());this.resize.observe(viewport,{box:'border-box'});
|
||||
}
|
||||
reset(){cancelAnimationFrame(this.resizeFrame);this.resizeFrame=0;this.resizeSize='';this.key='';this.data=null;this.graph=null;this.viewport.replaceChildren();this.autoFit=true;this.drag=null;$('#family-zoom-value').textContent='100%';}
|
||||
viewportSize(){
|
||||
const v=this.viewport,r=v.getBoundingClientRect();
|
||||
// clientHeight rounds fractional pixels up; using it as a child height can
|
||||
// create a scrollbar, remove it on the next fit, and repeat indefinitely.
|
||||
return {width:Math.floor(Math.min(v.clientWidth,r.width)),height:Math.floor(Math.min(v.clientHeight,r.height))};
|
||||
}
|
||||
scheduleResize(){
|
||||
if(this.resizeFrame)return;
|
||||
this.resizeFrame=requestAnimationFrame(()=>{
|
||||
this.resizeFrame=0;const {width,height}=this.viewportSize(),key=width+':'+height;
|
||||
if(!width||!height||key===this.resizeSize)return;
|
||||
this.resizeSize=key;if(this.autoFit)this.fit();else this.applyScale();
|
||||
});
|
||||
}
|
||||
reset(){this.key='';this.data=null;this.viewport.replaceChildren();this.autoFit=true;this.drag=null;$('#family-zoom-value').textContent='100%';}
|
||||
render(data) {
|
||||
this.data=data;
|
||||
const key=JSON.stringify([data.people,data.links,data.showArchived,data.selfId]);
|
||||
@@ -46,16 +61,16 @@ class FamilyMap {
|
||||
}
|
||||
applyScale() {
|
||||
const v=this.viewport,g=this.graph,space=v.querySelector('.family-map-space'),surface=v.querySelector('.family-map-surface');
|
||||
if(!g||!space||!v.clientWidth)return;
|
||||
const w=Math.max(v.clientWidth,g.width*this.scale+32),h=Math.max(v.clientHeight,g.height*this.scale+32);
|
||||
const {width,height}=this.viewportSize();if(!g||!space||!width||!height)return;
|
||||
const w=Math.max(width,Math.ceil(g.width*this.scale+32)),h=Math.max(height,Math.ceil(g.height*this.scale+32));
|
||||
space.style.width=w+'px';space.style.height=h+'px';
|
||||
this.left=(w-g.width*this.scale)/2;this.top=(h-g.height*this.scale)/2;
|
||||
surface.style.transform=`translate(${this.left}px,${this.top}px) scale(${this.scale})`;
|
||||
$('#family-zoom-value').textContent=Math.round(this.scale*100)+'%';
|
||||
}
|
||||
fit() {
|
||||
const v=this.viewport,g=this.graph;if(!g||!v.clientWidth||!v.clientHeight)return;
|
||||
this.autoFit=true;this.scale=Math.max(.001,Math.min(1,(v.clientWidth-40)/g.width,(v.clientHeight-40)/g.height));
|
||||
const v=this.viewport,g=this.graph,{width,height}=this.viewportSize();if(!g||!width||!height)return;
|
||||
this.autoFit=true;this.scale=Math.max(.001,Math.min(1,(width-40)/g.width,(height-40)/g.height));
|
||||
this.applyScale();v.scrollTo(0,0);
|
||||
}
|
||||
zoom(factor) {
|
||||
|
||||
Reference in New Issue
Block a user