HTML 5 Canvasベースの3 D圧力器の逆シーケンス化


実際の応用では、JSONファイルを操作することによって3 D上のシーンの変化を操作できるのは非常に便利なことだと思います.特にエディタをしてグラフィックをドラッグしたり、グラフィック上の一連の変化をしたりするときに、データを直感的に反応させることができます.ここでは簡単に基礎的な例を作って、参考にしてみましょう.
この例のアドレス:http://www.hightopo.com/guide...
実際のシーンの再生:
まず、この例のシーンを構築してみましょう.よく知っている友达はすでに見ているかもしれません.このシーンは3つの部分に分かれています.左、右上、右下です.HTはht.widget.SplitViewによって簡単にシーンを分割することができ、良好なページレイアウトを実現し、最後にこの分割コンポーネントをhtmlのbody体に追加する.
//    
dataModel = new ht.DataModel();//    
                
g3d = new ht.graph3d.Graph3dView(dataModel);//3D   
propertyView = new ht.widget.PropertyView(dataModel);//     
formPane = new ht.widget.FormPane();//    
rightSplit = new ht.widget.SplitView(propertyView, formPane, 'v', 100);//    
                        
new ht.widget.SplitView(g3d, rightSplit, 'h', 0.65).addToDOM();  

次に、シーンにエンティティを追加し、エンティティを3 Dシーンに追加します.この場合、エンティティに様々な属性とスタイル、ラベルをタグとして追加できます.この例で使用するエンティティは3 Dモデルで、ht.Default.parseObj関数を使用してobjファイルとmtlファイルを解析します.
//    
var params = {center: true};//JSON          ht.Default.parseObj    
var modelMap = ht.Default.parseObj(meter_obj, meter_mtl, params);//  obj mtl  ,       map  json   ,             

もちろん、meter_を宣言したことが前提です.Objおよびmeter_mtlは2つのファイルで、ここでは2つの部分をjsファイルにそれぞれ配置し、ヘッダで呼び出します.
上の動図から,この例で変化が必要なモデル部分は「ポインタ」と下の「スイッチ」の2つの部分のみであることが分かるので,この2つのobjモデルの部分を遍歴的に取得し,3 Dモデルを登録する:
var array = [];
for(var name in modelMap){
    var model = modelMap[name];//modelMap     
    array.push(model);
                    
    if(name === 'pointer'){//obj              pointer
        model.mat = {//      ,              
            func: function(data){
                var start = Math.PI * 0.736,
                range = Math.PI * 1.49,   
                angle = start - range * data.a('meter.value') / 4;//      meter.value   
                return ht.Default.createMatrix([//   JSON     、                  
                    { t3: [0, -82.5, 0] },
                    { r3: [0, 0, angle] },
                    { t3: [0, 82.5, 0]  }
                ]);
            }
        };                         
    }
    if(name === 'switch'){//obj              switch
        model.mat = {
            func: function(data){
                return ht.Default.createMatrix([
                    { t3: [0, 48.5, 0] },
                    { r3: [0, 0, data.a('meter.angle')] },
                    { t3: [0, -48.5, 0]  }
                ]);
            }
        }; 
        model.color = {
            func: function(data){
                if(data.a('meter.angle')){
                    return 'rgb(186, 0, 0)';
                }else{
                    return 'black';
                }
            }
        };
    }
}
ht.Default.setShape3dModel('meter', array);//  3D  ,   modeling              ,      JSON     

その後、ユーザーは必要な場所で直接属性shape 3 dをここに登録した3 Dモデル名に設定することができ、以下に3つのノードを作成し、ノードをこの3 Dモデルに設定します.
for(var i=0; i<3; i++){//  3    meter
    var node = new ht.Node();
    node.setTag(i);//   tag   
    node.setName('Meter - 00' + (i+1));//                
    node.s({
        'label.color': 'white',
        'label.background': '#5271B8',
        'label.face': 'center',
        'label.position': 23,
        'label.scale': 2,
        'label.reverse.flip': true, 
                        
        'note.scale': 1.5,//      ,                  
        'note.t3': [-30, -5, -90], 
                        
        'note2.scale': 1.2,
        'note2.position': 17,
        'note2.t3': [0, -20, -30],
        'note2.color': 'black',
        'note2.background': 'yellow', 
                        
        'shape3d': 'meter',//         meter 3D   
        'shape3d.scaleable': false,
        'wf.visible': 'selected',//         
        'select.brightness': 1
    });
    node.a({//                        
        'meter.value': i+1,
        'meter.angle': i * Math.PI / 3
    });
    node.p3(i*200-200, params.rawS3[1]/2, i===1?100:-100);                    
    node.r3(0, -Math.PI/6*(i-1), 0);
    node.s3(params.rawS3);//         rawS3        
    dataModel.add(node); //                     
}
dataModel.sm().ss(dataModel.getDataByTag(1));//       tag    1   

