2016-03-04 2 views
1

У меня есть DIV, который был преобразован с использованием матрицы.Как вычислить размер ограничивающих прямоугольников для элемента DOM, на котором применяется матрица преобразования CSS? Без использования Element.getBoundingClientRect()

Мне нужно рассчитать некоторую информацию относительно размера ограничивающих прямоугольников.

Конкретно мне нужно выяснили: ширина, высота, поворот (град из матрицы)

я не могу использовать Element.getBoundingClientRect()

Я мужественным интересное в математике решения, при условии, что у меня есть все данные, необходимые для выполнения рендеринга div заранее (например: верхняя, левая позиция), любые обратные связи приветствуются.

В этом примере зеленый квадрат представляет собой визуальное представление о измерении, которое мне нужно выяснить.

#box { 
 
    position: absolute; 
 
    top: 100px; 
 
    left: 100px; 
 
    width: 200px; 
 
    height: 200px; 
 
    background-color: red; 
 
    transform: matrix(0.707107, 0.707107, -0.707107, 0.707107, -0.707107, 34.6482); 
 
} 
 

 
#result { 
 
    position: absolute; 
 
    height: 282.8427734375px; 
 
    left: 57.871490478515625px; 
 
    top: 93.22679901123047px; 
 
    width: 282.8428039550781px; 
 
    border: 1px solid green; 
 
}
<div id="box"></div> 
 
<div id="result"></div>

+1

_ «Я не могу использовать Element.getBoundingClientRect()» _ Почему? – guest271314

+0

Спасибо за комментарий. Мне нужно минималистическое DOM-запрос для моего приложения, в этом вопросе я упростил свой вариант использования. Мне нужно математическое решение, если это возможно, поэтому я могу найти правильные размеры без операций DOM. – GibboK

+0

Что вы подразумеваете под «без операций DOM»? – guest271314

ответ

1

Когда вы говорите «без операций DOM» Я предполагаю, что у вас есть все данные, необходимые для выполнения расчета вручную заранее. В частности, у вас есть координаты (left, top) и размеры предварительно преобразованного прямоугольника размером width/height, а также детали каждого преобразования, которое было применено к прямоугольнику, и в правильном порядке. В этом случае, я бы сначала построить четыре пункта следующим образом, который представляет собой предварительно трансформированные прямоугольник:

  • p1 = (left, top)
  • p2 = (left + width, top)
  • p3 = (left, top + height)
  • p4 = (left + width, top + height)

Тогда я бы применить цепь трансформации в каждую из этих четырех точек, чтобы получить p1', p2', p3', p4'.

Тогда я бы работать над каждым p' и макс/мин top/left координаты всех из них:

  • max_top
  • min_top
  • max_left
  • min_left

сейчас , из этой информации Я могу получить следующее:

  • (min_left, min_top) даст нам верхнюю левую точку ограничивающего прямоугольника.
  • (max_left - min_left, max_top - min_top) даст нам размеры ограничивающего прямоугольника.

Однако было бы проще, если бы вы могли просто запросить матрицу преобразования элемента и разбить ее компоненты на поплавки.Затем используйте математическую библиотеку JS (например, numericJS), чтобы построить матрицу трансформации из этих компонентов и использовать ее для преобразования ваших точек.

Вот фрагмент, который может быть использован для извлечения матрицы numericJS из CSS transform свойства элемента:

getTransformationMatrix: function (element) { 
    var transform = element.css('transform'); 

    // Verify that the returned result is valid 
    if (transform && transform !== "none" && transform !== "") { 
     // The returned string from 'element.css('transform')' has the following template - 'matrix(a, c, b, d, tx, ty)'. We would like to extract the values of a, b, c and d, 
     // in order to use them to construct a Matrix object which will represent the following matrix: 
     // a b tx 
     // (c d ty) 
     // 0 0 1 
     // For more information, please see https://developer.mozilla.org/en-US/docs/Web/CSS/transform 
     var transformValues = transform.split('(')[1].split(')')[0].split(','); 

     var a = parseFloat(transformValues[0]); 
     var c = parseFloat(transformValues[1]); 
     var b = parseFloat(transformValues[2]); 
     var d = parseFloat(transformValues[3]); 
     var tx = parseFloat(transformValues[4]); 
     var ty = parseFloat(transformValues[5]); 

     return [[a, b, tx], [c, d, ty], [0, 0, 1]]; 
    } 

    // return the identity matrix if no transformation is set on the element. 
    return new [[1, 0 ,0], [0, 1, 0], [0, 0, 1]]; 
} 

Теперь вы можете использовать его, чтобы преобразовать заданную точку:

function getTransformedPoint(matrix, point) { 
    return numeric.dot(matrix, [p.left, p.top, 1]); 
} 

var matrix = getTransformationMatrix(element); 
transformedP1 = getTransformedPoint(matrix, p1); 
transformedP2 = getTransformedPoint(matrix, p2); 
transformedP3 = getTransformedPoint(matrix, p3); 
transformedP4 = getTransformedPoint(matrix, p4); 
+0

Включили ли вы поворот на своем примере? – GibboK

+0

Нет, я имел в виду общий случай. Если это все о вращении, я бы сначала перевел все свои точки (-rotationCenter.left, - rotationCenter.top), тогда я буду поворачивать все свои точки на X градусов с помощью преобразования вращения вращения, тогда я переведу все указывает на (rotationCenter.left, rotationCenter.top). – gipouf

+1

вы можете использовать http://www.numericjs.com/ для выполнения преобразований. – gipouf

Смежные вопросы