XY координаты повернутых углов HTML-элементов

Пытаясь получить координаты XY HTML-элемента, я могу рассчитать физическое расстояние в пикселях от углов повернутого элемента относительно другого элемента.

Во фрагменте я пытаюсь вычислить расстояние от левого верхнего угла внутреннего элемента до центра внешнего элемента. Но у меня есть только значения Left и Top от не повернутого div. Мне нужно, чтобы значения отражали точку XY повернутого div. Есть ли способ получить эту точку, относительно окна просмотра или другого элемента?

я пробовал getBoundingClientRect() но это дает большие прямоугольные и неправильные координаты, потому что это на самом деле вертикальный прямоугольник, содержащий полный повернутый div.

Итак, есть ли способ получить эти координаты, пожалуйста?

document.getElementById('outRotated').innerHTML = clacDistancCornerCenter() + "  Rotated distance of corner to center: "


function clacDistancCornerCenter() {
  var outer = document.getElementById('outer');
  var inner = document.getElementById('inner');

  var centerX = outer.offsetWidth / 2;
  var centerY = outer.offsetHeight / 2;


  var innersCornerX = outer.offsetLeft;
  var innersCornerY = outer.offsetTop;

  //distance formula -> d = sqrt( pow( x2 - x1)  + pow( y2 - y1) )

  var distance = Math.sqrt(Math.pow(centerX - innersCornerX, 2) + Math.pow(centerY - innersCornerY, 2));

  return distance;
}

function calcDistHorizontal() {
  $('div').css('transform', 'rotate(0deg)');
  document.getElementById('outHorizontal').innerHTML = clacDistancCornerCenter()+ "  This Should be differnt when horizontal: ";
}
div {
  top: 15%;
  left: 20%;
  width: 50%;
  height: 50%;
  border: 1px solid black;
  position: absolute;
  display: block;
  transform: rotate(25deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="outRotated"> </p>
<p id="outHorizontal"> </p>

<button onclick="calcDistHorizontal()">Distance Horizontal</button>

<div id="outer">
  <div id="mid">
    <div id="inner">
    </div>
  </div>
</div>

3 ответа

Решение

Я нашел простое решение, без лишней математики... Я создаю новый элемент шириной 0px для представления точки. Я помещаю его в угол, который я хочу измерить, затем запрашиваю координаты области просмотра с помощью getBoundingClientRect(), который возвращает прямоугольный объект с верхним, нижним, левым и правым местами относительно окна просмотра экранов. А так как точечный элемент имеет ширину / высоту 0, то верхняя часть равна нижней, а левая равна правой.

clacDistancCornerCenter();


function clacDistancCornerCenter() {
  var center = document.getElementById('center').getBoundingClientRect();
  var corner = document.getElementById('corner').getBoundingClientRect();

  //alert("left =" + center.left + "top =" + center.top + "right =" + center.right + "bottom =" + center.bottom);

  var centerX = center.left;
  var centerY = center.top;


  var innersCornerX = corner.left;
  var innersCornerY = corner.top;

  //distance formula -> d = sqrt( pow( x2 - x1)  + pow( y2 - y1) )

  var distance = Math.sqrt(Math.pow(centerX - innersCornerX, 2) + Math.pow(centerY - innersCornerY, 2));

  document.getElementById('outRotated').innerHTML = "Distance center to corner: "+ distance;
}

function horizontal() {

  $('div').css('transform', 'rotate(0deg)');

}


function relocate(top, left) {
  var point = document.getElementById('corner');
  if (top) {
    point.style.bottom = 'auto';
    point.style.top = 0;
  } else {
    point.style.top = 'auto';
    point.style.bottom = 0;

  }

  if (left) {
    point.style.right = 'auto';
    point.style.left = 0;
  } else {
    point.style.left = 'auto';
    point.style.right = 0;
  }
  clacDistancCornerCenter();
}
div {
  top: 15%;
  left: 20%;
  width: 50%;
  height: 50%;
  border: 1px solid black;
  position: absolute;
  display: block;
  transform: rotate(25deg);
}
.point {
  width: 7px;
  height: 7px;
  background-color: blue;
  //border:3px solid blue;
  position: absolute;
  display: block;
}
#center {
  left: 50%;
  top: 50%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="outRotated"></p>
<p id="outRotated"> Set points width and height to 0 to get the actual correct distance. For now the points are large for easy understanding</p>

<br/>
<button onclick="relocate(true,true)">Top Left</button>-------
<button onclick="relocate(true,false)">Top Right</button>
<br/>
<button onclick="relocate(false,true)">Bottom Left</button>
<button onclick="relocate(false,false)">Bottom Right</button>
<br/>
<button onclick="horizontal()">Horizontal</button>

<div id="outer">
  <span id="center" class="point" onclick="outputXY()"></span>
  <div id="mid">
    <div id="inner">
      <span id="corner" class="point" onclick="outputXY()"></span>
    </div>
  </div>
</div>

Чтобы сделать это с любым преобразованием css 2d, вы можете использовать getComputedStyle и использовать матрицу преобразования, чтобы получить преобразованные координаты.

function calcElemTransformedPoint(elem, point)
{
    var style = getComputedStyle(elem);
    var transformOrigin = style.transformOrigin.split(' ').map(function(e)
    {
        // Remove 'px' and cast to number
        return +e.slice(0,-2);
    });
    var p = [point[0] - transformOrigin[0], point[1] - transformOrigin[1]];
    var transform = style.transform;
    // Matrix
    var m = [];
    if(transform.slice(0,7) === 'matrix(')
        m = transform.slice(7,-1).split(',').map(function(e){ return +e; });
    else
    {
        // 'matrix3d('
        var tmp = transform.slice(9,-1).split(',');
        m = [
            +tmp[0],
            +tmp[1],
            +tmp[4],
            +tmp[5],
            +tmp[12],
            +tmp[13]
        ];
    }
    // Matrix multiplication
    return [
        p[0] * m[0] + p[1] * m[2] + m[4] + transformOrigin[0],
        p[0] * m[1] + p[1] * m[3] + m[5] + transformOrigin[1]
    ];
}

Пример использования

Math!

Если у вас есть класс точек с именем Vector, со свойством x и a y, вы можете использовать такой метод, чтобы получить окончательные координаты XY:

vA.getVectorRotated = function(vB, angle){
   angle = angle*Math.PI/180;
   return new Vector( (Math.cos(angle) * (this.x - vB.x)
                     - Math.sin(angle) * (this.y - vB.y) + vB.x),
                      (Math.sin(angle) * (this.x - vB.x) 
                     + Math.cos(angle) * (this.y - vB.y) + vB.y) );
};
Другие вопросы по тегам