简体   繁体   English

CSS3转换Matrix3D动画闪烁,为什么?

[英]CSS3 Transform Matrix3D Animation Glitching, Why?

I've got it running in this fiddle . 我已经在小提琴中运行它了。 I'm trying to make two faces of a cube rotate, however the jump in front of each other, when they pass each other on the z-axis. 我试图使一个多维数据集的两个面旋转,但是当它们在z轴上彼此传递时,彼此之间的跳转。 All I want is to learn the basics of a Matrix 3D transform in the browser. 我只想在浏览器中学习Matrix 3D变换的基础知识。

I should add, I know that it's the z-axis crossing over, but the question is, can a DOM object not spread it's along the z-azis? 我应该补充一点,我知道这是z轴的交叉点,但是问题是,DOM对象是否不能沿z方位角传播? It seems it can only have one z-position for the whole object 似乎整个对象只能有一个z位置

I may have matrix calculations wrong, I'm certainly a 3D graphics noob, but I'm assuming things cannot be too far off, as the behaviour is pretty much as expected, aside from the obvious issue. 我可能对矩阵的计算有误,我当然是3D图形的傻瓜,但我假设事情不会太过遥远,因为除了明显的问题外,行为几乎与预期的一样。

Bonus Points: 奖励积分:

My z-axis rotation matrix is not behaving as I expected. 我的z轴旋转矩阵不符合我的预期。 I'm not sure why. 我不知道为什么。 The X and Y work, if you can also help with this, that'd be excellent. X和Y可以工作,如果您还可以提供帮助,那就太好了。

The Code: 编码:

HTML: HTML:

<div id="world" style="width: 400px, height: 400px">
    <div class="face" id="test" style="background-color: red;"></div>
    <div class="face" id="test2" style="background-color: pink;"></div>    
</div>

CSS: CSS:

#world {
    perspective: 100;
    perspective-origin:200px 200px;
    transform-style: preserve-3d;
}

.face{
    position: absolute;
    opacity: 0.9;
    top: 150px;
    left: 150px;
    width: 100px;
    height: 100px;
}

JS: JS:

DEG_TO_RAD = 0.017453292519943295;

function MatrixEl (el) {
    this.el = el;
    this.matrix = this.getMatrix();
    this.x = 0;
    this.y = 0;
    this.z = 0;
    this.xrot = 0;
    this.yrot = 0;
    this.zrot = 0;
    this.current_scale = 1;
}

MatrixEl.prototype.getMatrix = function () {
    return [
    [1,0,0,0],
    [0,1,0,0],
    [0,0,1,0],
    [0,0,0,1],
    ];
};

MatrixEl.prototype.scale = function (scale) {
    this.current_scale = scale;
    this.matrix[0][0] *= scale;
    this.matrix[1][1] *= scale;
    this.matrix[2][2] *= scale;
};

MatrixEl.prototype.translate = function (x, y, z) {
    m = this.matrix;
    this.x = x;
    this.y = y;
    this.z = z;
    m[3][0] = this.x;
    m[3][1] = this.y;
    m[3][2] = this.z;
}

MatrixEl.prototype.rotate = function (x, y, z) {
    var m = this.matrix;
    this.xrot = x;
    this.yrot = y;
    this.zrot = z;
    var amount = this.xrot * DEG_TO_RAD;
    m[1][1] *= Math.cos(amount);
    m[1][2] *= Math.sin(-amount);
    m[2][1] *= Math.sin(amount);
    m[2][2] *= Math.cos(amount);    

    var amount = this.yrot * DEG_TO_RAD;
    m[0][0] *= Math.cos(amount);
    m[0][2] *= Math.sin(amount);
    m[2][0] *= Math.sin(-amount);
    m[2][2] *= Math.cos(amount);    

    var amount = this.zrot * DEG_TO_RAD;
    m[0][0] *= Math.cos(amount);
    m[0][1] *= Math.sin(-amount);
    m[1][0] *= Math.sin(amount);
    m[1][1] *= Math.cos(amount);
};

MatrixEl.prototype.set = function (x, y, z, xrot, yrot, zrot, scale) {
    var m = this.matrix = this.getMatrix();
    this.rotate(xrot, yrot, zrot);
    this.scale(scale);
    this.translate(x, y, z);
    this.el.style.transform="matrix3d(" + m[0].concat(
            m[1],
            m[2],
            m[3]
        ).join(',') + ')';
};
var yRotVel = 45 / 1000;
var dist = 50;
var time = 0
var square = new MatrixEl(document.getElementById('test'));
var square2 = new MatrixEl(document.getElementById('test2'));

function animate (dt) {
    var angle = dt*yRotVel;
    var z = dist*Math.sin(dt*yRotVel*DEG_TO_RAD);
    var z2 = dist*Math.sin((dt*yRotVel+ 90)*DEG_TO_RAD);

    // square.set(x, y, z, xrot, yrot, zrot, scale)
    square.set(0, z, z, angle, 0, 0, 1.0);
    square2.set(0, z2, z2, angle+90, 0, 0, 1);
    requestAnimationFrame(animate);
}
requestAnimationFrame(animate);

The fix is in this fiddle , my issue was that the browser can't easily do the animations on the individual items. 解决的办法是摆弄小提琴 ,我的问题是浏览器无法轻松地对单个项目进行动画处理。

To fix this I simply constructed a cube, and then animated the whole cube, rather than animating the individual faces and it worked. 为了解决这个问题,我简单地构造了一个立方体,然后对整个立方体进行了动画处理,而不是对单个面孔进行动画处理,并且它起作用了。

The matrix / vector maths needs to be done properly, as if you combine rotations currently it skews objects in ways it shouldn't. 矩阵/矢量数学需要正确完成,就像您当前组合旋转一样,它以不应该使用的方式使对象倾斜。 I'll try and fix that part of the code soon, but in answer to my original question, you can do this without glitches. 我将尽快修复代码的这一部分,但为回答我的原始问题,您可以做到这一点。 The glitches were caused by not animating the shape as a whole. 毛刺是由于未对整个形状进行动画处理而导致的。

The code below contains the changed approach: 下面的代码包含更改后的方法:

var yRotVel = 45 / 1000;
var dist = 50;
var time = 0
var square = new MatrixEl(document.getElementById('test'));
var square2 = new MatrixEl(document.getElementById('test2'));
var square3 = new MatrixEl(document.getElementById('test3'));
var square4 = new MatrixEl(document.getElementById('test4'));
var square5 = new MatrixEl(document.getElementById('test5'));
var square6 = new MatrixEl(document.getElementById('test6'));
var cube = new MatrixEl(document.getElementById('world'));

square.set(150, 150, 50, 0, 0, 0, 1.0);
square2.set(150, 100, 0, 90, 0, 0, 1);
square3.set(150, 150, -50, 180, 0, 0, 1);
square4.set(150, 200, 0, 270, 0, 0, 1);
square5.set(100, 150, 0, 0, 90, 0, 1);
square6.set(200, 150, 0, 0, 90, 0, 1);

function animate (dt) {
    var angle = dt*yRotVel;
    var z = dist*Math.sin(dt*yRotVel*DEG_TO_RAD);
    // square.set(x, y, z, xrot, yrot, zrot, scale)
    cube.set(0, 0, 0, 0, angle, 0, 1);
    requestAnimationFrame(animate);
}
requestAnimationFrame(animate);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM