我正在使用canvas元素处理html,css和javascript。有时这些画布会对它们应用css3三维变换(包括缩放,旋转和平移),我需要预测我的三维变换画布中的二维渲染位置,我有一些问题用它。
转换实际上没有应用于画布本身;它们被应用于画布周围的两个容器div:
<div class="viewport">
<div class="container-outer">
<div class="container-inner">
<canvas></canvas>
</div>
</div>
</div>
我有两个容器的原因是我可以同时应用两个转换。我在变换上激活了css过渡,所以我可以,例如,在一个容器上进行x变换,在另一个容器上进行y变换,如果它们有单独的缓动函数,则生成的动画是曲线而不是直线运动。
我试图预测容器内部四个角的位置。我正在使用的方法是正确预测翻译和缩放的结果,但不是旋转。这是它的工作原理。我从一个角落的已知原始位置开始,比如[0,0,0]。为了示例,我们将说我的所有div和画布都是500px x 500px,并且我在视口div上设置了500px的透视图。所以我的观点来源是[250,250,500]。因此,我采用我已知的角位置,将其转换为异构4x1向量矩阵[0,0,0,1],并使用matrixVectorMultiply()将其乘以对应于应用于容器内部的变换的matrix3d css矩阵。我获取结果向量并再次使用matrixVectorMultiply()将其乘以与应用于container-outer的转换相对应的matrix3d css矩阵。
matrixVectorMultiply = function(mx, vec)
{ // Given a 4x4 transformation matrix and an xyz vector, this will return the dot product (a new vector)
if (typeof vec.z == 'undefined')
{
vec.z = 0;
}
return {
x: vec.x*mx.array[0] + vec.y*mx.array[1] + vec.z*mx.array[2] + mx.array[3]
,y: vec.x*mx.array[4] + vec.y*mx.array[5] + vec.z*mx.array[6] + mx.array[7]
,z: vec.x*mx.array[8] + vec.y*mx.array[9] + vec.z*mx.array[10] + mx.array[11]
};
};
'vec'是一个具有x,y和z属性的简单对象。 'mx'是一个简单的对象,有两个属性,'array'包含matrix3d转换数组的row-primary数组表示,'string'包含该数组的列主要字符串表示,可以插入CSS转换属性。
现在我有一个三维坐标应该是我的角落的新位置,在外部和内部过渡都已执行之后。但我需要将3d坐标投影到我的2D视图窗口中,具有以下功能:
projection3d = function(pos, origin)
{ // Given an xyz point and an xyz perspective origin point, this will return the xy projected location
// Using the equation found here: http://en.wikipedia.org/wiki/3D_projection#Diagram
var pos2d = {x: null, y: null, z: null},
relPos2d = {x: null, y: null},
relPos = {x: null, y: null, z: null};
// First, we take our given point and locate it relative to the perspective origin, rather than the screen
relPos.x = pos.x - origin.x;
relPos.y = pos.y - origin.y;
relPos.z = pos.z - origin.z;
// Then we take this object and project it onto our 2d plane
relPos2d.x = relPos.x * (Math.abs(origin.z) / Math.abs(relPos.z));
relPos2d.y = relPos.y * (Math.abs(origin.z) / Math.abs(relPos.z));
// Then we take this and locate it relative to the screen again, instead of the perspective origin
pos2d.x = relPos2d.x + origin.x;
pos2d.y = relPos2d.y + origin.y;
return pos2d;
};
我获取该函数的结果并在视觉上将其与浏览器中的css 3d变换的实际结果进行比较,并发现正确预测了翻译和缩放,但没有轮换,我不能为生活我明白为什么不。
有没有人有任何见解?我应该提供进一步的信息吗?