Cesium指南-自定義原生js組件

Cesium中可操作的模塊都是由Widget組成的,比如地圖上的首頁按鈕腮郊,點擊按鈕后地圖將恢復(fù)到地球狀態(tài)摹蘑,看似一個很簡單的功能,代碼卻不少轧飞,這是由于使用了組件化的思想衅鹿,將一些功能抽成組件的方式方便添加和刪除。下面就使用原生的javascript來實現(xiàn)一個放大縮小地圖的組件过咬,后面再介紹使用用vue來實現(xiàn)其它的組件大渤。主要包括ZoomInOut .js,ZoomInOut .css,ZoomInOutViewModel.js三個文件效果圖如下所示:

WX20210418-190206@2x.png

1.創(chuàng)建ViewModel文件

自定義組件采用的是MVVM的思想,主要借助于knockout這個js庫來實現(xiàn)ViewModel泵三,因此在創(chuàng)建自定義組件的時候需要創(chuàng)建一個ViewModel的文件,該文件主要用于定義屬性衔掸、創(chuàng)建事件的實現(xiàn)烫幕。

1.1 定義屬性

使用Object.defineProperties重寫getset方法敞映。如下所示:

Object.defineProperties(ZoomInOutViewModel.prototype, {
    scene: {
        get: function () {
            return this._scene;
        },
    },
    zoomIn: {
        get: function () {
            return this._zoomIn;
        },
    },
    zoomOut: {
        get: function () {
            return this._zoomOut;
        },
    },
});

1.2 創(chuàng)建事件

使用createCommand進行創(chuàng)建事件,

this._zoomIn = createCommand(function () {
    });
//ZoomInOutViewModel.js
import defined from "../../Core/defined.js";
import DeveloperError from "../../Core/DeveloperError.js";
import knockout from "../../ThirdParty/knockout.js";
import createCommand from "../createCommand.js";

function ZoomInOutViewModel(scene) {
    if (!defined(scene)) {
        throw new DeveloperError("scene is required.");
    }

    this._scene = scene;

    var that = this;
    this._zoomOut = createCommand(function () {
        // 獲取當前鏡頭位置的笛卡爾坐標
        let cameraPos = that._scene.camera.position;
        // 獲取當前坐標系標準
        let ellipsoid = that._scene.globe.ellipsoid;
        // 根據(jù)坐標系標準诗芜,將笛卡爾坐標轉(zhuǎn)換為地理坐標
        let cartographic = ellipsoid.cartesianToCartographic(cameraPos);
        // 獲取鏡頭的高度
        let height = cartographic.height;
        that._scene.camera.zoomOut(height * 1.2);
    });

    this._zoomIn = createCommand(function () {
        // 獲取當前鏡頭位置的笛卡爾坐標
        let cameraPos = that._scene.camera.position;
        // 獲取當前坐標系標準
        let ellipsoid = that._scene.globe.ellipsoid;
        // 根據(jù)坐標系標準,將笛卡爾坐標轉(zhuǎn)換為地理坐標
        let cartographic = ellipsoid.cartesianToCartographic(cameraPos);
        // 獲取鏡頭的高度
        let height = cartographic.height;
        that._scene.camera.zoomIn(height/3);
    });

    this.zoomInTooltip = "放大";
    this.zoomOutTooltip = "縮小";

    knockout.track(this, ["zoomInTooltip"]);
    knockout.track(this, ["zoomOutTooltip"]);
}

Object.defineProperties(ZoomInOutViewModel.prototype, {
    scene: {
        get: function () {
            return this._scene;
        },
    },
    zoomIn: {
        get: function () {
            return this._zoomIn;
        },
    },
    zoomOut: {
        get: function () {
            return this._zoomOut;
        },
    },
});
export default ZoomInOutViewModel;

2.創(chuàng)建元素

創(chuàng)建元素跟平時我們使用js創(chuàng)建元素的方式是一樣的,主要不同點在于事件的綁定不一樣栓霜,這里綁定事件是直接在setAttribute中使用click進行事件綁定翠桦,click指定的函數(shù)名為ViewModel中創(chuàng)建的事件函數(shù),如下所示:

var zoomOut = document.createElement("button");
    zoomOut.style.marginTop = '5px';
    zoomOut.style.fontWeight = 'bold';
    zoomOut.type = "button";
    zoomOut.className = "cesium-button cesium-toolbar-button cesium-home-button";
    zoomOut.setAttribute(
        "data-bind",
        "\
    attr: { title: zoomOutTooltip },\
    click: zoomOut"
    );
    zoomOut.innerText = "-";
    element.appendChild(zoomOut);

3.綁定元素

創(chuàng)建好ViewModel后胳蛮,需要將ViewModel與元素進行綁定销凑,采用knockout中的applyBindings進行元素的綁定,如下所示:

knockout.applyBindings(viewModel, element);

4.添加元素到地圖上

創(chuàng)建好元素并綁定后仅炊,需要將其顯示在地圖上斗幼,首先找到Viewer.js文件,在/Cesium/Source/Widgets/Viewer/Viewer.js目錄下抚垄,然后將ZoomInOut.js引入進行再進行實例化蜕窿,將新的元素添加到viewerContainer上谋逻,如下所示:

