马黑黑 发表于 2025-12-10 12:29

理解 rotate3d

<style>
        .artBox { font-size: 18px; margin: 20px auto; max-width: 1200px; }
        .artBox > p { margin: 10px 0; line-height: 30px; }
        .artBox mark { padding: 4px 6px; background: lightblue; }
        .sbox { height: 200px; display: grid; grid-template-columns: repeat(3, 1fr); place-items: center; border: 1px solid gray; }
        .sbox span { font: bold 2em/1.5 sans-serif; text-shadow: 2px 2px 4px gray; }
        .rotateX { color: red; animation: rotX linear 5s infinite; }
        .rotateY { color: green; animation: rotY linear 5s infinite; }
        .rotateZ { color: blue; animation: rotZ linear 5s infinite; }
        @keyframes rotX { to { transform: rotateX(360deg); } }
        @keyframes rotY { to { transform: rotateY(360deg); } }
        @keyframes rotZ { to { transform: rotateZ(360deg); } }
</style>

<div class="artBox">
        <p>rotate3d本质上是 rotateX、rotateY、rotateZ 的集合,不同的是语法结构及其导致的使用方式:rotate3d 更为抽象、难用,rotateX/Y/Z 更为直白、易用。</p>
        <p>要理解 rotate3d,先得弄清楚 rotateX、rotateY 和 rotateZ 这三个 transform 转换下的函数。它们的具体功能是将对象在对应周上旋转多少个角度。假设你就是这个要旋转的对象,rotateX 就是你在单杠上做翻转运动——单杠的横条是X轴,你双手握着它不停地让身体绕X轴翻转着;rotateY 则是你在跳钢管舞——钢管是Y轴,你抱着它让身体性感地绕Y轴旋转着;rotateZ 就像你在表演耶稣钉在十字架上,十字架则像风车一样面向观者旋转着,并且摄影师还将镜头忽而拉近忽而拉远……此时你身体的旋转是绕Z轴进行,Z轴就是观者和被观察对象间的连接线。以下例子是 rotateX/Y/Z 的简易表演,它们没有你的表演待遇,不提供任何道具:</p>
        <div class="sbox">
                <span class="rotateX">rotateX</span>
                <span class="rotateY">rotateY</span>
                <span class="rotateZ">rotateZ</span>
        </div>
        <div class="codebox" data-title="CSS动画代码:">
@keyframes rotX { to { transform: rotateX(360deg); } }
@keyframes rotY { to { transform: rotateY(360deg); } }
@keyframes rotZ { to { transform: rotateZ(360deg); } }
        </div>
        <p>rotate3d 同时也是 transform 转换属性的函数,可以视为是 rotateX、rotateY、rotateZ 的语法糖。下面的例子,动画的设置等效于前例(可以点击“预览”按钮查看效果):</p>
       
        <div class="codebox" data-prev="1">
&lt;style&gt;
        .sbox { margin: 20px auto; width: 1204px; height: 200px; display: grid; grid-template-columns: repeat(3, 1fr); place-items: center; border: 1px solid gray; }
        .sbox span { font: bold 2em/1.5 sans-serif; text-shadow: 2px 2px 4px gray; }
        .rotateX { color: red; animation: rotX linear 5s infinite; }
        .rotateY { color: green; animation: rotY linear 5s infinite; }
        .rotateZ { color: blue; animation: rotZ linear 5s infinite; }
        @keyframes rotX { to { transform: rotate3d(1, 0, 0, 360deg); } }
        @keyframes rotY { to { transform: rotate3d(0, 1, 0, 360deg); } }
        @keyframes rotZ { to { transform: rotate3d(0, 0, 1, 360deg); } }
&lt;/style&gt;

&lt;div class="sbox"&gt;
        &lt;span class="rotateX"&gt;rotateX&lt;/span&gt;
        &lt;span class="rotateY"&gt;rotateY&lt;/span&gt;
        &lt;span class="rotateZ"&gt;rotateZ&lt;/span&gt;
