问题
Is it possible to get the four actual corner coordinates of a <div />
that has been transformed with CSS3 attributes like scale
, skew
and rotate
?
Example:
Before the CSS3 transformation the coordinates are
x1y1: 0,0
x1y2: 0,200
x2y1: 200,0
x2yw: 200,200
and the div looks like this:

after a little bit of CSS3 magic transform: skew(10deg, 30deg) rotate(30deg) scale(1, 2);
it looks like this:

How can I get the coordinates (with javascript) of the actual corners (not the bounding box)? Any help greatly appreciated.
回答1:
After hours trying to calculate all the transformations and almost giving up desperately I came up with a simple yet genius little hack that makes it incredibly easy to get the corner points of the transformed <div />
I just added four handles inside the div that are positioned in the corners but invisible to see:
<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;
}
Now with jQuery (or pure js) it's a piece of cake to retrieve the position:
$(".handle.se").offset()
回答2:
I don't think that there is API for that. As well as there is no API to convert coordinates in HTML5 <canvas>
. But there is a way to calculate coordinates manually. Here is a class from my <canvas>
library which converts coordinates: https://github.com/enepomnyaschih/jwcanvas/blob/master/jwidget/public/jwcanvas/transform.js
You can use it as a template.
To initialize coordinate system, you should just instantiate an object of JW.Canvas.Transform
class and apply method complex
. After that, you can apply other transformations to coordinate system via transform
method. Matrixes are:
- translate: [1, 0, 0, 1, x, y]
- scale: [x, 0, 0, y, 0, 0]
- rotate clockwise: [cos(a), sin(a), -sin(a), cos(a), 0, 0]
- skew along x: [1, 0, tan(a), 1, 0, 0]
- skew along y: [1, tan(a), 0, 1, 0, 0]
After that, you'll be able to convert coordinates via convert
method. Use back
method to calculate backwards convertion object.
回答3:
I recommend to you this site : http://www.useragentman.com/blog/2011/01/07/css3-matrix-transform-for-the-mathematically-challenged/ and in particular the section "Other Interesting Facts About Matrices"...
But as Egor Nepomnyaschih pointed out, you just have to implement the calculus for each transformation and to chain them.
I have implemented a jsFiddle based on your example : http://jsfiddle.net/pvS8X/3/ .
Just be careful : the origin is the middle of your figure! If your want to refer to the top, left corner, you have to set this is your CSS code :
transform-origin: 0 0;
cf. https://developer.mozilla.org/fr/docs/CSS/transform-origin.
The main method are these one :
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;
}
where p is an object on the form { x: <some_horizontal_pos>, y: <some_vertical_pos>}
.
回答4:
You can find the new position of your element respective to the window using .getBoundingClientRect()
来源:https://stackoverflow.com/questions/17087577/get-actual-pixel-coordinates-of-div-after-css3-transform