import ZoomInOut from "../ZoomInOut/ZoomInOut.js";
  //ZoomInOut
  var zoomInOutContainer = document.createElement("div");
  zoomInOutContainer.className = "cesium-viewer-zoomInOutContainer";
  viewerContainer.appendChild(zoomInOutContainer);
  var zoomInOut = new ZoomInOut(zoomInOutContainer,scene);
//ZoomInOut.js
import defined from "../../Core/defined.js";
import destroyObject from "../../Core/destroyObject.js";
import DeveloperError from "../../Core/DeveloperError.js";
import knockout from "../../ThirdParty/knockout.js";
import getElement from "../getElement.js";
import ZoomInOutViewModel from "./ZoomInOutViewModel.js";

/**
 * 放大縮小組件
 * @param container
 * @param scene
 * @constructor
 */
function ZoomInOut(container, scene) {
    if (!defined(container)) {
        throw new DeveloperError("container is required.");
    }
    container = getElement(container);
    var viewModel = new ZoomInOutViewModel(scene);

    var element = document.createElement("div");

    var zoomIn = document.createElement("button");
    zoomIn.type = "button";
    zoomIn.className = "cesium-button cesium-toolbar-button cesium-home-button";
    zoomIn.setAttribute(
        "data-bind",
        "\
    attr: { title: zoomInTooltip },\
    click: zoomIn"
    );
    zoomIn.innerText = "+";
    element.appendChild(zoomIn);

    var zoomOut = document.createElement("button");
    zoomOut.style.marginTop = '5px';
    zoomOut.style.fontWeight = 'bold';
    zoomOut.type = "button";
    zoomOut.className = "cesium-button cesium-toolbar-button cesium-home-button";
    zoomOut.setAttribute(
        "data-bind",
        "\
    attr: { title: zoomOutTooltip },\
    click: zoomOut"
    );
    zoomOut.innerText = "-";
    element.appendChild(zoomOut);

    container.appendChild(element);

    knockout.applyBindings(viewModel, element);

    this._container = container;
    this._viewModel = viewModel;
    this._element = element;
}

Object.defineProperties(ZoomInOut.prototype, {
    container: {
        get: function () {
            return this._container;
        },
    },
    viewModel: {
        get: function () {
            return this._viewModel;
        },
    },
});

/**
 * 判斷是否銷毀組件,由于能調(diào)用該方法桐经,所以一定是沒銷毀的毁兆,因此直接返回false
 * @returns {boolean}
 */
ZoomInOut.prototype.isDestroyed = function () {
    return false;
};

/**
 * 銷毀組件
 */
ZoomInOut.prototype.destroy = function () {
    knockout.cleanNode(this._element);
    this._container.removeChild(this._element);

    return destroyObject(this);
};
export default ZoomInOut;

5.引入樣式文件

如果有創(chuàng)建css文件,需要引入到項目中阴挣,首先找到widgets.css文件气堕,目錄在/Cesium/Source/Widgets/widgets.css,然后使用@import url(./ZoomInOut/ZoomInOut.css);引入樣式文件畔咧。

.cesium-viewer-zoomInOutContainer{
    display: block;
    width: 30px;
    height: 100px;
    margin: 0;
    border-radius: 0;
    position: absolute;
    right:12px;
    top: 40px;
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末茎芭,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子誓沸,更是在濱河造成了極大的恐慌骗爆,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蔽介,死亡現(xiàn)場離奇詭異,居然都是意外死亡煮寡,警方通過查閱死者的電腦和手機虹蓄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來幸撕,“玉大人薇组,你說我怎么就攤上這事∽” “怎么了律胀?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長貌矿。 經(jīng)常有香客問我炭菌,道長,這世上最難降的妖魔是什么逛漫? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任黑低,我火速辦了婚禮,結(jié)果婚禮上酌毡,老公的妹妹穿的比我還像新娘克握。我一直安慰自己,他們只是感情好枷踏,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布菩暗。 她就那樣靜靜地躺著,像睡著了一般旭蠕。 火紅的嫁衣襯著肌膚如雪停团。 梳的紋絲不亂的頭發(fā)上旷坦,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機與錄音客蹋,去河邊找鬼塞蹭。 笑死,一個胖子當著我的面吹牛讶坯,可吹牛的內(nèi)容都是我干的番电。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼辆琅,長吁一口氣:“原來是場噩夢啊……” “哼漱办!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起婉烟,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤娩井,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后似袁,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體洞辣,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年昙衅,在試婚紗的時候發(fā)現(xiàn)自己被綠了扬霜。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡而涉,死狀恐怖著瓶,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情啼县,我是刑警寧澤材原,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站季眷,受9級特大地震影響余蟹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜子刮,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一客叉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧话告,春花似錦兼搏、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至病线,卻和暖如春吓著,著一層夾襖步出監(jiān)牢的瞬間鲤嫡,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工绑莺, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留暖眼,地道東北人。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓纺裁,卻偏偏與公主長得像诫肠,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子欺缘,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容