rotate3d的简写

时间:2013-03-04 17:26:38

标签: css css3 css-transforms

如何以速记rotateX(50deg) rotateY(20deg) rotateZ(15deg)组合rotate3d()

4 个答案:

答案 0 :(得分:313)

rotateX(50deg)相当于rotate3d(1, 0, 0, 50deg)

rotateY(20deg)相当于rotate3d(0, 1, 0, 20deg)

rotateZ(15deg)相当于rotate3d(0, 0, 1, 15deg)

因此...

rotateX(50deg) rotateY(20deg) rotateZ(15deg)

相当于

rotate3d(1, 0, 0, 50deg) rotate3d(0, 1, 0, 20deg) rotate3d(0, 0, 1, 15deg)


对于通用rotate3d(x, y, z, α),您有矩阵

generic rotate matrix

,其中

explanation


现在,您可以获取3 rotate3d个变换中每个变换的矩阵,然后将它们相乘。并且得到的矩阵是对应于得到的单个rotate3d的矩阵。不确定如何轻松地从中提取rotate3d的值,但是很容易为单个matrix3d提取这些值。


在第一种情况下(rotateX(50deg)rotate3d(1, 0, 0, 50deg)),您有:

x = 1y = 0z = 0α = 50deg

因此,在这种情况下,矩阵的第一行是1 0 0 0

第二个是0 cos(50deg) -sin(50deg) 0

第三个0 sin(50deg) cos(50deg) 0

第四个显然是0 0 0 1


在第二种情况下,您有x = 0y = 1z = 0α = 20deg

第一行:cos(20deg) 0 sin(20deg) 0

第二行:0 1 0 0

第三行:-sin(20) 0 cos(20deg) 0

第四:0 0 0 1


在第三种情况下,您有x = 0y = 0z = 1α = 15deg

第一行:cos(15deg) -sin(15deg) 0 0

第二行sin(15deg) cos(15deg) 0 0

第三和第四行分别是0 0 1 00 0 0 1


注意 :您可能已经注意到rotateY变换的sin值的符号与其他两个变换的不同。这不是一个计算错误。原因在于,对于屏幕,您的y轴指向下方,而不是向上。


因此,这些是您需要乘以的三个4x4矩阵,以便为生成的单4x4转换获取rotate3d矩阵。正如我所说,我不确定将4个值输出是多么容易,但4x4矩阵中的16个元素恰好是链接变换的matrix3d等效的16个参数。 / p>


修改

实际上,结果很简单......你计算了rotate3d矩阵矩阵的轨迹(对角元素之和)。

4 - 2*2*(1 - cos(α))/2 = 4 - 2*(1 - cos(α)) = 2 + 2*cos(α)

然后,您计算三个4x4矩阵的乘积的跟踪,将结果与提取2 + 2*cos(α)的{​​{1}}等同。然后,您计算αxy

在这种特殊情况下,如果我正确计算,由三个z矩阵的乘积产生的矩阵的轨迹将是:

4x4

所以T = cos(20deg)*cos(15deg) + cos(50deg)*cos(15deg) - sin(50deg)*sin(20deg)*cos(15deg) + cos(50deg)*cos(20deg) + 1 ,这意味着cos(α) = (T - 2)/2 = T/2 - 1

答案 1 :(得分:15)

语法:

rotate3d(x, y, z, a)

值:

  • x<number>描述向量的x坐标,表示旋转轴。
  • y<number>描述向量的y坐标,表示旋转轴。
  • z<number>描述向量的z坐标,表示旋转轴。
  • a<angle>表示旋转的角度。正角度表示顺时针旋转,负角度表示逆时针旋转角度。

喜欢在:

.will-distort{
    transform:rotate3d(10, 10, 10, 45deg);
}

Fiddled here

Caniuse it here

More docs about it

答案 2 :(得分:7)

取决于你想要做什么,这个'黑客'可以帮助你。假设您正在制作动画,并且您希望在转换后添加转换等等,并且您不希望CSS看起来像是在进行100次转换:

这适用于chrome:  1.将您想要的任何变换应用于元素。  2.下次要添加变换时,将其添加到计算变换中:     “window.getComputedStyle(element).transform” - 但请确保将新变换放在左侧。  3.现在你的变换看起来像“rotateZ(30deg)ma​​trix3d(......)”。  4.下次要添加另一个转换时,重复此过程 - Chrome始终将转换减少为matrix3d表示法。

TL; DR-应用您想要的任何变换,然后获得计算的matrix3d变换。

