尝试动态获取任意变换元素的顶点角。将各种解决方案混合在一起产生的结果在所有变换都是3d时都能很好地工作。见.. https://jsfiddle.net/xux8h8h0/13/
但是当同一继承链中存在2d和3d变换时不起作用。
$ SPACE_TAB=" "; sed -ne '/^SUBDIRS/,/^['"$SPACE_TAB"']*$/p' test.in
SUBDIRS = \
text1 \
text2 \
# commented text
text3 \
text4 \
$(".target").on('click', function() {
//remove vertices from last click
$(".vertex").remove();
scrollpos=getScroll();
//store nested transforms
var transforms = [];
//walk up the DOM and get all transforms effecting this element
var p = this;
while (p && p.nodeType==1) {
var computedStyle = getComputedStyle(p);
//parse a 4x4 matrix from the matrix string
var t = parseTransformMatrix(computedStyle.transform);
var css=computedStyle.transform;
//if there was a transform applied,let's remember it
if (t) {
// get the transform origin
//Set the transform to NOE since we'll need to get the child elements un transformed rectangle at the end
var origin=computedStyle.transformOrigin;
p.style.transform = 'none';
//add an object to the transforms array holding useful info
transforms.unshift({
matrix: t,
element: p,
origin:origin,
css: css
})
}
p=p.parentNode;
}
//ALL applied transforms have been undone. Let's get the untransformed rectangle of the element
var box = this.getBoundingClientRect();
var i = 0;
while (i < transforms.length) {
var origin = parseTransformOrigin(transforms[i].origin);
var bbox=transforms[i].element.getBoundingClientRect();
transforms[i].origin=origin;
transforms[i].origin[0]+= bbox.left;
transforms[i].origin[1]+=bbox.top;
i++;
}
i = 0;
while (i < transforms.length) {
transforms[i].element.style.transform = transforms[i].css;
i++;
}
//var points=getBoxPoints(box);
//
var points=[
[box.left,box.top,0,1],
[box.right,box.top,0,1],
[box.right,box.bottom,0,1],
[box.left,box.bottom,0,1]
];
for(var k=0;k<points.length;k++){
var point=points[k];
var prev=[];
i = 0;
while (i < transforms.length) {
var org=transforms[i].origin;
prev.push(transforms[i]);
var mat=computeTransformMatrix(transforms[i].matrix.matrix,org);
var tp=transformVertex(mat,point);
var pv=projectVertex(tp);
point[0]=pv[0];
point[1]=pv[1];
var m=i;
var scrollpos=getScroll();
i++;
}
var vertex = document.createElement('div');
vertex.setAttribute('class','vertex');
vertex.style.left = (point[0]+scrollpos[0])+ "px";
vertex.style.top = (point[1]+scrollpos[1])+"px";
vertex.style.zIndex=99;
document.body.appendChild(vertex);
}
});
function parseTransformMatrix(computedStyle) {
var style = computedStyle;
if (style == 'none') {
return false;
}
var matrix = style.split('(')[1].split(')')[0].split(',');
var fullMatrix = new Matrix(4, 4);
if (matrix.length<16) {
//2d matrix
fullMatrix.matrix[0][0] = parseFloat(matrix[0]);
fullMatrix.matrix[1][0] = parseFloat(matrix[1]);
//
fullMatrix.matrix[0][1] = parseFloat(matrix[2]);
fullMatrix.matrix[1][1] = parseFloat(matrix[3]);
//
fullMatrix.matrix[0][3] = parseFloat(matrix[4]);
fullMatrix.matrix[1][3] = parseFloat(matrix[5]);
}
else{
//column 1
fullMatrix.matrix[0][0] = parseFloat(matrix[0]);
fullMatrix.matrix[1][0] = parseFloat(matrix[1]);
fullMatrix.matrix[2][0] = parseFloat(matrix[2]);
fullMatrix.matrix[3][0] = parseFloat(matrix[3]);
//column 2
fullMatrix.matrix[0][1] = parseFloat(matrix[4]);
fullMatrix.matrix[1][1] = parseFloat(matrix[5]);
fullMatrix.matrix[2][1] = parseFloat(matrix[6]);
fullMatrix.matrix[3][1] = parseFloat(matrix[7]);
//column 3
fullMatrix.matrix[0][2] = parseFloat(matrix[8]);
fullMatrix.matrix[1][2] = parseFloat(matrix[9]);
fullMatrix.matrix[2][2] = parseFloat(matrix[10]);
fullMatrix.matrix[3][2] = parseFloat(matrix[11]);
//column 4
fullMatrix.matrix[0][3] = parseFloat(matrix[12]);
fullMatrix.matrix[1][3] = parseFloat(matrix[13]);
fullMatrix.matrix[2][3] = parseFloat(matrix[14]);
fullMatrix.matrix[3][3] = parseFloat(matrix[15]);
}
return fullMatrix;
}
function parseTransformOrigin(style) {
var origin = style.split(' ');
var out = [ 0, 0, 0, 1 ];
for (var i = 0; i < origin.length; ++i)
{
out[i] = parseFloat(origin[i].trim());
}
return out;
}
function Matrix(cols, rows) {
this.matrix = [];
var i = 0;
while (i < rows) {
var j = 0;
this.matrix.push([]);
while (j < cols) {
var val =0;
if(i==j){val=1}
this.matrix[i].push(val);
j++;
}
i++;
}
}
function transformVertex(mat, vert)
{
var out = [ ];
for (var i = 0; i < 4; ++i)
{
var sum = 0;
for (var j = 0; j < 4; ++j)
{
sum += +mat[i][j] * vert[j];
}
out[i] = sum;
}
return out;
}
function projectVertex(vert)
{
var out = [ ];
for (var i = 0; i < 4; ++i)
{
out[i] = vert[i] / vert[3];
}
return out;
}
function getScroll(){
if(window.pageYOffset!= undefined){
return [pageXOffset, pageYOffset];
}
else{
var sx, sy, d= document, r= d.documentElement, b= d.body;
sx= r.scrollLeft || b.scrollLeft || 0;
sy= r.scrollTop || b.scrollTop || 0;
return [sx, sy];
}
}
function createTranslateMatrix(x, y, z)
{
var out =
[
[1, 0, 0, x],
[0, 1, 0, y],
[0, 0, 1, z],
[0, 0, 0, 1]
];
return out;
}
function multiply(pre, post)
{
var out = [ [], [], [], [] ];
for (var i = 0; i < 4; ++i)
{
for (var j = 0; j < 4; ++j)
{
var sum = 0;
for (var k = 0; k < 4; ++k)
{
sum += (pre[k][i] * post[j][k]);
}
out[j][i] = sum;
}
}
return out;
}
function computeTransformMatrix(tx, origin)
{
var out;
var preMul = createTranslateMatrix(-origin[0], -origin[1], -origin[2]);
var postMul = createTranslateMatrix(origin[0], origin[1], origin[2]);
var temp1 = multiply(preMul, tx);
out = multiply(temp1, postMul);
return out;
}
html,
body {
height: 100%;
background-color: #ddd;
padding: 55px;
margin:0px;
}
/* 2d transform in chain*/
#nested {
transform: translate(20px) rotate(-10deg);
//transform: translate(20px) rotate(-10deg);
}
/* 3d transform in chain*/
#transformed {
transform: perspective(600px) translateX(40px) rotateY(40deg) rotateX(40deg);
//transform: rotate(90deg);
width: 400px;
height: 400px;
background-color: #dd0000;
border: 2px solid black;
}
.target {
width: 80px;
height: 80px;
background-color: #0000dd;
border: 2px solid white;
}
.vertex {
position: absolute;
border: 3px solid black;
border-radius: 5px;
background-color: black;
width:1px;
height:1px;
}
请参阅.. https://jsfiddle.net/wsf4rv54/1/
这是为什么?第一个链接中的最后一个蓝色方块(所有三维变换)透视图似乎逐渐使顶点元素错过了标记,我也无法弄明白。
答案 0 :(得分:0)
虽然这不能解决您的问题,但它可能会指向正确的方向......
在第二个示例中,您在第一个rotate(-10deg)
中使用了rotateX(-10deg)
。在css的3d空间中rotate
等于rotateZ
,而不是rotateX
。