ここではノードに2つの寸法を追加し、文字ヒントとしてgetNote/getNote 2(HTの1つのノードで2つ目の寸法がサポートされているのでnote 2の2番目の寸法が提供されている)関数をリロードすることでnoteの命名方法を再ロードすることができ、もちろんHTの他の類似の文字ヒントでもこのような方法で文字の表示情報を変更することができます.ここでは、meter.valueとmeter.angleの2つのプロパティの動的データをデータバインディングで取得します.
g3d.getNote = function(data){//   getNote   
    return 'Value:' + data.a('meter.value').toFixed(2);
};
g3d.getNote2 = function(data){
    var value = Math.round(data.a('meter.angle') / Math.PI * 180);//    meter.angle   ,                       
    return value ? 'Angle:' + value : 'Switch is off';
};

また、シーンの表示部分では、eyeとcenterを実現する値を変更することで、視線が遠くて近い効果を実現します.
var oldEye = g3d.getEye().slice(0),
oldCenter = g3d.getCenter().slice(0),
newEye = [200, 300, 650],
newCenter = [0, params.rawS3[1]/2, 0];

ht.Default.startAnim({//                
    duration: 1000,//    
    easing: function(t){ //      ,     ht.Default.animEasing
        return (t *= 2) < 1 ? 0.5 * t * t : 0.5 * (1 - (--t) * (t - 2));                      
    },
    action: function(k){//action       ,                k      easing(t)        
        g3d.setEye(
            oldEye[0] + (newEye[0] - oldEye[0]) * k,
            oldEye[1] + (newEye[1] - oldEye[1]) * k,
            oldEye[2] + (newEye[2] - oldEye[2]) * k
        );
        g3d.setCenter(
            oldCenter[0] + (newCenter[0] - oldCenter[0]) * k,
            oldCenter[1] + (newCenter[1] - oldCenter[1]) * k,
            oldCenter[2] + (newCenter[2] - oldCenter[2]) * k
        );    
    }                  
});

左実装完了~次に実装右上部、属性値の表示および制御について、名前、meter.value、meter.angleおよび回転rotationの4つの属性を追加し、データバインド操作属性バーの値によって3 Dモデルの表示状態を変更し、データバインディングaccessTypeとnameの値を取得することで、このプロパティを呼び出します.
propertyView.addProperties([//  json                
    {
        name: 'name',//           accessType,   accessType       setName/getName      
        editable: true//        
    },
    {
        name: 'meter.value',//    name  ,     accessType       Data     
        accessType: 'attr',//   getAttr/setAttr         
        editable: true,
        slider: {
            min: 0,
            max: 4
        }
    },
    {
        name: 'meter.angle',
        accessType: 'attr',
        editable: true,
        formatValue: function(value){//                 
            return Math.round(value / Math.PI * 180);
        },
        slider: {
            min: 0,
            max: Math.PI,
            step: Math.PI/180*5,//          
            getToolTip: function(){//              
                return Math.round(this.getValue() / Math.PI * 180);
            }
        }
    },
    {
        name: 'rotation',
        editable: true,
        formatValue: function(value){
            return Math.round(value / Math.PI * 180);
        },
        slider: {
            min: -Math.PI,
            max: Math.PI,
            step: Math.PI/180*5,
            getToolTip: function(){
                return Math.round(this.getValue() / Math.PI * 180);
            }
        }
    }                    
]); 

最後に右下のformPaneフォームパネルの解析を行います.formPaneはaddRow関数を使用してフォームに行を追加します.このフォームには2行あり、最初の行には2つの部分があります.
formPane.addRow([//         
    {
        id: 'export',
        button: {//                                
            label: 'Export JSON',
            onClicked: function(){//        
                var json = dataModel.serialize();
                formPane.v('textArea', json);
            }
        }
    },
    {
        button: {                            
            label: 'Import JSON',
            onClicked: function(){
                dataModel.clear();//      
                dataModel.deserialize(formPane.v('textArea'));//      textArea         ,       id  
            }
        }
    }
],
[0.1, 0.1]);  //                  1     ,  1                                 
formPane.addRow([
    {
        id: 'textArea',
        textArea: {
        }
    }
],
[0.1], 0.1);  

これで、プロパティバーやJSONファイルを修正することで、3 Dで修正した効果を直接見ることができます~どうですか?クールで速いのではないでしょうか.