Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/407.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 查找viewbox以使所有元素都可见_Javascript_Svg - Fatal编程技术网

Javascript 查找viewbox以使所有元素都可见

Javascript 查找viewbox以使所有元素都可见,javascript,svg,Javascript,Svg,我有一个svg DOM元素。它可以有几个子元素,从简单的元素(如矩形)到更复杂的元素(如路径) 是否有可能为svg元素找到一个视图框,以便所有元素都可见,但不会太小。假设到每一侧的最远距离应为svg宽度的25% 我目前的想法是首先找到所有子对象的x和y值的最小值和最大值,然后根据这些值计算视口,但这似乎是一项相当繁琐的任务(特别是对于路径等元素) 函数findMinMax(元素){ 设min={x:Math.Infinity,y:Math.Infinity}; 设max={x:-Math.Inf

我有一个svg DOM元素。它可以有几个子元素,从简单的元素(如矩形)到更复杂的元素(如路径)

是否有可能为svg元素找到一个视图框,以便所有元素都可见,但不会太小。假设到每一侧的最远距离应为svg宽度的25%

我目前的想法是首先找到所有子对象的x和y值的最小值和最大值,然后根据这些值计算视口,但这似乎是一项相当繁琐的任务(特别是对于路径等元素)

函数findMinMax(元素){
设min={x:Math.Infinity,y:Math.Infinity};
设max={x:-Math.Infinity,y:-Math.Infinity};
开关(oElement.tagName){
案例“rect”:
min.x=rect.getAttribute(“x”);
min.y=rect.getAttribute(“y”);
max.x=rect.getAttribute(“x”)+rect.getAttribute(“宽度”);
max.y=rect.getAttribute(“y”)+rect.getAttribute(“高度”);
打破
案例“多边形”:
//...
打破
案例“多段线”:
//...
打破
案例“行”:
//...
打破
案例“圆圈”:
//...
打破
案例“路径”:
//...
打破
}
[…element.children].forEach(c=>{
设o=findMinMax(c);
如果(o.min.x
有人有更好的方法吗?

调用每个元素。所有SVGLocatable元素都支持该方法,所有图形元素都派生自SVGLocatable

如果将所有元素放入
容器中,则可以在
上调用getBBox,浏览器将为您完成所有计算。
元素也可以工作,因此您甚至可能不需要创建容器。

就像Robert说的(我以前做过)如果您想要一个完整的示例-

出于某种原因,下面沙箱中的代码一直没有响应,但在codePen中工作良好

双击时,svg viewbox将更改为使用b_box技术进行尽可能多的缩放

演示:

const svgDrawing=document.getElementById('drawing');
//console.log(svgDrawing.currentTranslate);
让viewbox=svgDrawing.viewbox.baseVal;
//console.log(“viewbox”,viewbox);
让原稿w=viewbox.width;
让原始高度=viewbox.height;
设w_h_比=2;
const g=document.getElementById('437');
//log(g.transform.baseVal.consolid().matrix);
//const extra=document.getElementById('example');
//log(extra.transform.baseVal.consolid().matrix);
const b_box_br=document.getElementById('b_box_bottomRight');
const b_box_tl=document.getElementById('b_box_左上角');
const b_box_max={左:无限,上:无限,右:0,下:0};
var point=svgDrawing.createSVGPoint();
功能ZoomeEvent(evt){
evt.preventDefault();
如果(evt.deltaY>1){
zoomInOut(-1,10);
}否则{
zoomInOut(+1,10);
}
}
函数缩放(方向、步长){
如果(方向>0){
viewbox.width-=w_h_比率*步长;
viewbox.height-=步长;
}否则{
viewbox.width+=w_h_比率*步长;
viewbox.height+=步长;
}
}
函数缩放(x、y、宽度、高度){
viewbox.x=x;
viewbox.y=y;
viewbox.width=宽度;
viewbox.height=高度;
}
函数zoomFull(evt){
console.log('full')
evt.preventDefault();
viewbox.width=原始宽度;
viewbox.height=原始高度;
console.log(“缩放100%”);
常量元素=[…svgDrawing.childNodes];
console.log(“元素”,元素);
var-inside=true;
对于(元素的el){
如果(el.nodeName==“#text”){
//这不是一个真正的节点
}else if(el.id.包括('b_-box')){
//这些只是我们的向导节点
}else if(元素符号(el、svgDrawing)){
内=真;
}否则{
内=假;
}
}
//var dir=内部?+1:-1;
//动物输出(dir,(100/(10**i));
缩放缩放(最大框左、最大框顶、,
b_盒(最大宽度,b_盒(最大高度));
}
功能元件集成(el,盒子){
var结果=假;
el_rect=el.getBoundingClientRect();
点x=右上角;
点y=垂直底部;
var invertedSVGMatrix=el.getScreenCTM().inverse();
var p=点矩阵变换(DSVGMatrix);
点x=左上角;
点y=垂直顶部;
var p2=点矩阵变换(DSVGMatrix);
设trans=el.transform.baseVal;
如果(横向长度>0){
常量矩阵=trans.consolidate().矩阵;
p、 x+=矩阵e;
p、 y+=矩阵f;
p2.x+=矩阵.e;
p2.y+=矩阵f;
}
如果(p.x>b_盒最大右侧){
b_box_br.setAttribute('cx',p.x.);
b_box_max.right=p.x;
}
如果(p.y>b_盒最大底部){
b_box_br.setAttribute('cy',p.y.);
b_箱_最大底部=p.y;
}
b_box_br.setAttribute('r',5);
如果(p2.x=box_rect.left&&
el_rect.right zoomEvent(e));
addEventListener('dblclick',e=>zoomFull(e));
//resizeSVG();
window.onresize=函数(){
console.log(window.innerWidth、window.innerHeight);
//console.log(window.innerWidth、window.innerHeight);
resizeSVG();
};
函数resizeSVG(){
如果((window.innerWidth-40)/w_h_比率>(window.innerHeight-120)){
svgDrawing.setAttribute(“高度”,window.innerHeight-120);
svgDrawing.setAttribute(“宽度”,宽高比*(窗口
function findMinMax(element) {
  let min = {x: Math.Infinity, y: Math.Infinity};
  let max = {x: -Math.Infinity, y: -Math.Infinity};

  switch (oElement.tagName) {
    case "rect":
      min.x = rect.getAttribute("x");
      min.y = rect.getAttribute("y");
      max.x = rect.getAttribute("x") + rect.getAttribute("width");
      max.y = rect.getAttribute("y") + rect.getAttribute("height");
      break;
    case "polygon":
      //...
      break;
    case "polyline":
      //...
      break;
    case "line":
      //...
      break;
    case "circle":
      //...
      break;
    case "path":
      //...
      break;
  }

  [...element.children].forEach(c => {
    let o = findMinMax(c);
    if (o.min.x < min.x) min.x = o.min.x;
    if (o.min.y < min.y) min.y = o.min.y;
    if (o.max.x < max.x) max.x = o.max.x;
    if (o.max.y < max.y) max.y = o.max.y;
  });

  return {min, max};
}