JavaScript:用于CSS变换透视的矩阵操作

3
我正在使用这个脚本,它声称实现了规范中描述的matrix3d操作,但该脚本缺少矩阵透视操作,因此我"捣鼓"了一些东西,但我不确定它是否准确或正确。
// the perspective matrix to multiply with
CSSMatrix.Perspective = function(x, y, z){
  var m = new CSSMatrix();
  m.m13 = x;
  m.m23 = y;
  m.m33 = z;
  return m;
};

以及使用这个矩阵的方法

// myMatrix.perspective(x,y,z); to apply a perspective matrix
CSSMatrix.prototype.perspective = function(x, y, z){
  if (y == null) y = 0;
  if (z == null) z = 0;
  return CSSMatrix.multiply(this, CSSMatrix.Perspective(x, y, z));
};

我的问题是,如果yzundefined,应该使用什么值?它会像旋转一样使用x作为所有其他轴,还是像上面的代码中一样使用0(零)?
我也不确定CSSMatrix.Perspective矩阵是否按规范正确编写并实现到CSSMatrix原型中。
更新: 我发现了另一个透视函数的实现(请参见下文),并创建了一个fiddle来演示它也无法正常工作。
CSSMatrix.prototype.perspective = function(d){
  return CSSMatrix.multiply(this, CSSMatrix.Perspective(d));
};
CSSMatrix.Perspective = function(d){
  var m = new CSSMatrix(); 
  m.m43 = -1/d; 
  return m;
};

为什么这两个值不同呢?谢谢您的回复。
2个回答

3
这里的问题似乎在于规范/文档(例如Mozilla CDN docs)中表示3D矩阵的方式与CSSMatrix polyfill code 中表示的方式不同。该代码使用了一个转置版本的矩阵,该矩阵在文档中被表示为正确的矩阵。代码可以正常工作,但如果考虑规范/文档中使用的矩阵,则代码所指的矩阵位置[3,4]实际上是位置[4,3]。
关于计算透视的公式:根据MDN文档here,应使用/乘以以下矩阵来应用透视(d是透视值):
a1 a2 a3 a4    1 0  0   0
b1 b2 b3 b4 =  0 1  0   0
c1 c2 c3 c4    0 0  1   0
d1 d2 d3 d4    0 0 −1/d 1 

所以你走在了正确的道路上,但是由于polyfill代码内部引用矩阵的方式不同,你错误地构建了透视矩阵。请使用m.m34 = -1/d;而不是m.m43 = -1/d;

我已经更新了修复后的代码在这里


非常感谢,这确实是有问题的,但出于某种原因,在我的设置中它无法正常工作,似乎透视必须始终在对象中首先出现。 - thednp
@thednp - 我可以确认从我的Fiddle测试中,perspective需要是transform参数中的第一个。 - nhylated
是的,我会确保按正确顺序重新排列对象元素:透视、旋转/扭曲、平移、缩放;再次感谢。 - thednp
我修复了属性顺序的问题,但是遇到了另一个问题,也许你可以看一下http://stackoverflow.com/questions/35892678/javascript-issue-with-360deg-rotations-and-matrix-composition - thednp

0
根据“视角”属性的规范,它只接受一个参数,即“长度”。它不接受X、Y和Z。
参考文献:W3ORG - Perspective Property 参考文献:W3School的透视示例 我知道我没有给出您的视角解决方案,但所写的不是预期的行为。如果我对您的问题的理解有误,请告诉我,我会尽力帮助您。谢谢。

谢谢。尽管您的回答没有帮助我,但是我找到了类似这样的东西https://github.com/amadeus/transformer/blob/master/src/transformer.js#L528-L535,但将其适应到我的代码中时它不起作用。 - thednp
我已经更新了问题并发现了新的情况,你能否请看一下? - thednp
你好朋友,我看了你添加的新参考代码。我也看了你的fiddle,但是即使付出了很多努力,我也无法得到确切的答案。很抱歉没有对你有所帮助。希望你能尽早找到解决方案。谢谢。 - Vinod Tigadi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接