赫丹 發表於 2020-3-6 16:46:00

基于HTML5和CSS3构建3D模型

<p>关于CSS 3D的研究,其实早在2013年就开始了。无奈受限于当时的浏览器兼容性以及硬件性能等原因,对3D的一些探索也只是停留在DEMO阶段。这里可以参考我之前Github上的一个3D房屋模型DEMO。</p>
<p>CSS 3D的应用是我们一直在思考的,虽然近几年来浏览器和硬件有了很大提升,但基于CSS 3D做复杂应用还是比较受限。目前基于CSS 3D更多的是做一些美感和效果展现,以及一些轻量级的应用。</p>
<p>我们聚划算前端团队在慕课网上开通了自己的主页,希望把我们的一些技术和想法拿出来跟大家进行分享和沟通交流,借此机会我先抛砖引玉,跟大家做这次分享。</p>
<hr>
<p>言归正传。</p>
<p>今天要分享的话题是基于HTML5和CSS3构建3D模型,希望通过这次的分享,每个人都能够开启自己的3D之旅。主要有以下3点内容:</p>
<ol>
<li>CSS3基础知识</li>
<li>构建一个3D模型</li>
<li>3D模型模块化及扩展</li>
</ol><hr>
<p>CSS3基础知识</p>
<p>对于css的二维世界,相信大家都不陌生。在二维的世界里,我们可以对元素设置宽高、位置、旋转、背景等等。</p>
<p>在css三维世界里,扩展出了一个z轴,这个z轴垂直于屏幕并指向外面。如图,</p>
<p><img src="https://img.alicdn.com/tps/TB1TIZSMVXXXXbGXVXXXXXXXXXX-330-286.png"></p>
<p>基于这个三维坐标系,在二维基础上扩展一下我们的想象,如果一个元素可以绕着三个坐标轴进行平移、旋转会出线什么效果呢?</p>
<p>聪明的你肯定能够想象出来,在三维世界里,这个元素就变成立体的了。我们先不做演示,先来解释几个概念,Perspective,Transform、Translate和Transition(简称“三蠢”)</p>
<h3>Perspective</h3>
<p>Perspective在3D世界里是一个非常重要的概念,这个属性的设置决定了我们看到的是三维效果还是二维效果。Perspective的字面意思是透视、视角,计算机要模拟现实世界的三维效果,必须有一个虚拟摄像机(Camera)的概念,摄像机的移动代表现实世界中我们眼睛的移动,我们眼睛看到的真实物体有近大远小的效果,同样,虚拟摄像机的也要模拟出这样的场景。W3C解释是下图这样,透视点是物体到摄像机的距离(d), perspective设置的大小不同,人眼所看到的物体也会发生变化。</p>
<p><img src="https://img.alicdn.com/tps/TB1aF.8MVXXXXbPXpXXXXXXXXXX-362-376.jpg"></p>
<p>perspective-origin指摄像机的中心点位置,默认值是center center(或50% 50%)。换句话说,作为摄像机镜头的三个维度,perspective-origin代表了X和Y轴,而perspective代表Z轴。摄像机在三维空间进行移动,也就告诉浏览器也进行不同的渲染,而呈现给我们的就是不同的视角效果。</p>
<p><img src="https://img.alicdn.com/tps/TB1w271MVXXXXalXFXXXXXXXXXX-522-272.jpg"></p>
<p>构建一个3D缺少不了3个要素,摄像机(Camera)、舞台(stage)和物体(Object)本身。我们先来创建这三个要素,代码如下:</p>
<pre class="prettyprint"><code><span class="tag">&lt;div<span class="pln"> <span class="atn">class<span class="pun">=<span class="atv">"camera"<span class="tag">&gt;<span class="pln">
      <span class="tag">&lt;div<span class="pln"> <span class="atn">class<span class="pun">=<span class="atv">"stage"<span class="tag">&gt;<span class="pln">
            <span class="tag">&lt;div<span class="pln"> <span class="atn">class<span class="pun">=<span class="atv">"box"<span class="tag">&gt;&lt;/div&gt;<span class="pln">
      <span class="tag">&lt;/div&gt;<span class="pln">
    <span class="tag">&lt;/div&gt;<span class="pln">
    .camera {
      width: 200px;
      height: 200px;
      perspective: 500px;
      perspective-origin: center center;
    }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<h3>Transform</h3>
<p>Transform指3D变换,主要的方法有旋转(Rotate)和平移(Translate)。Rotate可以绕X、Y、Z三个轴旋转,对应rotateX、rotateY、rotateZ三个方法。同样,坐标平移Translate也有tranlateX、tranlateY、translateZ三个方法。</p>
<p>在刚才的摄像机Camera设置完成后,我们需要设置一个立体空间,这个立体空间只有一个属性需要设置transform-style,默认清空下这个属性值被设置为flat,即在这个空间下的元素是没有z轴概念的,为了让元素都是立体元素,需要在这个立体空间上设置tranform-style的值为preserve-3d。</p>
<pre class="prettyprint"><code><span class="pun">.<span class="pln">stage <span class="pun">{<span class="pln">
      width<span class="pun">:<span class="lit">100<span class="pun">%;<span class="pln">
      height<span class="pun">:<span class="lit">100<span class="pun">%;<span class="pln">
      border<span class="pun">:<span class="lit">1px<span class="pln"> dashed <span class="com">#000;<span class="pln">
      transform<span class="pun">-<span class="pln">style<span class="pun">:<span class="pln">preserve<span class="pun">-<span class="lit">3d<span class="pun">;<span class="pln">
    <span class="pun">}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p>空间设置完成后,我们就可以来添加物体了,如上,我们设置了一个叫box的物体,下面我们来设置它的3D属性。</p>
