预测css 3d变换像素的渲染

时间:2014-05-21 19:50:04

标签: css3 3d transformation

我正在使用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变换的实际结果进行比较,并发现正确预测了翻译和缩放,但没有轮换,我不能为生活我明白为什么不。

有没有人有任何见解?我应该提供进一步的信息吗?

0 个答案:

没有答案