26

是否可以获得<div />已经用 CSS3 属性转换的 a 的四个实际角坐标,例如scale,skewrotate

例子:

在 CSS3 转换之前,坐标是

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

和 div 看起来像这样:

转型前

经过一点 CSS3 魔术后transform: skew(10deg, 30deg) rotate(30deg) scale(1, 2); ,它看起来像这样:

改造后

如何获取实际角(不是边界框)的坐标(使用 javascript)?非常感谢任何帮助。

4

4 回答 4

23

经过数小时试图计算所有变换并几乎绝望地放弃后,我想出了一个简单而天才的小技巧,这使得获得变换的角点变得非常容易<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()
于 2013-06-13T23:06:27.410 回答
4

我认为没有API。以及在 HTML5 中没有用于转换坐标的 API <canvas>。但是有一种方法可以手动计算坐标。这是我的<canvas>库中的一个转换坐标的类:https ://github.com/enepomnyaschih/jwcanvas/blob/master/jwidget/public/jwcanvas/transform.js

您可以将其用作模板。

要初始化坐标系,您应该只实例化一个JW.Canvas.Transform类对象并应用方法complex。之后,您可以通过transform方法将其他变换应用于坐标系。矩阵是:

  • 翻译:[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方法计算反向转换对象。

于 2013-06-13T13:26:47.337 回答
4

我向您推荐这个网站:http ://www.useragentman.com/blog/2011/01/07/css3-matrix-transform-for-the-mathematically-challenged/尤其是“关于矩阵的其他有趣事实”部分“……

但正如 Egor Nepomnyaschih 指出的那样,您只需要为每个转换实现微积分并将它们链接起来。

我已经根据您的示例实现了一个 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>}

于 2013-06-13T14:58:03.507 回答
-1

您可以使用 .getBoundingClientRect() 找到元素相对于窗口的新位置

于 2016-09-16T18:46:53.140 回答