<p>首先,我们对这个物体做3D平移</p>
<pre class="prettyprint"><code><span class="pun">.<span class="pln">box <span class="pun">{<span class="pln">
      width<span class="pun">:<span class="lit">100px<span class="pun">;<span class="pln">
      height<span class="pun">:<span class="lit">100px<span class="pun">;<span class="pln">
      background<span class="pun">:<span class="com">#069;<span class="pln">
      transform<span class="pun">:<span class="pln"> translateX<span class="pun">(<span class="lit">50px<span class="pun">)<span class="pln"> translateY<span class="pun">(<span class="lit">50px<span class="pun">);<span class="pln">
    <span class="pun">}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p><img src="https://img.alicdn.com/tps/TB1oUgVMVXXXXauXVXXXXXXXXXX-964-597.gif"></p>
<p>然后,改变camera的perspective属性</p>
<p><img src="https://img.alicdn.com/tps/TB1sps8MVXXXXXRXFXXXXXXXXXX-964-597.gif"></p>
<p>无论我们如何修改perspective或者perspective-origin,竟然没有任何效果!这是为什么呢???</p>
<blockquote>
<p>原因是在没有设置box的rotate、translateZ的情形下,box的深度没有变化,导致摄像机Camera透过perspective看出去的位置都是相同的,也造成不论怎么去看这个box都是一样的大小。</p>
</blockquote>
<p>OK,那我们来设置box的translateZ,让box沿着Z轴做一些平移</p>
<pre class="prettyprint"><code><span class="pun">.<span class="pln">box <span class="pun">{<span class="pln">
      width<span class="pun">:<span class="lit">100px<span class="pun">;<span class="pln">
      height<span class="pun">:<span class="lit">100px<span class="pun">;<span class="pln">
      background<span class="pun">:<span class="com">#069;<span class="pln">
      transform<span class="pun">:<span class="pln"> translateX<span class="pun">(<span class="lit">50px<span class="pun">)<span class="pln"> translateY<span class="pun">(<span class="lit">50px<span class="pun">)<span class="pln"> translateZ<span class="pun">(<span class="lit">150px<span class="pun">);<span class="pln">
    <span class="pun">}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p><img src="https://img.alicdn.com/tps/TB1ojs6MVXXXXaeXFXXXXXXXXXX-964-597.gif"></p>
<p>改变perspective属性</p>
<p><img src="https://img.alicdn.com/tps/TB1Ssg6MVXXXXaLXFXXXXXXXXXX-964-597.gif"></p>
<blockquote>
<p>按照人眼睛看到的物体近大远小的原理,摄像机离物体的距离(perspective)越近,看到的物体越大,离得越远,物体越小。当摄像机已经透过物体之后,就看不到了。想象你有穿墙术,当你离墙很远的时候,你能看到墙的边缘,当你离墙越近,墙也就越大,当你穿过墙之后,墙在你身后,也就看不到了。</p>
</blockquote>
<p>我们让box发生一些旋转,绕Y轴旋转45度</p>
<pre class="prettyprint"><code><span class="pun">.<span class="pln">box <span class="pun">{<span class="pln">
      width<span class="pun">:<span class="lit">100px<span class="pun">;<span class="pln">
      height<span class="pun">:<span class="lit">100px<span class="pun">;<span class="pln">
      background<span class="pun">:<span class="com">#069;<span class="pln">
      transform<span class="pun">:<span class="pln"> translateX<span class="pun">(<span class="lit">50px<span class="pun">)<span class="pln"> translateY<span class="pun">(<span class="lit">50px<span class="pun">)<span class="pln"> rotateY<span class="pun">(<span class="lit">45deg<span class="pun">);<span class="pln">
    <span class="pun">}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p><img src="https://img.alicdn.com/tps/TB1LwU8MVXXXXcEXpXXXXXXXXXX-964-597.gif"></p>
<p>改变perspective-origin属性</p>
<p><img src="https://img.alicdn.com/tps/TB1I9ZDMVXXXXaMaFXXXXXXXXXX-964-597.gif"></p>
<h3>Transition</h3>
<p>最后我们来说一下Transition这个概念,Transition的意思是过渡,我们在做一些动画效果的时候会用到它。Transition是一个简写属性,用于设置4个过渡属性</p>
<ul>
<li>transition-property(规定设置过渡效果的 CSS 属性的名称)</li>
<li>transition-duration (规定完成过渡效果需要多少秒或毫秒)</li>
<li>transition-timing-function(规定速度效果的速度曲线)</li>
<li>transition-delay (定义过渡效果何时开始)</li>
</ul>
<p>语法</p>
<blockquote>
<p>transition: property duration timing-function delay;</p>
</blockquote>
<p>我们来做一个例子</p>
<pre class="prettyprint"><code><span class="pun">.<span class="pln">tst <span class="pun">{<span class="pln">
      transition<span class="pun">:<span class="pln"> transform <span class="lit">2s<span class="pln"> linear <span class="lit">1s<span class="pun">;<span class="pln">
    <span class="pun">}</span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p>然后把这个class设置在物体box上,任意改变box上一个Transform属性</p>
