1. 程式人生 > >基於WebGL架構的3D視覺化平臺ThingJS——實現櫃子開關門動畫

基於WebGL架構的3D視覺化平臺ThingJS——實現櫃子開關門動畫

ThingJS是基於WebGL架構的物聯網3D視覺化PasS平臺,零門檻、高效率、低成本開發各類3D應用,大大降低了傳統3D視覺化開發。

第一步,載入場景(場景為預先搭建好的),這裡可以用摸摸搭自己搭建場景連結,摸摸搭官網:http://www.3dmomoda.com/

//載入場景程式碼
var app = new THING.App({ 
    // 場景地址
    "url": "http://www.thingjs.com/./uploads/wechat/oLX7p05lsWJZUIxnIWsNXAzJ40X8/scene/Test",
    //背景設定
    "skyBox" :"BlueSky"
});

第二步,建立一個Cang類繼承THING.Thing。對THING.Thing類進行拓展

class Cang extends THING.Thing {
    constructor(app) {
        super(app);
        this.isCang = true;
        this.ui = null;
    }

    openDoor() {
        this.playAnimation('open1');
    }

     closeDoor() {
        this.playAnimation('close1');
    }
createUI() { if (this.ui) return; var cabinet = this; // 建立widget (動態繫結資料用) var panel = THING.widget.Panel({ width: "110px", closeIcon: false, opacity: 0.8, }); this.panel = panel; panel.addString
(this, 'name').name('機櫃'); // 建立obj ui (跟隨物體用) var ui = app.create({ type: 'UI', parent: this, el: panel.domElement, offset: [0, cabinet.size[1], 0] }); this.ui = ui; } // 顯示介面 showUI(boolValue) { if (!this.ui) this.createUI(); this.panel.visible = boolValue; } }

第三步,新增Cang類別,註冊這個類

THING.Utils.addCastType('Cang', /Cang/);  
THING.factory.registerClass('Cang', Cang);
Cang.current = null;
Cang.open = false;

第四步,初始化Cang類

function init_cangs() {
    var cangs = app.query('.Cang');

    // 雙擊左鍵開門
    cangs.on('dblclick', function() {

        // 攝影機飛行
        var pos = this.selfToWorld([0, 2.0, 2.1]);
        var targ = this.position;
        targ[1] += 0.95;
        app.camera.flyTo({
            time: 1000,
            position: pos,
            target: targ, 
        });

        // 機櫃開門動畫
        if (Cang.current) {
            Cang.current.closeDoor();
            Cang.current = null;
        }
        this.openDoor();

        // 設定為當前
        Cang.current = this;        
        this.style.outlineColor = null; // 當前機櫃不溝邊
    })

    // 右鍵關門
    app.on('click', function(event) {
        if (event.button == 2) {
            if (Cang.current) {
                Cang.current.closeDoor();
                Cang.current = null;
            } else {
                // 如果沒有當前機櫃則飛到一個最佳位置
                app.camera.flyTo({
                    time: 1500,
                    position: [-10.4, 13.6, 12.3],
                    target: [3.6, -4, -1.7], 
                });
            }
        }
    });

    // 機櫃 滑過溝邊
    cangs.on('mouseon', function () {
        if (this != Cang.current) {
            this.style.outlineColor = '#00ff00';
            this.showUI(true);
        }
    });
    cangs.on('mouseoff', function () {
        this.style.outlineColor = null;
        this.showUI(false);
    });

    
}

第五步,場景載入時初始化機櫃,將攝像頭角度設定到合理位置

在這裡插入程式碼片app.on('load', function() {
     //攝影機飛行到合適位置
     app.camera.flyTo({
         time: 1000,
         position: [-15.8, 14.3, 17.9],
       target: [0.3, -2.0, 1.5]
    });

    init_cangs();
});

這是搭建好的預覽圖 這樣簡單便捷的搭建方式是不是被驚豔到了呢,以下是全部程式碼感興趣的小夥伴,copy下去體驗吧

//載入場景程式碼
var app = new THING.App({ 
    // 場景地址
    "url": "http://www.thingjs.com/./uploads/wechat/oLX7p05lsWJZUIxnIWsNXAzJ40X8/scene/Test",
    //背景設定
    "skyBox" :"BlueSky"
});

app.on('load', function() {
    // 攝影機飛行到合適位置
    app.camera.flyTo({
        time: 1000,
        position: [-15.8, 14.3, 17.9],
        target: [0.3, -2.0, 1.5]
    });

    init_cangs();
});

//--------------------------------------------------------------------------------------
//機櫃類
class Cang extends THING.Thing {
    constructor(app) {
        super(app);
        this.isCang = true;
        this.ui = null;
    }

    openDoor() {
        this.playAnimation('open1');
    }

     closeDoor() {
        this.playAnimation('close1');
    }
    
    createUI() {
        if (this.ui)
            return;
        var cabinet = this;

        // 建立widget (動態繫結資料用)
        var panel = THING.widget.Panel({
            width: "110px",
            closeIcon: false,
            opacity: 0.8,
        });
        this.panel = panel;
        panel.addString(this, 'name').name('機櫃');

        // 建立obj ui (跟隨物體用)
        var ui = app.create({
            type: 'UI',
            parent: this,
            el: panel.domElement,
            offset: [0, cabinet.size[1], 0]
        });
        this.ui = ui;   
    }

    // 顯示介面
    showUI(boolValue) {
        if (!this.ui)
            this.createUI();

        this.panel.visible = boolValue;
    }

} 
THING.Utils.addCastType('Cang', /Cang/);  
THING.factory.registerClass('Cang', Cang);
Cang.current = null;
Cang.open = false;

function init_cangs() {
    var cangs = app.query('.Cang');

    // 雙擊左鍵開門
    cangs.on('dblclick', function() {

        // 攝影機飛行
        var pos = this.selfToWorld([0, 2.0, 2.1]);
        var targ = this.position;
        targ[1] += 0.95;
        app.camera.flyTo({
            time: 1000,
            position: pos,
            target: targ, 
        });

        // 機櫃開門動畫
        if (Cang.current) {
            Cang.current.closeDoor();
            Cang.current = null;
        }
        this.openDoor();

        // 設定為當前
        Cang.current = this;        
        this.style.outlineColor = null; // 當前機櫃不溝邊
    })

    // 右鍵關門
    app.on('click', function(event) {
        if (event.button == 2) {
            if (Cang.current) {
                Cang.current.closeDoor();
                Cang.current = null;
            } else {
                // 如果沒有當前機櫃則飛到一個最佳位置
                app.camera.flyTo({
                    time: 1500,
                    position: [-10.4, 13.6, 12.3],
                    target: [3.6, -4, -1.7], 
                });
            }
        }
    });

    // 機櫃 滑過溝邊
    cangs.on('mouseon', function () {
        if (this != Cang.current) {
            this.style.outlineColor = '#00ff00';
            this.showUI(true);
        }
    });
    cangs.on('mouseoff', function () {
        this.style.outlineColor = null;
        this.showUI(false);
    });

    
}