在CSS3变换后获取div的实际像素坐标

时间:2013-06-13 12:53:27

标签: javascript jquery css3 transform

是否有可能获得<div />的四个实际角点坐标,这些坐标已使用CSS3属性转换为scaleskewrotate

示例:

在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)? 非常感谢任何帮助。

4 个答案:

答案 0 :(得分:19)

在数小时后尝试计算所有变换并且几乎绝望地放弃了我想出了一个简单而又天才的小黑客,这使得非常容易来获得变换的{{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>

现在使用jQuery(或纯js)来检索位置是一块蛋糕:

.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;
}           

答案 1 :(得分:4)

我认为没有API。除了在HTML5 <canvas>中转换坐标之外,没有API。但是有一种方法可以手动计算坐标。以下是我的<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方法计算向后转换对象。

答案 2 :(得分: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>}形式的对象。

答案 3 :(得分:-1)

您可以使用.getBoundingClientRect()

找到元素对应窗口的新位置