<p><img src="https://img.alicdn.com/tps/TB1L5g8MVXXXXX7XFXXXXXXXXXX-964-597.gif"></p>
<p>可以看到这个变化是在设置完1s后(delay)在2s(duration)的时间内线性(linear)完成的((⊙o⊙)…有点绕口)。</p>
<p>构建一个3D模型</p>
<p>有了上面的概念之后,再来构建一个3D模型就非常简单了。通过对多个平面的平移、旋转,我们来构建一个Cube模型。</p>
<p>一个立方体有上、下、左、右、前、后6个面,我们先创建这6个面</p>
<pre class="prettyprint"><code><span class="tag">&lt;div<span class="pln"> <span class="atn">class<span class="pun">=<span class="atv">"camera"<span class="tag">&gt;<span class="pln">
      <span class="tag">&lt;div<span class="pln"> <span class="atn">class<span class="pun">=<span class="atv">"stage"<span class="tag">&gt;<span class="pln">
            <span class="tag">&lt;div<span class="pln"> <span class="atn">class<span class="pun">=<span class="atv">"cube up"<span class="tag">&gt;<span class="pln">up<span class="tag">&lt;/div&gt;<span class="pln">
            <span class="tag">&lt;div<span class="pln"> <span class="atn">class<span class="pun">=<span class="atv">"cube down"<span class="tag">&gt;<span class="pln">down<span class="tag">&lt;/div&gt;<span class="pln">
            <span class="tag">&lt;div<span class="pln"> <span class="atn">class<span class="pun">=<span class="atv">"cube left"<span class="tag">&gt;<span class="pln">left<span class="tag">&lt;/div&gt;<span class="pln">
            <span class="tag">&lt;div<span class="pln"> <span class="atn">class<span class="pun">=<span class="atv">"cube right"<span class="tag">&gt;<span class="pln">right<span class="tag">&lt;/div&gt;<span class="pln">
            <span class="tag">&lt;div<span class="pln"> <span class="atn">class<span class="pun">=<span class="atv">"cube front"<span class="tag">&gt;<span class="pln">front<span class="tag">&lt;/div&gt;<span class="pln">
            <span class="tag">&lt;div<span class="pln"> <span class="atn">class<span class="pun">=<span class="atv">"cube back"<span class="tag">&gt;<span class="pln">back<span class="tag">&lt;/div&gt;<span class="pln">
      <span class="tag">&lt;/div&gt;<span class="pln">
    <span class="tag">&lt;/div&gt;</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p>然后再设置每个面的Transform属性</p>
<pre class="prettyprint"><code><span class="pun">.<span class="pln">camera <span class="pun">{<span class="pln">
      width<span class="pun">:<span class="pln"> <span class="lit">400px<span class="pun">;<span class="pln">
      height<span class="pun">:<span class="pln"> <span class="lit">400px<span class="pun">;<span class="pln">
      perspective<span class="pun">:<span class="pln"> <span class="lit">1000px<span class="pun">;<span class="pln">
      perspective<span class="pun">-<span class="pln">origin<span class="pun">:<span class="pln"> center center<span class="pun">;<span class="pln">
    <span class="pun">}<span class="pln">
    <span class="pun">.<span class="pln">stage <span class="pun">{<span class="pln">
      width<span class="pun">:<span class="lit">100<span class="pun">%;<span class="pln">
      height<span class="pun">:<span class="lit">100<span class="pun">%;<span class="pln">
      border<span class="pun">:<span class="lit">1px<span class="pln"> dashed <span class="com">#000;<span class="pln">
      transform<span class="pun">:<span class="pln"> rotateY<span class="pun">(<span class="lit">0deg<span class="pun">)<span class="pln"> rotateX<span class="pun">(<span class="lit">0deg<span class="pun">);<span class="pln">
      transform<span class="pun">-<span class="pln">style<span class="pun">:<span class="pln">preserve<span class="pun">-<span class="lit">3d<span class="pun">;<span class="pln">
    <span class="pun">}<span class="pln">
    <span class="pun">.<span class="pln">cube <span class="pun">{<span class="pln">
      position<span class="pun">:<span class="pln"> absolute<span class="pun">;<span class="pln">
      left<span class="pun">:<span class="pln"> <span class="lit">75px<span class="pun">;<span class="pln">
      top<span class="pun">:<span class="pln"> <span class="lit">100px<span class="pun">;<span class="pln">
      margin<span class="pun">-<span class="pln">left<span class="pun">:<span class="pln"> <span class="lit">30px<span class="pun">;<span class="pln">
      width<span class="pun">:<span class="pln"> <span class="lit">200px<span class="pun">;<span class="pln">
      height<span class="pun">:<span class="pln"> <span class="lit">200px<span class="pun">;<span class="pln">
      color<span class="pun">:<span class="pln"> white<span class="pun">;<span class="pln">
      background<span class="pun">-<span class="pln">color<span class="pun">:<span class="pln"> rgba<span class="pun">(<span class="lit">255<span class="pun">,<span class="pln"> <span class="lit">85<span class="pun">,<span class="pln"> <span class="lit">85<span class="pun">,<span class="pln"> <span class="lit">1<span class="pun">);<span class="pln">
    <span class="pun">}<span class="pln">
    <span class="pun">.<span class="pln">up <span class="pun">{<span class="pln">
      background<span class="pun">-<span class="pln">color<span class="pun">:<span class="pln"> rgba<span class="pun">(<span class="lit">48<span class="pun">,<span class="pln"> <span class="lit">44<span class="pun">,<span class="pln"> <span class="lit">102<span class="pun">,<span class="lit">1<span class="pun">);<span class="pln">
      transform<span class="pun">:<span class="pln"> rotateX<span class="pun">(<span class="lit">90deg<span class="pun">)<span class="pln"> translateZ<span class="pun">(<span class="lit">100px<span class="pun">);<span class="pln">
    <span class="pun">}<span class="pln">
    <span class="pun">.<span class="pln">down <span class="pun">{<span class="pln">
      transform<span class="pun">:<span class="pln"> rotateX<span class="pun">(-<span class="lit">90deg<span class="pun">)<span class="pln"> translateZ<span class="pun">(<span class="lit">100px<span class="pun">);<span class="pln">
    <span class="pun">}<span class="pln">
    <span class="pun">.<span class="pln">left <span class="pun">{<span class="pln">
      background<span class="pun">-<span class="pln">color<span class="pun">:<span class="pln"> rgba<span class="pun">(<span class="lit">254<span class="pun">,<span class="pln"> <span class="lit">56<span class="pun">,<span class="pln"> <span class="lit">69<span class="pun">,<span class="lit">1<span class="pun">);<span class="pln">
      transform<span class="pun">:<span class="pln"> rotateY<span class="pun">(-<span class="lit">90deg<span class="pun">)<span class="pln"> translateZ<span class="pun">(<span class="lit">100px<span class="pun">);<span class="pln">
    <span class="pun">}<span class="pln">
    <span class="pun">.<span class="pln">right <span class="pun">{<span class="pln">
      transform<span class="pun">:<span class="pln"> rotateY<span class="pun">(<span class="lit">90deg<span class="pun">)<span class="pln"> translateZ<span class="pun">(<span class="lit">100px<span class="pun">);<span class="pln">
    <span class="pun">}<span class="pln">
    <span class="pun">.<span class="pln">front <span class="pun">{<span class="pln">
      background<span class="pun">-<span class="pln">color<span class="pun">:<span class="pln"> rgba<span class="pun">(<span class="lit">100<span class="pun">,<span class="pln"> <span class="lit">225<span class="pun">,<span class="pln"> <span class="lit">180<span class="pun">,<span class="lit">1<span class="pun">);<span class="pln">
      transform<span class="pun">:<span class="pln"> translateZ<span class="pun">(<span class="lit">100px<span class="pun">);<span class="pln">
    <span class="pun">}<span class="pln">
    <span class="pun">.<span class="pln">back <span class="pun">{<span class="pln">
      transform<span class="pun">:<span class="pln"> rotateY<span class="pun">(<span class="lit">180deg<span class="pun">)<span class="pln"> translateZ<span class="pun">(<span class="lit">100px<span class="pun">);<span class="pln">
    <span class="pun">}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p>关于如何旋转及平移,大家可以自行思考,比如把front面作为参考面,其他面应该如何平移和旋转?这里不做细述,有问题可以留言。</p>
