BBox расчет элементов SVG <g> - PullRequest
       108

BBox расчет элементов SVG <g>

0 голосов
/ 14 декабря 2018

Я только что натолкнулся на утомительный случай вычисления прыгающего бокса, и, похоже, я еще не понял всей правды.

Прежде всего, ограничивающий прямоугольник определяется как самый жесткий прямоугольник, нетрансформированный элемент может быть заключен в.

У меня всегда было впечатление, что для групп это означает, что он получает в основном объединение ограничивающего прямоугольника всех детей.

Однако сегодня я столкнулся с этим:

<g id="outer">
  <g id="inner" transform="translate(100, 100)">
    <rect x="0" y="0" width="100" height="100" />
  </g>
</g>

Ограничительные рамки элементов следующие:

  • rect: x: 0, y: 0, w: 100, h: 100
  • #inner: x: 0, y: 0, w: 100, h: 100
  • #outer: x: 100, y: 100, w: 100, h: 100

Я ожидал бы, что все коробки одинаковы, но, как вы можете видеть, внешняя коробка НЕ ​​является объединением внутренних элементов (в этом случае этобудет равна bbox # inner).Вместо этого он принимает во внимание преобразование внутренних элементов.

Итак, правильно ли говорить, что bbox группы является объединением TRANSFORMED bbox его дочерних элементов?Или, если говорить более программно, объединение всех getBoundingClientRect вызовов (при условии, что прокрутка равна 0, потому что getCoundingClientRect игнорирует прокрутку)?

Я был бы очень признателен за ссылку , указывающую мне на правильныйчасть спецификации.

Ответы [ 2 ]

0 голосов
/ 14 декабря 2018

В этой демонстрации красный многоугольник представляет BBox #outer во время анимации, в которой вращается прямоугольник.

const SVG_NS = 'http://www.w3.org/2000/svg';
let o = outer.getBBox()
let i = inner.getBBox()

let BBpoly = drawBBox(o); 



function drawBBox(bb){
  let p = [{x:bb.x,y:bb.y},
           {x:bb.x+bb.width,y:bb.y},
           {x:bb.x+bb.width,y:bb.y+bb.height},
           {x:bb.x,y:bb.y+bb.height}];
  let BBpoly = drawPolygon(p, BBoxes);
  return BBpoly;
}


function drawPolygon(p, parent) {
  let poly = document.createElementNS(SVG_NS, 'polygon');
  let ry = [];
  for (var i = 0; i < p.length; i++) {
    ry.push(String(p[i].x + ", " + p[i].y));
  }
  var points = ry.join(" ");
  poly.setAttributeNS(null, 'points', points);

  parent.appendChild(poly);
  return poly;
}


function updatePolygon(p,poly){
  let ry = [];
  for (var i = 0; i < p.length; i++) {
    ry.push(String(p[i].x + ", " + p[i].y));
  }
  var points = ry.join(" ");
  poly.setAttributeNS(null, 'points', points);
}

let a = 0;
function Frame(){
  requestAnimationFrame(Frame);
  inner.setAttributeNS(null,"transform", `rotate(${a}, 120,120)`)
  let bb = outer.getBBox()
  let p = [{x:bb.x,y:bb.y},
           {x:bb.x+bb.width,y:bb.y},
           {x:bb.x+bb.width,y:bb.y+bb.height},
           {x:bb.x,y:bb.y+bb.height}];
  updatePolygon(p,BBpoly);
  
  a++
}

Frame()
svg{border:1px solid; width:300px;}
polygon{fill:none; stroke:red; }
<svg viewBox="0 0 250 250">
  <g id="BBoxes"></g>
  <g id="outer">
  <g id="inner">
    <rect x="70" y="70" width="100" height="100"  />
  </g>
</g>
</svg>
0 голосов
/ 14 декабря 2018

Ограничительная рамка, возвращаемая getBBox, является коробкой в ​​преобразованной системе координат элемента

Возвращает ограничивающую рамку в текущем пользовательском пространстве (т. Е. После применения 'атрибут transform ', если имеется) для геометрии всех содержащихся графических элементов, исключая эффекты обводки, отсечения, маскировки и фильтрации) ...

Внешний элемент SVG имеет другую систему координат,Т.е. место, где он размещает источник, не совпадает с внутренним элементом <g> из-за преобразования внутреннего элемента.

getBoundingClientRect, однако, работает в глобальной системе координат.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...