TWaver - 專注UI技術(shù)

          http://twaver.servasoft.com/
          posts - 171, comments - 191, trackbacks - 0, articles - 2
            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          TWaver3D拓?fù)鋱D之球花綻放

          Posted on 2016-11-23 10:32 TWaver 閱讀(327) 評(píng)論(0)  編輯  收藏


          這樣一簇絢爛豐滿艷麗多姿的3D小球花,要多少代碼才能完成?其實(shí)不足百行,您信嗎?下面咱就看一下具體實(shí)現(xiàn)過程,讓您分分鐘學(xué)會(huì)用TWaver HTML5制作3D拓?fù)鋱D。


          搭建3D空間

          首先為花簇的綻放建一個(gè)展示的舞臺(tái)。接觸過TWaver2D的都知道,box、network是必不可少的,但對(duì)3D場(chǎng)景來說,還遠(yuǎn)遠(yuǎn)不夠。一是要添加鏡頭位置,確定我們?cè)谑裁唇嵌群途嚯x進(jìn)行觀察;二是要加上燈光,否則再美的畫面也看不見。燈光分為點(diǎn)光源和環(huán)境光,一般來說要一個(gè)環(huán)境光和若干點(diǎn)光源搭配才能出來好的效果。

          var box = new mono.DataBox();
          var network
          = new mono.Network3D(box, null, monoCanvas);
          mono.Utils.autoAdjustNetworkBounds(network,document.documentElement,
          'clientWidth','clientHeight');
          network.getCamera().setPosition(
          004000);
          network.isSelectable
          =function(){return false};
          network.setClearColor(
          'black');
          var pointLight 
          = new mono.PointLight(0xFFFFFF,0.8);
          box.add(pointLight);
          var pointLight 
          = new mono.PointLight(0xFFFFFF,0.5);
          pointLight.setPosition(
          500,2000,0);
          box.add(pointLight);
          box.add(
          new mono.AmbientLight(0x888888));

          創(chuàng)建3D小球花瓣


          每一個(gè)3D小球就是一個(gè)花瓣,是整個(gè)花簇的基礎(chǔ)部件,也是最容易做的,只要幾行代碼而已。


          function createNode(color){
            
          //var color = color || '#'+('00000'+(Math.random()*0x1000000<<0).toString(16)).slice(-6);
            var node=new mono.Sphere(10,BALL_SEGMENT,BALL_SEGMENT);
            node.s({
              
          'm.type''phong',
              
          'm.color': color,
              
          'm.ambient': color,
            });
            
          return node;
          }

          其中的BALL_SEGMENT是球體切片數(shù)量,數(shù)量越大生成的球體越圓滑,但計(jì)算量也就越大。解除注釋掉的那條語(yǔ)句將會(huì)每次生成一個(gè)隨機(jī)顏色的小球,這種五顏六色的感覺也別有趣味。


          生成3D花朵


          正如若干花瓣組成一朵小花,我們也要將若干個(gè)小球連接在一起。這一步最重要的是花瓣的排列,既要隨機(jī)有活力,又要規(guī)律有造型。實(shí)例中是將小球隨機(jī)排列在一個(gè)球面的局部。


          function getSpherePoint(r, angle1, angle2){
              var x
          =r*Math.sin(angle1)*Math.cos(angle2);
              var y
          =r*Math.cos(angle1);
              var z
          =r*Math.sin(angle1)*Math.sin(angle2);
              
          return new mono.Vec3(x, y, z);
          }

          有了花瓣的擺放位置,一朵花也就很容易開放了:

          function createTree(box, count, range, offset, color){
              var angleStep
          =Math.PI/50;
              var center
          =new mono.Sphere(10,BALL_SEGMENT,BALL_SEGMENT);
              center.s({
                  
          'm.type''phong',
                  
          'm.color': color,
                  
          'm.ambient': color,
              });
              box.add(center);
              
          for(var i=0;i<count;i++){
                  var node
          = createNode(color);
                  var r
          =1000;
                  var angle1
          =range*Math.random()/5;
                  var angle2
          =Math.PI*2*Math.random();
                  var point
          =getSpherePoint(r, angle1, angle2);
                  point.y
          -=offset;
                  node.setPosition(point);
                  node.setParent(center);
                  box.add(node);
                  box.add(createLink(center, node));
              }
              
          return center;
          }

          通過改變其參數(shù),可以開出不同的花朵。其中count是花瓣的數(shù)量,range是花朵球面的角度,offset是花瓣到花托的長(zhǎng)度,color是花朵的顏色。


          綻放3D花簇

          剩下的工作就極其簡(jiǎn)單了,先建一個(gè)中心小球,再通過兩個(gè)循環(huán),就生成了有兩層花朵的球狀花簇。


          var center=createNode('red');
          box.add(center);
          for(var i=0;i<40;i++){
              var angle1
          =Math.random()*Math.PI;
              var angle2
          =Math.random()*Math.PI*2;
              var point
          =getSpherePoint(1000, angle1, angle2);
              var tree
          =createTree(box, 100, Math.PI*0.4800'yellow');
              tree.setPosition(point.x, point.y, point.z);
              var rotation
          =point.rotationTowards(new mono.Vec3(0,1,0), point);
              tree.setRotation(rotation);
              box.add(createLink(center, tree));
          }

          當(dāng)然,你可以說這根本不像什么花簇。其實(shí)本來也不是要做一個(gè)現(xiàn)實(shí)的什么東西,只是為了用一段小而美的程序,讓大家領(lǐng)略TWaver3D拓?fù)鋱D的風(fēng)采。如果您從中g(shù)et到了什么技能和興趣,那才是我們的真正目的!

          實(shí)際上,這個(gè)例子稍作變化,就可以用來展示豐富的3D網(wǎng)絡(luò)拓?fù)鋱D、各種復(fù)雜數(shù)據(jù)的樹狀關(guān)系圖。你一定可以讓它綻放的更加美麗!


          為了證實(shí)代碼確實(shí)不足百行,特附上完整源碼:

           1 <!DOCTYPE html>
           2 <html>
           3 <head>
           4     <title>Mono Test</title>
           5     <script type="text/javascript" src = "t.js"></script>
           6     <script type="text/javascript">
           7         var BALL_SEGMENT=7;
           8         function init(){
           9             var box = new mono.DataBox();
          10             var network= new mono.Network3D(box, null, monoCanvas);
          11             mono.Utils.autoAdjustNetworkBounds(network,document.documentElement,'clientWidth','clientHeight');
          12             network.getCamera().setPosition(004000);
          13             network.isSelectable=function(){return false};
          14             network.setClearColor('black');
          15             var pointLight = new mono.PointLight(0xFFFFFF,0.8);
          16             box.add(pointLight);
          17             var pointLight = new mono.PointLight(0xFFFFFF,0.5);
          18             pointLight.setPosition(500,2000,0);
          19             box.add(pointLight);
          20             box.add(new mono.AmbientLight(0x888888));
          21             var center=createNode('red');
          22             box.add(center);
          23             for(var i=0;i<10;i++){
          24                 var angle1=Math.random()*Math.PI;
          25                 var angle2=Math.random()*Math.PI*2;
          26                 var point=getSpherePoint(300, angle1, angle2);
          27                 var tree=createTree(box, 100, Math.PI*0.6700'#'+('00000'+(Math.random()*0x1000000<<0).toString(16)).slice(-6));
          28                 tree.setPosition(point.x, point.y, point.z);
          29                 var rotation=point.rotationTowards(new mono.Vec3(0,1,0), point);
          30                 tree.setRotation(rotation);
          31                 box.add(createLink(center, tree));
          32             }
          33             for(var i=0;i<40;i++){
          34                 var angle1=Math.random()*Math.PI;
          35                 var angle2=Math.random()*Math.PI*2;
          36                 var point=getSpherePoint(1000, angle1, angle2);
          37                 var tree=createTree(box, 100, Math.PI*0.4800);
          38                 tree.setPosition(point.x, point.y, point.z);
          39                 var rotation=point.rotationTowards(new mono.Vec3(0,1,0), point);
          40                 tree.setRotation(rotation);
          41                 box.add(createLink(center, tree));
          42             }
          43         }
          44         function createTree(box, count, range, offset, color){
          45             var angleStep=Math.PI/50;
          46             var center=new mono.Sphere(10,BALL_SEGMENT,BALL_SEGMENT);
          47             center.s({
          48                 'm.type''phong',
          49                 'm.color': color,
          50                 'm.ambient': color,
          51             });
          52             box.add(center);
          53             for(var i=0;i<count;i++){
          54                 var node= createNode(color);
          55                 var r=1000;
          56                 var angle1=range*Math.random()/5;
          57                 var angle2=Math.PI*2*Math.random();
          58                 var point=getSpherePoint(r, angle1, angle2);
          59                 point.y-=offset;
          60                 node.setPosition(point);
          61                 node.setParent(center);
          62                 box.add(node);
          63                 box.add(createLink(center, node));
          64             }
          65             return center;
          66         }
          67         function getSpherePoint(r, angle1, angle2){
          68             var x=r*Math.sin(angle1)*Math.cos(angle2);
          69             var y=r*Math.cos(angle1);
          70             var z=r*Math.sin(angle1)*Math.sin(angle2);
          71             return new mono.Vec3(x, y, z);
          72         }
          73         function createNode(color){
          74             var color = color || '#'+('00000'+(Math.random()*0x1000000<<0).toString(16)).slice(-6);
          75             var node=new mono.Sphere(10,BALL_SEGMENT,BALL_SEGMENT);
          76             node.s({
          77                 'm.type''phong',
          78                 'm.color': color,
          79                 'm.ambient': color,
          80             });
          81             return node;
          82         }
          83         function createLink(node1, node2){
          84             var link=new mono.Link(node1, node2);
          85             link.s({
          86                 'm.transparent'true,
          87                 'm.opacity'0.2,
          88             });
          89             return link;
          90         }     
          91     </script>
          92 </head>
          93 <body onload = 'init()'>
          94     <div>
          95         <canvas id="monoCanvas"/>
          96     </div>
          97 </body>
          98 </html>


          如有任何問題,可以留言,或者發(fā)郵件給我們:tw-service@servasoft.com。

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 武功县| 双牌县| 竹北市| 蕲春县| 甘孜县| 宁津县| 壶关县| 冕宁县| 左贡县| 南开区| 永康市| 乃东县| 林芝县| 策勒县| 廊坊市| 迁西县| 霍林郭勒市| 常州市| 莱芜市| 张家界市| 琼海市| 合川市| 全州县| 淳安县| 阿鲁科尔沁旗| 龙游县| 沙湾县| 漯河市| 黄浦区| 岑巩县| 浦城县| 南木林县| 云梦县| 鄂尔多斯市| 曲水县| 大同县| 临沂市| 巫山县| 清水县| 乌鲁木齐县| 泰顺县|