<blockquote>
<p>注意:在进行旋转的时候,物体的坐标系也是跟着旋转的,所以先平移再旋转和先旋转再平移的效果是不一样的!这时候一定要分清楚当前坐标系!</p>
</blockquote>
<p>最后,一个Cube模型就显示出来了!</p>
<p><img src="https://img.alicdn.com/tps/TB1LHg1MVXXXXXAXVXXXXXXXXXX-964-597.gif"></p>
<blockquote>
<p>是不是So easy?!老板再也不担心我做不出炫酷的效果啦!</p>
</blockquote>
<hr>
<p>3D模型模块化及扩展</p>
<blockquote>
<p>道生一,一生二,二生三,三生万物。</p>
</blockquote>
<p>像这样一个简单的立方体我们可以通过几个面的平移、旋转构建出来。那如果是一个复杂模型,如果也用这样的方式构建,可能就会带来很大的工作量。当遇到这样问题的时候,我们自然而然会考虑到代码的模块化与自动化实现,有了这个“道”,万事万物就可以由此衍生出来了。</p>
<p>下面我们尝试用代码的方式来生成一个立方体,Let's go!</p>
<pre class="prettyprint"><code><span class="kwd">class<span class="pln"> <span class="typ">Cube<span class="pln"> <span class="pun">{<span class="pln">
      constructor<span class="pun">(<span class="pln">id<span class="pun">,<span class="pln"> l<span class="pun">,<span class="pln"> w<span class="pun">,<span class="pln"> h<span class="pun">,<span class="pln"> x<span class="pun">,<span class="pln"> y<span class="pun">,<span class="pln"> z<span class="pun">)<span class="pln"> <span class="pun">{<span class="pln">
            <span class="kwd">this<span class="pun">.<span class="pln">id <span class="pun">=<span class="pln"> id<span class="pun">;<span class="com">//ID<span class="pln">
            <span class="kwd">this<span class="pun">.<span class="pln">l <span class="pun">=<span class="pln"> l<span class="pun">;<span class="com">//长<span class="pln">
            <span class="kwd">this<span class="pun">.<span class="pln">w <span class="pun">=<span class="pln"> w<span class="pun">;<span class="com">//宽<span class="pln">
            <span class="kwd">this<span class="pun">.<span class="pln">h <span class="pun">=<span class="pln"> h<span class="pun">;<span class="com">//高<span class="pln">
            <span class="kwd">this<span class="pun">.<span class="pln">x <span class="pun">=<span class="pln"> x<span class="pun">;<span class="com">//x坐标<span class="pln">
            <span class="kwd">this<span class="pun">.<span class="pln">y <span class="pun">=<span class="pln"> y<span class="pun">;<span class="com">//y坐标<span class="pln">
            <span class="kwd">this<span class="pun">.<span class="pln">z <span class="pun">=<span class="pln"> z<span class="pun">;<span class="com">//z坐标<span class="pln">
      <span class="pun">}<span class="pln">
    <span class="pun">}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p>通过ES6语法创建一个Cube类,构造参数分别有id、长宽高l、w、h和坐标x、y、z,然后需要创建这个Cube的DOM元素。</p>