&lt;/div&gt;
        </div>
        <p>rotate3d 函数的语法共四个参数:</p>
        <blockquote><mark>transform: rotate3d(X, Y, Z, 角度);</mark></blockquote>
        <p>参数 X、Y、Z 决定旋转对象绕 X、Y、Z 三个轴中的哪一根轴或哪几根轴转,取值并没有严格规定,通常使用归一化矢量值,即 0~1 的范围,可以使用正、负数,正值时表示顺时针旋转、负值表示逆时针旋转,但这取决于第四个参数即角度参数的正负值,这里假设角度参数为正值。X、Y、Z 的绝对值大小可能不很重要,浏览器系统引擎关心的是它们之间的比例关系从而决定旋转对象在三个轴上如何旋转,它有自己的一整套处理机制,按照“X绝对值的平方+Y绝对值的平方+Z绝对值的平方=1”的原则做调整,因此实际对XYZ的赋值可以随意,我们关心的仅是正负、0或非0(0表示对应轴没有转动、非0表示转动);角度参数可以是 deg(角度)、turn(一圈)或 rad(弧度),可以是正、负值,正值时对象以顺时针旋转、负值时对象以逆时针旋转(这里假设XYZ矢量为正值)。关于对象的旋转方向,决定因素有两个:XYZ矢量取值的正负数和角度参数取值的正负数,二者的乘积为正则对象以顺时针方向旋转,为负逆时针旋转。</p>
        <p>XYZ矢量设置容易令人困惑,所以很多人更倾向于使用 rotateX/Y/Z 去设置对象的旋转,不愿意使用 rotate3d 函数。实际上,rotate3d 函数也不复杂,总结来讲就是:XYZ三个参数的表示对象在哪一(些)轴上旋转、角度参数表示旋转多少个角度(或圈、弧度);XYZ三值以归一化取值,-1~1 范围,三者在系统内部按各自绝对值的平方和等于1的规范做调整,使用者可以不用管这个,只关心0或非0的意义以及它们之间的比例关系的意义即可;角度参数支持正负值。</p>
        <p>不论是使用 rotateX/Y/Z 还是 rotate3d 函数来设置对象旋转,它们都可以用于 2d 旋转 和 3d 旋转。3d 旋转带来更强烈的立体感(近大远小),想让对象以3d形式渲染旋转效果,需要在对象的父级元素使用 perspective 属性设置场景的透视深度,并在对象CSS选择器或父元素(假设 perspective 景深设置在了祖父级元素)设置 transform-style 为 preserve-3d。下面的例子,父元素启用了 perspective 设置,左边子元素是2d旋转,右边子元素是3d旋转(设置有 transform0style: preserve-3d;):</p>
        <div class="codebox" data-prev="1">
&lt;style&gt;
        .papa {
                margin: 20px auto;
                width: 1024px;
                height: 300px;
                border: 1px solid gray;
                display: grid;
                grid-template-columns: 1fr 1fr;
                place-items: center;
                perspective: 500px;
        }
        .son {
                width: 200px;
                height: 200px;
                background: lightgreen;
                transform: rotate3d(0, 1, 0, 30deg);
                display: grid;
                place-items: center;
                font-size: 30px;
        }
        .son-3d { transform-origin: preserve-3d;}
&lt;/style&gt;

&lt;div class="papa"&gt;
        &lt;div class="son"&gt;2d旋转&lt;/div&gt;
        &lt;div class="son son-3d"&gt;3d旋转&lt;/div&gt;
&lt;/div&gt;
        </div>
        <p>理解 rotate3d 有些难度,希望本文对大家有所帮助。</p>
</div>

<script type="module">
        import linenumber from 'https://638183.freep.cn/638183/web/js/linenumber.js';
        linenumber();
</script>

红影 发表于 2025-12-10 13:15

“rotate3d 可以视为是 rotateX、rotateY、rotateZ 的语法糖。”

这个说法好,这个可以不用一个个地转了,能一下子三维都设置为非0 的,很奇妙{:4_187:}

红影 发表于 2025-12-10 13:17

想起那个《暗香浮动月黄昏》的帖子了,就有两维非0的,在空间进行旋转。
这个帖子为了讲解,都直接设置为1,那个帖子里还有小数,也就是不是垂直于某一维的方向转动的。

红影 发表于 2025-12-10 13:18

这个帖子好,看完这个对前一个帖子也有更深的理解了{:4_187:}

红影 发表于 2025-12-10 13:19

讲解很详细,黑黑辛苦了{:4_187:}

马黑黑 发表于 2025-12-10 13:42

