autofit fixed and simplified, thx Mike ! (Mike code readapted for edge cases)
This commit is contained in:
+18
-62
@@ -1332,69 +1332,25 @@ class BZgraflow extends Buildoz{
|
||||
return(crossLayerLinks)
|
||||
}
|
||||
|
||||
/**
|
||||
* Union bounding boxes of nodes and wires (viewport coords).
|
||||
* Same measurement strategy as autofit(). Call with transform cleared for stable sizes.
|
||||
*/
|
||||
getContentSize(){
|
||||
let left = Infinity
|
||||
let top = Infinity
|
||||
let right = -Infinity
|
||||
let bottom = -Infinity
|
||||
|
||||
const includeBB = (bb) => {
|
||||
if(!bb) return
|
||||
left = Math.min(left, bb.left)
|
||||
top = Math.min(top, bb.top)
|
||||
right = Math.max(right, bb.right)
|
||||
bottom = Math.max(bottom, bb.bottom)
|
||||
}
|
||||
|
||||
this.nodesContainer?.querySelectorAll?.('.bzgf-node').forEach(nodeEl => includeBB(nodeEl.getBoundingClientRect()))
|
||||
this.wiresContainer?.querySelectorAll?.('path.bzgf-wire').forEach(path => includeBB(path.getBoundingClientRect()))
|
||||
|
||||
const gapx = parseInt(this.getBZAttribute('gapx')) || 80
|
||||
const gapy = parseInt(this.getBZAttribute('gapy')) || 80
|
||||
const hasBounds = Number.isFinite(left) && Number.isFinite(right) && Number.isFinite(top) && Number.isFinite(bottom)
|
||||
const rawWidth = hasBounds ? Math.max(right - left, 1) : Math.max(this.mainContainer?.clientWidth || this.offsetWidth || 1, 1)
|
||||
const rawHeight = hasBounds ? Math.max(bottom - top, 1) : Math.max(this.mainContainer?.clientHeight || this.offsetHeight || 1, 1)
|
||||
|
||||
return({
|
||||
left: hasBounds ? left : null,
|
||||
top: hasBounds ? top : null,
|
||||
right: hasBounds ? right : null,
|
||||
bottom: hasBounds ? bottom : null,
|
||||
rawWidth,
|
||||
rawHeight,
|
||||
width: rawWidth + (2 * gapx),
|
||||
height: rawHeight + (2 * gapy),
|
||||
gapx,
|
||||
gapy,
|
||||
})
|
||||
}
|
||||
|
||||
autofit(percent=100){
|
||||
if(!this.parentElement) return
|
||||
|
||||
const prevTransformOrigin = this.style.transformOrigin
|
||||
this.style.transform = 'none'
|
||||
this.style.transformOrigin = 'top left'
|
||||
|
||||
const { left, top, width: contentW, height: contentH, gapx, gapy } = this.getContentSize()
|
||||
const parentBB = this.parentElement.getBoundingClientRect()
|
||||
const sx = parentBB.width / contentW
|
||||
const sy = parentBB.height / contentH
|
||||
const scale = Math.min(sx, sy)*(percent/100) // uniform scale to fit inside parent
|
||||
const tx = left != null ? (-left + gapx) : gapx
|
||||
const ty = top != null ? (-top + gapy) : gapy
|
||||
if(!this.isSubflow) {
|
||||
this.style.transformOrigin = prevTransformOrigin || 'top left'
|
||||
this.style.transform = `scale(${scale}) translate(${tx}px, ${ty}px)`
|
||||
} else {
|
||||
this.style.transform = `scale(${scale})`
|
||||
this.style.width = `calc(100% / ${scale})` // means 100% of the parent node DESPITE the scaling
|
||||
this.style.height = `calc(100% / ${scale})` // means 100% of the parent node DESPITE the scaling
|
||||
autofit(percent=100){
|
||||
const outwidth = Math.max(this.clientWidth, 1)
|
||||
const outheight = Math.max(this.clientHeight, 1)
|
||||
let inwidth = this.nodesContainer.scrollWidth
|
||||
let inheight = this.nodesContainer.scrollHeight
|
||||
try { // SVG scrollWidth ignores overflowing paths; getBBox() covers wire extent.
|
||||
const wireBB = this.wiresContainer.getBBox()
|
||||
if(wireBB.width > 0 || wireBB.height > 0){
|
||||
inwidth = Math.max(inwidth, wireBB.x + wireBB.width)
|
||||
inheight = Math.max(inheight, wireBB.y + wireBB.height)
|
||||
}
|
||||
} catch(_){ // getBBox throws if SVG not rendered yet, but should not happen as we have _canRunAutoPlace() / _scheduleLayoutWhenReady()
|
||||
return
|
||||
}
|
||||
const ratio = Math.min( (outwidth / inwidth), (outheight / inheight) ) * (percent / 100)
|
||||
this.nodesContainer.style.scale = ratio
|
||||
this.wiresContainer.style.scale = ratio
|
||||
this.nodesContainer.style.transformOrigin = 'top left'
|
||||
this.wiresContainer.style.transformOrigin = 'top left'
|
||||
}
|
||||
}
|
||||
Buildoz.define('graflow', BZgraflow)
|
||||
|
||||
Reference in New Issue
Block a user