<pre class="prettyprint"><code><span class="kwd">class<span class="pln"> <span class="typ">Cube<span class="pln"> <span class="pun">{<span class="pln">
      constructor<span class="pun">(<span class="pln">id<span class="pun">,<span class="pln"> l<span class="pun">,<span class="pln"> w<span class="pun">,<span class="pln"> h<span class="pun">,<span class="pln"> x<span class="pun">,<span class="pln"> y<span class="pun">,<span class="pln"> z<span class="pun">)<span class="pln"> <span class="pun">{<span class="pln">
            <span class="kwd">this<span class="pun">.<span class="pln">id <span class="pun">=<span class="pln"> id<span class="pun">;<span class="com">//ID<span class="pln">
            <span class="kwd">this<span class="pun">.<span class="pln">l <span class="pun">=<span class="pln"> l<span class="pun">;<span class="com">//长<span class="pln">
            <span class="kwd">this<span class="pun">.<span class="pln">w <span class="pun">=<span class="pln"> w<span class="pun">;<span class="com">//宽<span class="pln">
            <span class="kwd">this<span class="pun">.<span class="pln">h <span class="pun">=<span class="pln"> h<span class="pun">;<span class="com">//高<span class="pln">
            <span class="kwd">this<span class="pun">.<span class="pln">x <span class="pun">=<span class="pln"> x<span class="pun">;<span class="com">//x坐标<span class="pln">
            <span class="kwd">this<span class="pun">.<span class="pln">y <span class="pun">=<span class="pln"> y<span class="pun">;<span class="com">//y坐标<span class="pln">
            <span class="kwd">this<span class="pun">.<span class="pln">z <span class="pun">=<span class="pln"> z<span class="pun">;<span class="com">//z坐标<span class="pln">

            <span class="kwd">this<span class="pun">.<span class="pln">_create<span class="pun">();<span class="pln">
      <span class="pun">}<span class="pln">

      _create<span class="pun">()<span class="pln"> <span class="pun">{<span class="pln">
            <span class="kwd">this<span class="pun">.<span class="pln">cube <span class="pun">=<span class="pln"> document<span class="pun">.<span class="pln">createElement<span class="pun">(<span class="str">'div'<span class="pun">);<span class="com">//构建DOM节点<span class="pln">
            <span class="kwd">this<span class="pun">.<span class="pln">faces <span class="pun">=<span class="pln"> <span class="kwd">new<span class="pln"> <span class="typ">Array<span class="pun">(<span class="lit">6<span class="pun">);<span class="com">//构建六个面<span class="pln">
            <span class="kwd">for<span class="pun">(<span class="pln">let i <span class="pun">=<span class="pln"> <span class="lit">0<span class="pun">;<span class="pln"> i <span class="pun">&lt;<span class="pln"> <span class="kwd">this<span class="pun">.<span class="pln">faces<span class="pun">.<span class="pln">length<span class="pun">;<span class="pln"> i<span class="pun">++)<span class="pln"> <span class="pun">{<span class="pln">
                <span class="kwd">this<span class="pun">.<span class="pln">faces<span class="pun">[<span class="pln">i<span class="pun">]<span class="pln"> <span class="pun">=<span class="pln"> document<span class="pun">.<span class="pln">createElement<span class="pun">(<span class="str">'div'<span class="pun">);<span class="pln">
                <span class="kwd">this<span class="pun">.<span class="pln">faces<span class="pun">[<span class="pln">i<span class="pun">].<span class="pln">id <span class="pun">=<span class="pln"> <span class="str">`${this.id}-face-${i}`<span class="pun">;<span class="pln">
                <span class="kwd">this<span class="pun">.<span class="pln">faces<span class="pun">[<span class="pln">i<span class="pun">].<span class="pln">style<span class="pun">.<span class="pln">position <span class="pun">=<span class="pln"> <span class="str">'absolute'<span class="pun">;<span class="pln"> <span class="com">//必须<span class="pln">
                <span class="kwd">this<span class="pun">.<span class="pln">faces<span class="pun">[<span class="pln">i<span class="pun">].<span class="pln">style<span class="pun">.<span class="pln">backgroundColor <span class="pun">=<span class="pln"> <span class="str">"#"<span class="pun">+((<span class="lit">1<span class="pun">&lt;&lt;<span class="lit">24<span class="pun">)*<span class="typ">Math<span class="pun">.<span class="pln">random<span class="pun">()<span class="lit">0<span class="pun">).<span class="pln">toString<span class="pun">(<span class="lit">16<span class="pun">);<span class="com">//生成随机颜色<span class="pln">
                <span class="kwd">this<span class="pun">.<span class="pln">cube<span class="pun">.<span class="pln">appendChild<span class="pun">(<span class="kwd">this<span class="pun">.<span class="pln">faces<span class="pun">[<span class="pln">i<span class="pun">]);<span class="pln">
            <span class="pun">}<span class="pln">
            <span class="kwd">this<span class="pun">.<span class="pln">_setCubeStyle<span class="pun">();<span class="pln">
            <span class="kwd">this<span class="pun">.<span class="pln">_setFrontFace<span class="pun">();<span class="pln">
            <span class="kwd">this<span class="pun">.<span class="pln">_setBackFace<span class="pun">();<span class="pln">
            <span class="kwd">this<span class="pun">.<span class="pln">_setLeftFace<span class="pun">();<span class="pln">
            <span class="kwd">this<span class="pun">.<span class="pln">_setRightFace<span class="pun">();<span class="pln">
            <span class="kwd">this<span class="pun">.<span class="pln">_setUpFace<span class="pun">();<span class="pln">
            <span class="kwd">this<span class="pun">.<span class="pln">_setDownFace<span class="pun">();<span class="pln">
      <span class="pun">}<span class="pln">
    <span class="pun">}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p>OK,现在我们Cube对象基本元素都有了。接下来我们需要设置6个面的样式,我们约定前、后、左、右、上、下分别对应faces数组中的6个面。</p>
