<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      代碼改變世界

      transformjs玩轉星球

      2016-12-05 08:19  【當耐特】  閱讀(2603)  評論(3)    收藏  舉報

      如你所見。這篇就是要講下使用transformjs制作星球的過程。你也可以無視文章,直接去看源碼和在線演示:

      源碼 | 在線演示

      代碼100行多一點,直接看也沒有什么壓力。下面分幾步講解下。

      生成球上點坐標

      設球心為 (a,b,c),半徑為r,
      則球的標準方程為 (x-a)2+(y-b)2+(z-c)2=r2

      這里假設球心的(0,0,0),則:
      標準方程為 x2+y2+z2=r2

      因為可以渲染的時候再把球的本地坐標轉為世界坐標進行位移,所以球心(0,0,0)便可以。

      function randomPoints() {
          var x, y, z, j = -1, i = 0;
          for (; i < size; i++) {
              x = getRandomNumber(-250, 250);
              y = getRandomNumber(-250, 250);
              j *= -1;
              if (x * x + y * y <= r * r) {
                  z = j * Math.sqrt(Math.abs(r * r - x * x - y * y));
                  positions.push({x: x, y: y, z: z});
                  rd_positions.push({x: x, y: y, z: z});
              }
          }
      }
      

      上面的生成過程很取巧:

      • 1.隨機生成2D內的圓內的坐標x和y。(x * x + y * y <= r * r就是表示圓內)
      • 2.根據2D維度的坐標推算其屬于球面上的z

      其中positions用來存放所有點的local坐標,rd_positions用來以后存放投影后的坐標。

      坐標轉Dom

      function createImgs() {
          var i = 0,
              len = positions.length;
          for (; i < len; i++) {
              var img = document.createElement("img");
              img.style.position = "absolute";
              img.style.left = "0px";
              img.style.top = "0px";
              img.src = "../asset/star.png";
              document.body.appendChild(img);
              Transform(img,true);
              transformImg(img,i);
              img_list.push(img);
          }
      }
      

      所有的點都對應創建一個絕對定位的圖片,并且通過Transform(img,true)給img注入transformation能力。注意第二個參數true代表關閉透視投影,因為投影下面會自己去實現。

      投影變換

      function positionsProjection() {
          var index = 0,
              len=positions.length;
          for (; index < len; index++) {
              var p = positions[index];
              var rp = rd_positions[index];
              //perspective projection
              //rp.x = p.x * distance / Math.abs(camera_position.z - p.z);
              //rp.y =  p.y * distance / Math.abs(camera_position.z - p.z);
              //orthogonal projection
              rp.x = p.x ;
              rp.y =  p.y ;
          }
      }
      

      為了簡單起見,把球心和攝像機(也可以叫眼睛、亦或是視點)的坐標分別設置為:

      center = {x: 300, y: 300, z: 0},
      camera_position = {x: 300, y: 300, z: 500},
      distance = 600,
      

      distance代表攝像機到投影平面的距離,攝像機就固定在球心的正前方不動,這樣進行透視投影或正交投影計算起來無比方便,免去用齊次坐標、4*4矩陣的過程。如下簡單推導便可:

      這里需要注意的是,上面是透視投影的圖解,會產生近大遠小的感覺。透視投影是視錐體(上圖沒有把視錐體畫出來),正交投影是立方體。
      正交投影如下圖解,x和y坐標投影后不變就可以了:

      可以這么理解:

      • 透視投影從一個點看無數個點
      • 正交投影從無數個點看無數個點

      旋轉

      function rotate() {
          var cx,
              z,
              i = 0,
              len=positions.length;
          for (; i < len; i++) {
              cx = positions[i].x;
              z = positions[i].z;
              positions[i].x = positions[i].x * Math.cos(step_angle) - positions[i].z * Math.sin(step_angle);
              positions[i].z = positions[i].z * Math.cos(step_angle) + cx * Math.sin(step_angle);
          }
      }
      

      可以看到,上面是繞y軸旋轉,所以y的坐標不變,x和z需要經過下面的matrix變換:

      Transformation

      function transformImg(img, i) {
          var z = positions[i].z;
          img.translateX = center.x + rd_positions[i].x;
          img.translateY = center.x + rd_positions[i].y;
          //projection
          img.scaleX = img.scaleY = 0.5 * distance / Math.abs(camera_position.z - z);
          img.style.opacity =0.1+ 1 - (r - z) / (2 * r);
      }
      
      function render(){
          var i = 0,
              len=positions.length;
          for (; i < len; i++) {
              transformImg(img_list[i],i);
          }
      }
      

      初始化和循環

      function tick() {
          rotate();
          positionsProjection();
          render();
          requestAnimationFrame(tick);
      }
      
      (function () {
          randomPoints();
          createImgs();
          positionsProjection();
          tick();
      })();
      

      通過通過上面幾行代碼串整個流程。通過requestAnimationFrame循環執行tick。

      最后

      為了加深理解,你可以把源碼 clone下來,然后改代碼實現:

      • 試試繞著z軸旋轉
      • 試試繞著x軸旋轉
      • 試試切換下透視投影和正交投影
      • 透視投影的時候試著修改攝像機的z坐標
      • 正交投影的時候試著修改攝像機的z坐標
      • 透視投影的時候試著修改到投影面的距離
      • 正交投影的時候試著修改到投影面的距離
      • 不使用星星素材換過其他素材會達到意想不到的酷炫效果

      第二種實現方式:試試Transform(img,false)

      因為Transform第二個參數不傳,或者設置為false的時候是打開透視投影的。
      所以可以設置img.translateZ來使用瀏覽器自身的透視投影,省去positionsProjection過程。

      創建圖片的時候,使用下面的方式注入Transformation能力,

      Transform(img, false);
      
      • 即打開透視投影,
      • 即近大遠小,
      • 即不用自己去positionsProjection
      • 即不用自己去設置圖片的scaleX和scaleY

      渲染的時候直接使用原始坐標便可:

      function transformImg(img, i) {
          var p = positions[i];
          img.translateX =  p.x;
          img.translateY =  p.y;
          img.translateZ = p.z;
          img.style.opacity =0.1+ 1 - (r - p.z) / (2 * r);
      }
      
      function render(){
          var i = 0,
              len=positions.length;
          for (; i < len; i++) {
              transformImg(img_list[i],i);
          }
      }
      

      循環和初始化,不再需要投影過程:

      function tick() {
          rotate();
          render();
          requestAnimationFrame(tick);
      }
      
      (function () {
          randomPoints();
          createImgs();
          tick();
      })();
      

      transformjs

      transformjs提供了基礎的transformation能力,不與任何時間和運動庫綁定。雖然官網demo簡單,但是稍微費點腦細胞就可以做出很酷炫的效果。所以酷炫靠大家,用transformjs就對了。
      傳送門:transformjs 主頁 | transformjs Github

      所有例子可以在上面找到。

      主站蜘蛛池模板: 亚洲精品日本一区二区| 国产不卡精品一区二区三区| 亚洲第一香蕉视频啪啪爽| 开心激情站开心激情网六月婷婷| 亚洲色欲色欲WWW在线丝| 台东县| 成人欧美一区在线视频| 这里只有精品免费视频| 国产成人精品无码播放| 免费看无码自慰一区二区| 国产成人精品亚洲午夜| 九九热视频在线免费观看| 亚洲欧美日韩尤物AⅤ一区| 国产成人精品无码播放| 干老熟女干老穴干老女人| 国产精品中文字幕在线| 天天做天天爱夜夜爽| 不卡一区二区三区四区视频| 99网友自拍视频在线| 日本高清视频色欧WWW| 中文无码乱人伦中文视频在线| 97午夜理论电影影院| 亚洲成a人片在线观看久| 亚洲男人第一无码av网站| 亚洲午夜性猛春交xxxx| 成人国产精品免费网站| 99国精品午夜福利视频不卡99 | 综合色一色综合久久网| 亚洲中文字幕第二十三页| 人妻少妇精品视频二区| 久久96热在精品国产高清| 欧洲熟妇色xxxxx欧美| 鄂尔多斯市| 国产精品人妻| 国产尤物精品自在拍视频首页| 99久久99久久精品免费看蜜桃 | 国产无码高清视频不卡| 九九热精品在线观看视频| 国产伦精品一区二区三区| 色欲AV无码一区二区人妻| 少妇激情av一区二区三区|