Получить фактические пиксельные координаты div после преобразования CSS3

Можно ли получить четыре фактических угловых координаты a <div />, которые были преобразованы с помощью атрибутов CSS3, таких как scale, skew и rotate?

Пример:

Перед преобразованием CSS3 координаты

x1y1: 0,0
x1y2: 0,200
x2y1: 200,0
x2yw: 200,200

и div выглядит следующим образом:

before transformation

после немного магии CSS3 transform: skew(10deg, 30deg) rotate(30deg) scale(1, 2); это выглядит так:

after transformation

Как получить координаты (с javascript) фактических углов (а не ограничивающие рамки)? Любая помощь была высоко оценена.

Ответы

Ответ 1

После нескольких часов, пытаясь рассчитать все преобразования и почти отчаявшись, я придумал простой, но гениальный маленький взлом, который делает его невероятно легким, чтобы получить угловые точки преобразованного <div />

Я добавил четыре ручки внутри div, которые расположены в углах, но невидимо, чтобы видеть:

<div id="div">
  <div class="handle nw"></div>
  <div class="handle ne"></div>
  <div class="handle se"></div>
  <div class="handle sw"></div>
</div>

.handle {
    background: none;
    height: 0px;
    position: absolute;
    width: 0px;
}   
.handle.nw {
    left: 0;
    top: 0;
}   
.handle.ne {
    right: 0;
    top: 0;
}   
.handle.se {
    right: 0;
    bottom: 0;
}       
.handle.sw {
    left: 0;
    bottom: 0;
}           

Теперь с jQuery (или чистым js) это кусок торта для извлечения позиции:

$(".handle.se").offset()

Ответ 2

Я не думаю, что для этого есть API. Как и API для преобразования координат в HTML5 <canvas>. Но есть способ вычислить координаты вручную. Вот класс из моей библиотеки <canvas>, которая преобразует координаты: https://github.com/enepomnyaschih/jwcanvas/blob/master/jwidget/public/jwcanvas/transform.js

Вы можете использовать его в качестве шаблона.

Чтобы инициализировать систему координат, вы должны просто создать экземпляр объекта класса JW.Canvas.Transform и применить метод complex. После этого вы можете применить другие преобразования для координации системы с помощью метода transform. Матрицы:

  • translate: [1, 0, 0, 1, x, y]
  • шкала: [x, 0, 0, y, 0, 0]
  • вращаются по часовой стрелке: [cos (a), sin (a), -sin (a), cos (a), 0, 0]
  • перекос вдоль x: [1, 0, tan (a), 1, 0, 0]
  • перекос вдоль y: [1, tan (a), 0, 1, 0, 0]

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

Ответ 3

Я рекомендую вам этот сайт: http://www.useragentman.com/blog/2011/01/07/css3-matrix-transform-for-the-mathematically-challenged/ и, в частности, раздел "Другие интересные факты о матрицах"...

Но, как указал Егор Непомнящих, вам просто нужно реализовать исчисление для каждого преобразования и связать их.

Я применил jsFiddle на основе вашего примера: http://jsfiddle.net/pvS8X/3/.

Просто будьте осторожны: происхождение - это середина вашей фигуры! Если вы хотите сослаться на верхний левый угол, вы должны установить это код CSS:

transform-origin: 0 0;

ср. https://developer.mozilla.org/fr/docs/CSS/transform-origin.

Основной метод:

function skew(p, alpha, beta) {
    var tan_a = Math.tan(alpha * Math.PI / 180),
        tan_b = Math.tan(beta * Math.PI / 180),
        p_skewed = {};

    p_skewed.x = p.x + p.y * tan_a;
    p_skewed.y = p.x * tan_b + p.y;

    return p_skewed;
}


function rotate(p, theta) {
    var sin_th = Math.sin(theta * Math.PI / 180),
        cos_th = Math.cos(theta * Math.PI / 180),
        p_rot = {};

    p_rot.x = p.x * cos_th - p.y * sin_th;
    p_rot.y = p.x * sin_th + p.y * cos_th;

    return p_rot;
}


function scale(p, sx, sy) {
    var p_scaled = {};

    p_scaled.x = p.x * sx;
    p_scaled.y = p.y * sy;

    return p_scaled;
}

где p - объект в форме { x: <some_horizontal_pos>, y: <some_vertical_pos>}.

Ответ 4

Вы можете найти новое положение своего элемента, соответствующее окну, используя .getBoundingClientRect()