红影 发表于 2025-12-10 13:15
“rotate3d 可以视为是 rotateX、rotateY、rotateZ 的语法糖。”

这个说法好,这个可以不用一个个地转了 ...

可以视为语法糖,但实际上并非是语法糖,二者是独立函数,只是彼此间有联系

马黑黑 发表于 2025-12-10 13:43

红影 发表于 2025-12-10 13:17
想起那个《暗香浮动月黄昏》的帖子了,就有两维非0的,在空间进行旋转。
这个帖子为了讲解,都直接设置为1 ...

一般而言,关心0和非0的值即可

杨帆 发表于 2025-12-10 19:45

辛苦了~谢谢马老师对 rotate3d的经典讲授{:4_191:}

马黑黑 发表于 2025-12-10 20:04

杨帆 发表于 2025-12-10 19:45
辛苦了~谢谢马老师对 rotate3d的经典讲授

这个多少有点抽象,希望看完本文能够有个清晰的了解

杨帆 发表于 2025-12-10 21:20

马黑黑 发表于 2025-12-10 20:04
这个多少有点抽象,希望看完本文能够有个清晰的了解

是,本来挺抽象的,看了您的讲义后清晰了许多{:4_180:}

红影 发表于 2025-12-10 21:53

马黑黑 发表于 2025-12-10 13:42
可以视为语法糖,但实际上并非是语法糖,二者是独立函数,只是彼此间有联系

嗯嗯,知道,这只是一个比喻{:4_187:}

红影 发表于 2025-12-10 21:54

马黑黑 发表于 2025-12-10 13:43
一般而言,关心0和非0的值即可

不用管这个非0 的值是1还是小数{:4_173:}

马黑黑 发表于 2025-12-10 22:09

红影 发表于 2025-12-10 21:54
不用管这个非0 的值是1还是小数

一般来说就是这样。

马黑黑 发表于 2025-12-10 22:10

红影 发表于 2025-12-10 21:53
嗯嗯,知道,这只是一个比喻

嗯嗯

马黑黑 发表于 2025-12-10 22:14

杨帆 发表于 2025-12-10 21:20
是,本来挺抽象的,看了您的讲义后清晰了许多

多研究示例就会很清楚

霜染枫丹 发表于 2025-12-10 22:15

本帖最后由 霜染枫丹 于 2025-12-10 22:20 编辑

马老师晚上好!这个我先收藏,慢慢理解。我琢磨了月黄昏,感觉到这真是师傅领进门修行在个人,对类似的3d动画,我不陌生,我使用软件Xara 3D Maker 7来制作,这款软件我在东方财富网的时候学会的,就一直跟着升级使用到现在的版本7,很长时间没玩了。做过很多顶贴图之类的图片。第一次接触代码制作,感觉代码才是工作母机,软件类似于剪影,只是半成品,不能随心所欲,只能在框架内选择。这不是一个量级。

这些代码我都会收藏,认真的学习一下,我很喜欢这种可以有想象空间的东东。
感谢马老师的无私分享,辛苦了。恭祝吉祥快乐!!
{:4_187:}{:4_204:}{:4_190:}



马黑黑 发表于 2025-12-10 22:23

霜染枫丹 发表于 2025-12-10 22:15
马老师晚上好!这个我先收藏,慢慢理解。我琢磨了月黄昏,感觉到这真是师傅领进门修行在个人,对类似的3d动 ...

有基础学起来不会太难

霜染枫丹 发表于 2025-12-10 22:23

用软件制作虽然东西不大,也是很麻烦,很多选项,用代码可以做出来很多变化,便捷很多。我也是第一次知道可以这样,觉得特别好用。

马黑黑 发表于 2025-12-10 22:24

霜染枫丹 发表于 2025-12-10 22:23
用软件制作虽然东西不大,也是很麻烦,很多选项,用代码可以做出来很多变化,便捷很多。我也是第一次知道可 ...
HTML一般都只用代码,所见即所得的软件现在都跟不上了

红影 发表于 2025-12-10 22:24

马黑黑 发表于 2025-12-10 22:09
一般来说就是这样。

这里讲的是绕三个轴的旋转的纯粹的情况,其实经过不同数值的设置,它是空间的旋转。
页: [1] 2 3
查看完整版本: 理解 rotate3d