<pre class="prettyprint"><code><span class="com">//设置cube样式<span class="pln">
    _setCubeStyle<span class="pun">()<span class="pln"> <span class="pun">{<span class="pln">
      let style <span class="pun">=<span class="pln"> <span class="pun">{<span class="pln">
            <span class="str">'display'<span class="pun">:<span class="pln"> <span class="str">'flex'<span class="pun">,<span class="pln"> <span class="com">//为计算方便,设置flex布局,想想为什么?<span class="pln">
            <span class="str">'justify-content'<span class="pun">:<span class="pln"> <span class="str">'center'<span class="pun">,<span class="pln">
            <span class="str">'align-items'<span class="pun">:<span class="pln"> <span class="str">'center'<span class="pun">,<span class="pln">
            <span class="str">'transform-style'<span class="pun">:<span class="pln"> <span class="str">'preserve-3d'<span class="pun">,<span class="pln">
            <span class="str">'transform'<span class="pun">:<span class="pln"> <span class="str">`translateX(${this.x}px) translateY(${this.y}px) translateZ(${this.z}px)`<span class="pln">
      <span class="pun">}<span class="pln">
      <span class="typ">Object<span class="pun">.<span class="pln">assign<span class="pun">(<span class="kwd">this<span class="pun">.<span class="pln">cube<span class="pun">.<span class="pln">style<span class="pun">,<span class="pln"> style<span class="pun">)<span class="pln">
    <span class="pun">}<span class="pln">

    <span class="com">//设置Front面样式<span class="pln">
    _setFrontFace<span class="pun">()<span class="pln"> <span class="pun">{<span class="pln">
      let style <span class="pun">=<span class="pln"> <span class="pun">{<span class="pln">
          <span class="str">'width'<span class="pln"> <span class="pun">:<span class="pln"> <span class="kwd">this<span class="pun">.<span class="pln">l <span class="pun">+<span class="pln"> <span class="str">'px'<span class="pun">,<span class="pln">
          <span class="str">'height'<span class="pun">:<span class="pln"> <span class="kwd">this<span class="pun">.<span class="pln">h <span class="pun">+<span class="pln"> <span class="str">'px'<span class="pun">,<span class="pln">
          <span class="str">'transform'<span class="pun">:<span class="pln"> <span class="str">`translateZ(${this.w/2}px)`<span class="pln">
      <span class="pun">}<span class="pln">
      <span class="typ">Object<span class="pun">.<span class="pln">assign<span class="pun">(<span class="kwd">this<span class="pun">.<span class="pln">faces<span class="pun">[<span class="lit">0<span class="pun">].<span class="pln">style<span class="pun">,<span class="pln"> style<span class="pun">)<span class="pln">
    <span class="pun">}<span class="pln">
    <span class="com">//设置Back面样式<span class="pln">
    _setBackFace<span class="pun">()<span class="pln"> <span class="pun">{<span class="pln">
      let style <span class="pun">=<span class="pln"> <span class="pun">{<span class="pln">
          <span class="str">'width'<span class="pln"> <span class="pun">:<span class="pln"> <span class="kwd">this<span class="pun">.<span class="pln">l <span class="pun">+<span class="pln"> <span class="str">'px'<span class="pun">,<span class="pln">
          <span class="str">'height'<span class="pun">:<span class="pln"> <span class="kwd">this<span class="pun">.<span class="pln">h <span class="pun">+<span class="pln"> <span class="str">'px'<span class="pun">,<span class="pln">
          <span class="str">'transform'<span class="pun">:<span class="pln"> <span class="str">`rotateY(180deg) translateZ(${this.w/2}px)`<span class="pln">
      <span class="pun">}<span class="pln">
      <span class="typ">Object<span class="pun">.<span class="pln">assign<span class="pun">(<span class="kwd">this<span class="pun">.<span class="pln">faces<span class="pun">[<span class="lit">1<span class="pun">].<span class="pln">style<span class="pun">,<span class="pln"> style<span class="pun">)<span class="pln">
    <span class="pun">}<span class="pln">
    <span class="com">//设置Left面样式<span class="pln">
    _setLeftFace<span class="pun">()<span class="pln"> <span class="pun">{<span class="pln">
      let style <span class="pun">=<span class="pln"> <span class="pun">{<span class="pln">
          <span class="str">'width'<span class="pln"> <span class="pun">:<span class="pln"> <span class="kwd">this<span class="pun">.<span class="pln">w <span class="pun">+<span class="pln"> <span class="str">'px'<span class="pun">,<span class="pln">
          <span class="str">'height'<span class="pun">:<span class="pln"> <span class="kwd">this<span class="pun">.<span class="pln">h <span class="pun">+<span class="pln"> <span class="str">'px'<span class="pun">,<span class="pln">
          <span class="str">'transform'<span class="pun">:<span class="pln"> <span class="str">`rotateY(-90deg) translateZ(${this.l/2}px)`<span class="pln">
      <span class="pun">}<span class="pln">
      <span class="typ">Object<span class="pun">.<span class="pln">assign<span class="pun">(<span class="kwd">this<span class="pun">.<span class="pln">faces<span class="pun">[<span class="lit">2<span class="pun">].<span class="pln">style<span class="pun">,<span class="pln"> style<span class="pun">)<span class="pln">
    <span class="pun">}<span class="pln">
    <span class="com">//设置Right面样式<span class="pln">
    _setRightFace<span class="pun">()<span class="pln"> <span class="pun">{<span class="pln">
      let style <span class="pun">=<span class="pln"> <span class="pun">{<span class="pln">
          <span class="str">'width'<span class="pln"> <span class="pun">:<span class="pln"> <span class="kwd">this<span class="pun">.<span class="pln">w <span class="pun">+<span class="pln"> <span class="str">'px'<span class="pun">,<span class="pln">
          <span class="str">'height'<span class="pun">:<span class="pln"> <span class="kwd">this<span class="pun">.<span class="pln">h <span class="pun">+<span class="pln"> <span class="str">'px'<span class="pun">,<span class="pln">
          <span class="str">'transform'<span class="pun">:<span class="pln"> <span class="str">`rotateY(90deg) translateZ(${this.l/2}px)`<span class="pln">
      <span class="pun">}<span class="pln">
      <span class="typ">Object<span class="pun">.<span class="pln">assign<span class="pun">(<span class="kwd">this<span class="pun">.<span class="pln">faces<span class="pun">[<span class="lit">3<span class="pun">].<span class="pln">style<span class="pun">,<span class="pln"> style<span class="pun">)<span class="pln">
    <span class="pun">}<span class="pln">
    <span class="com">//设置Up面样式<span class="pln">
    _setUpFace<span class="pun">()<span class="pln"> <span class="pun">{<span class="pln">
      let style <span class="pun">=<span class="pln"> <span class="pun">{<span class="pln">
          <span class="str">'width'<span class="pln"> <span class="pun">:<span class="pln"> <span class="kwd">this<span class="pun">.<span class="pln">l <span class="pun">+<span class="pln"> <span class="str">'px'<span class="pun">,<span class="pln">
          <span class="str">'height'<span class="pun">:<span class="pln"> <span class="kwd">this<span class="pun">.<span class="pln">w <span class="pun">+<span class="pln"> <span class="str">'px'<span class="pun">,<span class="pln">
          <span class="str">'transform'<span class="pun">:<span class="pln"> <span class="str">`rotateX(90deg) translateZ(${this.h/2}px)`<span class="pln">
      <span class="pun">}<span class="pln">
      <span class="typ">Object<span class="pun">.<span class="pln">assign<span class="pun">(<span class="kwd">this<span class="pun">.<span class="pln">faces<span class="pun">[<span class="lit">4<span class="pun">].<span class="pln">style<span class="pun">,<span class="pln"> style<span class="pun">)<span class="pln">
    <span class="pun">}<span class="pln">
    <span class="com">//设置Down面样式<span class="pln">
    _setDownFace<span class="pun">()<span class="pln"> <span class="pun">{<span class="pln">
      let style <span class="pun">=<span class="pln"> <span class="pun">{<span class="pln">
          <span class="str">'width'<span class="pln"> <span class="pun">:<span class="pln"> <span class="kwd">this<span class="pun">.<span class="pln">l <span class="pun">+<span class="pln"> <span class="str">'px'<span class="pun">,<span class="pln">
          <span class="str">'height'<span class="pun">:<span class="pln"> <span class="kwd">this<span class="pun">.<span class="pln">w <span class="pun">+<span class="pln"> <span class="str">'px'<span class="pun">,<span class="pln">
          <span class="str">'transform'<span class="pun">:<span class="pln"> <span class="str">`rotateX(-90deg) translateZ(${this.h/2}px)`<span class="pln">
      <span class="pun">}<span class="pln">
      <span class="typ">Object<span class="pun">.<span class="pln">assign<span class="pun">(<span class="kwd">this<span class="pun">.<span class="pln">faces<span class="pun">[<span class="lit">5<span class="pun">].<span class="pln">style<span class="pun">,<span class="pln"> style<span class="pun">)<span class="pln">
    <span class="pun">}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p>这样,一个Cube类就创建好了。我们来运行验证一下。</p>