这个技巧还可以让你快速(也就是说,没有自己做任何数学运算)制作一个功能,可以在任何方向上相对于参考框架旋转对象。请参阅以下示例:

编辑:我也添加了xyz翻译。使用此功能,可以非常轻松地将对象放置在具有特定方向的特定3d位置。或者......想象一个立方体反弹并改变它的旋转轴,每次反弹取决于它的落地方式!

	var boxContainer = document.querySelector('.translator'),
	    cube = document.getElementById('cube'),
	    optionsContainer = document.getElementById('options');
	var dims = ['x', 'y', 'z'];
	var currentTransform;
	var currentTranslate;
	var init = function () {
	    optionsContainer.querySelector('.xRotation input')
	        .addEventListener('input', function (event) {
	        if (currentTransform != 'none') {
	            var newTransform = 'rotateX(' + (360 - event.target.value) + 'deg) ' + currentTransform;
	        } else {
	            var newTransform = 'rotateX(' + (360 - event.target.value) + 'deg)';
	        }
	        cube.style.transform = newTransform;
	    }, false);

	    optionsContainer.querySelector('.yRotation input')
	        .addEventListener('input', function (event) {
	        if (currentTransform != 'none') {
	            var newTransform = 'rotateY(' + (360 - event.target.value) + 'deg) ' + currentTransform;
	        } else {
	            var newTransform = 'rotateY(' + (360 - event.target.value) + 'deg)';
	        }
	        cube.style.transform = newTransform;
	    }, false);

	    optionsContainer.querySelector('.zRotation input')
	        .addEventListener('input', function (event) {

	        if (currentTransform != 'none') {
	            var newTransform = 'rotateZ(' + (360 - event.target.value) + 'deg) ' + currentTransform;
	        } else {
	            var newTransform = 'rotateZ(' + (360 - event.target.value) + 'deg)';
	        }
	        cube.style.transform = newTransform;
	    }, false);

	    optionsContainer.querySelector('.xTranslation input')
	        .addEventListener('input', function (event) {

	        if (currentTranslate != 'none') {
	            var newTransform = 'translateX(' + (100 - event.target.value) + 'px) ' + currentTranslate;
	        } else {
	            var newTransform = 'translateX(' + (100 - event.target.value) + 'px)';
	        }
	        boxContainer.style.transform = newTransform;
	    }, false);

	    optionsContainer.querySelector('.yTranslation input')
	        .addEventListener('input', function (event) {

	        if (currentTranslate != 'none') {
	            var newTransform = 'translateY(' + (100 - event.target.value) + 'px) ' + currentTranslate;
	        } else {
	            var newTransform = 'translateY(' + (100 - event.target.value) + 'px)';
	        }
	        boxContainer.style.transform = newTransform;
	    }, false);
	    optionsContainer.querySelector('.zTranslation input')
	        .addEventListener('input', function (event) {

	        if (currentTranslate != 'none') {
	            var newTransform = 'translateZ(' + (500 - event.target.value) + 'px) ' + currentTranslate;
	        } else {
	            var newTransform = 'translateZ(' + (500 - event.target.value) + 'px)';
	        }
	        boxContainer.style.transform = newTransform;
	    }, false);



reset();

	};

	function reset() {
	    currentTransform = window.getComputedStyle(cube).transform;
	    currentTranslate = window.getComputedStyle(boxContainer).transform;
	    optionsContainer.querySelector('.xRotation input').value = 360;
	    optionsContainer.querySelector('.yRotation input').value = 360;
	    optionsContainer.querySelector('.zRotation input').value = 360;
	    optionsContainer.querySelector('.xTranslation input').value = 100;
	    optionsContainer.querySelector('.yTranslation input').value = 100;
	    optionsContainer.querySelector('.zTranslation input').value = 500;


	}


	window.addEventListener('DOMContentLoaded', init, false);
	document.addEventListener('mouseup', reset, false);
.translator
{
	height: 200px;
	position: absolute;
	width: 200px;
    transform-style: preserve-3d;
}
.threeSpace
{
	height: 200px;
	moz-perspective: 1200px;
	o-perspective: 1200px;
	perspective: 200px;
	position: absolute;
	transform-origin: 50px 50px 100px;
	webkit-perspective: 1200px;
	width: 100px;
    perspective-origin: 100px 25px;
    transform-style: preserve-3d;
}
#pointer{
    position:relative;
    height:2px;
    width:2px;
    top:25px;
    left:100px;
    background:blue;
    z-index:9999;
    
}



#cube
{
	height: 100%;
	moz-transform-origin: 90px 110px 0px;
	moz-transform-style: preserve-3d;
	o-transform-origin: 90px 110px 0px;
	o-transform-style: preserve-3d;
	position: absolute;
	transform-origin: 90px 110px 0px;
	transform-style: preserve-3d;
	webkit-transform-origin: 90px 110px 0px;
	webkit-transform-style: preserve-3d;
	width: 100%;
}
#cube .midPoint{
    position:absolute;
    top:48px;
    left:48px;
    height:1px;
    width:1px;
    background:green;
}

#cube figure
{
	border: 2px solid black;
	color: white;
	display: block;
	font-size: 60px;
	font-weight: bold;
	height: 96px;
	line-height: 96px;
	position: absolute;
	text-align: center;
	width: 96px;
    /* transform-style: preserve-3d; */
}
#cube .front
{
	background: hsl(0, 100%, 50%);
}

#cube .back
{
	background: hsl(60, 100%, 50%);
}
#cube .right
{
	background: hsl(120, 100%, 50%);
}
#cube .left
{
	background: hsl(180, 100%, 50%);
}
#cube .top
{
	background: hsl(240, 100%, 50%);
}
#cube .bottom
{
	background: hsl(300, 100%, 50%);
}
#cube .front
{
	moz-transform: translateZ(50px);
	o-transform: translateZ(50px);
	transform: translateZ(50px);
	webkit-transform: translateZ(50px);
}



#cube .back
{
	moz-transform: rotateX(-180deg) translateZ(50px);
	o-transform: rotateX(-180deg) translateZ(50px);
	transform: rotateX(-180deg) translateZ(50px);
	webkit-transform: rotateX(-180deg) translateZ(50px);
}
#cube .right
{
	moz-transform: rotateY(90deg) translateZ(50px);
	o-transform: rotateY(90deg) translateZ(50px);
	transform: rotateY(90deg) translateZ(50px);
	webkit-transform: rotateY(90deg) translateZ(50px);
}
#cube .left
{
	moz-transform: rotateY(-90deg) translateZ(50px);
	o-transform: rotateY(-90deg) translateZ(50px);
	transform: rotateY(-90deg) translateZ(50px);
	webkit-transform: rotateY(-90deg) translateZ(50px);
}
#cube .top
{
	moz-transform: rotateX(90deg) translateZ(50px);
	o-transform: rotateX(90deg) translateZ(50px);
	transform: rotateX(90deg) translateZ(50px);
	webkit-transform: rotateX(90deg) translateZ(50px);
}
#cube .bottom
{
	moz-transform: rotateX(-90deg) translateZ(50px);
	o-transform: rotateX(-90deg) translateZ(50px);
	transform: rotateX(-90deg) translateZ(50px);
	webkit-transform: rotateX(-90deg) translateZ(50px);
}
#options{
    position:absolute;
    width:80%;
    top:40%;
    
    
}
#options input
{
	width: 60%;
}
<body>
    
     <div class="threeSpace">
         <div id="pointer"></div>
    <div class="translator">
        <div id="cube">
            <figure class="front"><div class='midPoint'></div></figure>
            <figure class="back"></figure>
            <figure class="right"></figure>
            <figure class="left"></figure>
            <figure class="top"></figure>
            <figure class="bottom"></figure>
        </div>
    </div>
    </div>
    <section id="options">
        <p class="xRotation">
            <label>xRotation</label>
            <input type="range" min="0" max="720" value="360" data-units="deg" />
        </p>
        <p class="yRotation">
            <label>yRotation</label>
            <input type="range" min="0" max="720" value="360" data-units="deg" />
        </p>
        <p class="zRotation">
            <label>zRotation</label>
            <input type="range" min="0" max="720" value="360" data-units="deg" />
        </p>
        <p class="xTranslation">
            <label>xTranslation</label>
            <input type="range" min="0" max="200" value="100" data-units="deg" />
        </p>
        <p class="yTranslation">
            <label>yTranslation</label>
            <input type="range" min="0" max="200" value="100" data-units="deg" />
        </p>
        <p class="zTranslation">
            <label>zTranslation</label>
            <input type="range" min="0" max="1000" value="500" data-units="deg" />
        </p>
    </section>
</body>

答案 3 :(得分:3)

确切的值为rotate3d(133,32,58,58deg)

请参阅fiddle(对于chrome和Safari,使用-webkit-transform)