<blockquote>
<p>注意:代码采用ES6语法,在浏览器运行时需要Babel转码。</p>
</blockquote>
<pre class="prettyprint"><code><span class="tag">&lt;div<span class="pln"> <span class="atn">class<span class="pun">=<span class="atv">"camera"<span class="tag">&gt;<span class="pln">
      <span class="tag">&lt;div<span class="pln"> <span class="atn">id<span class="pun">=<span class="atv">"stage"<span class="pln"> <span class="atn">class<span class="pun">=<span class="atv">"stage"<span class="tag">&gt;<span class="pln">
      <span class="tag">&lt;/div&gt;<span class="pln">
    <span class="tag">&lt;/div&gt;<span class="pln">

    .camera {
      width: 400px;
      height: 400px;
      perspective: 1000px;
      perspective-origin: center center;
    }
    .stage {
      width:100%;
      height:100%;
      border:1px dashed #000;
      transform: rotateY(30deg) rotateX(20deg);
      transform-style:preserve-3d;
    }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p>HTML代码很简单,这个时候我们只需要摄像机camera和空间stage两个元素,物体则由我们刚刚创建的Cube类生成。</p>
<pre class="prettyprint"><code><span class="pln">let c1 <span class="pun">=<span class="pln"> <span class="kwd">new<span class="pln"> <span class="typ">Cube<span class="pun">(<span class="str">'c1'<span class="pun">,<span class="pln"> <span class="lit">100<span class="pun">,<span class="pln"> <span class="lit">100<span class="pun">,<span class="pln"> <span class="lit">100<span class="pun">,<span class="pln"> <span class="lit">100<span class="pun">,<span class="pln"> <span class="lit">200<span class="pun">,<span class="pln"> <span class="lit">0<span class="pun">);<span class="pln">
    document<span class="pun">.<span class="pln">getElementById<span class="pun">(<span class="str">'stage'<span class="pun">).<span class="pln">appendChild<span class="pun">(<span class="pln">c1<span class="pun">.<span class="pln">cube<span class="pun">)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p>效果如下:</p>
<p><img src="https://img.alicdn.com/tps/TB1E.IMMVXXXXaPapXXXXXXXXXX-964-597.gif"><br><img src="https://img.alicdn.com/tps/TB1knMUMVXXXXataXXXXXXXXXXX-964-597.gif"></p>
<p>来创建一堆Cube,查看效果</p>
<pre class="prettyprint"><code><span class="pln">let c1 <span class="pun">=<span class="pln"> <span class="kwd">new<span class="pln"> <span class="typ">Cube<span class="pun">(<span class="str">'c1'<span class="pun">,<span class="pln"> <span class="lit">20<span class="pun">,<span class="pln"> <span class="lit">30<span class="pun">,<span class="pln"> <span class="lit">40<span class="pun">,<span class="pln"> <span class="lit">0<span class="pun">,<span class="pln"> <span class="lit">100<span class="pun">,<span class="pln"> <span class="lit">0<span class="pun">);<span class="pln">
    let c2 <span class="pun">=<span class="pln"> <span class="kwd">new<span class="pln"> <span class="typ">Cube<span class="pun">(<span class="str">'c1'<span class="pun">,<span class="pln"> <span class="lit">10<span class="pun">,<span class="pln"> <span class="lit">20<span class="pun">,<span class="pln"> <span class="lit">30<span class="pun">,<span class="pln"> <span class="lit">0<span class="pun">,<span class="pln"> <span class="lit">200<span class="pun">,<span class="pln"> <span class="lit">0<span class="pun">);<span class="pln">
    let c3 <span class="pun">=<span class="pln"> <span class="kwd">new<span class="pln"> <span class="typ">Cube<span class="pun">(<span class="str">'c1'<span class="pun">,<span class="pln"> <span class="lit">20<span class="pun">,<span class="pln"> <span class="lit">20<span class="pun">,<span class="pln"> <span class="lit">50<span class="pun">,<span class="pln"> <span class="lit">0<span class="pun">,<span class="pln"> <span class="lit">250<span class="pun">,<span class="pln"> <span class="lit">0<span class="pun">);<span class="pln">
    let c4 <span class="pun">=<span class="pln"> <span class="kwd">new<span class="pln"> <span class="typ">Cube<span class="pun">(<span class="str">'c1'<span class="pun">,<span class="pln"> <span class="lit">50<span class="pun">,<span class="pln"> <span class="lit">50<span class="pun">,<span class="pln"> <span class="lit">50<span class="pun">,<span class="pln"> <span class="lit">0<span class="pun">,<span class="pln"> <span class="lit">320<span class="pun">,<span class="pln"> <span class="lit">0<span class="pun">);<span class="pln">
    let $stage <span class="pun">=<span class="pln"> document<span class="pun">.<span class="pln">getElementById<span class="pun">(<span class="str">'stage'<span class="pun">);<span class="pln">
    $stage<span class="pun">.<span class="pln">appendChild<span class="pun">(<span class="pln">c1<span class="pun">.<span class="pln">cube<span class="pun">)<span class="pln">
    $stage<span class="pun">.<span class="pln">appendChild<span class="pun">(<span class="pln">c2<span class="pun">.<span class="pln">cube<span class="pun">)<span class="pln">
    $stage<span class="pun">.<span class="pln">appendChild<span class="pun">(<span class="pln">c3<span class="pun">.<span class="pln">cube<span class="pun">)<span class="pln">
    $stage<span class="pun">.<span class="pln">appendChild<span class="pun">(<span class="pln">c4<span class="pun">.<span class="pln">cube<span class="pun">)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p><img src="https://img.alicdn.com/tps/TB1o2MVMVXXXXXwaXXXXXXXXXXX-400-420.png"></p>
<blockquote>
<p>俄罗斯方块出现了!</p>
</blockquote>
<p>扩展</p>
<p>这次分享的内容就要结束了,回顾一下,我们讲解了CSS的基本概念、手动创建一个Cube模型以及如何通过模块化创建Cube对象。看完之后是不是觉得很简单?实际上这里面的原理确实不难,难的是我们如何应用这些来解决实际问题或者提升用户体验。</p>
<p>最后分享几个有意思的DEMO:</p>
<ol>
<li>
<p>3D魔方(在线地址)<br><img src="https://img.alicdn.com/tps/TB17QRrNXXXXXceXXXXXXXXXXXX-964-597.gif"></p>

</li>
<li>
<p>3D俄罗斯方块(在线地址)<br><img src="https://img.alicdn.com/tps/TB1Qx30MVXXXXazXFXXXXXXXXXX-723-552.gif"></p>

</li>
<li>3D立体书(在线地址)<br><img src="https://img.alicdn.com/tps/TB12lQ1MVXXXXX6XFXXXXXXXXXX-876-472.gif"></li>

</ol>
<p><br>作者:阿里聚划算技术团队<br>链接:https://www.imooc.com/article/12670<br>来源:慕课网</p>

</div>
<div id="MySignature" role="contentinfo">
    sunshine15666<br><br>
来源:https://www.cnblogs.com/xiaolucky/p/12427433.html
頁: [1]
查看完整版本: 基于HTML5和CSS3构建3D模型