D3、openlayers的一次嘗試
近期嘗試了一個webgl相關的內容,有些小激動,及時分享一下我的測試示例,效果如下:
此示例分從業務角度分為兩部分,一個部分為d3展示的柱圖,另一部分則為用openlayers展示的地圖。而其難點卻在界面的交互效果。實現內容的翻面。
一、翻面效果的實現
此效果看似神奇,理解清楚原理後也還是很簡單的。主要用到css3的backface-visibility屬性,他表示元素正面運動到用戶不可見的位置時,當前元素是否可見。
<div class="flip-container"> <div class="flip-wrap"> <div class="front"> </div> <div class="back"> </div> </div> </div>
以上是html代碼的結構,flip-container作為最外層的包裝,在其上面應用了perspective屬性(此屬性的詳細解釋可參考此文章),表示視距,他能影響到我們3d變換效果是否更接近真實;flip-wrap作為前、後兩個div的父級的參照,在現代瀏覽上此處可以不加入3d變換屬性,而Ie則需要加入。front和back這兩個div都是需要加上3d變換效果的。而對front的z-index層級加高,是為了讓其默認顯示在最前面。back默認讓其旋轉至-180deg,是為了讓其過濾效果更為流暢和平滑。
.flip-container{ -webkit-perspective: 1000; -moz-perspective: 1000; perspective: 1000; width: 600px; height: 400px; margin: 0 auto; } .flip-wrap{ position: relative; width: 100%; height: 100%; /*transform-style設置在父級,為了兼容IE*/ transform-style: preserve-3d; -moz-transform-style: preserve-3d; -ms-transform-style: preserve-3d; } .flip-wrap > .front, .flip-wrap >.back{ position: absolute; left: 0; top: 0; height: 100%; width: 100%; -moz-transition: .6s; -ms-transition: .6s; transition: .6s; transform-style: preserve-3d; -moz-transform-style: preserve-3d; -ms-transform-style: preserve-3d; backface-visibility: hidden; /*動畫完成後,沒正面面向用戶,則隱藏*/ } .flip-wrap > .front{ background: red; transform: rotateY(0deg); z-index: 2; /*z軸高一點,覆蓋back層*/ } .flip-wrap > .back{ background: green; transform: rotateY(-180deg); } .flip-container:hover .front{ transform: rotateY(180deg); } .flip-container:hover .back{ transform: rotateY(0deg); }
二、JS部分實現
JS代碼的結構圖:
flip.js:為此組件 入口
flip.ol.js:openlayer的具體實現
flip.d3.js:d3繪制柱圖的具體實現
flip.store.js:數據接口,用於返回從後臺接口獲取到的數據
city.js:城市名稱數據字典
adapter/d3.js:用於將後臺數據轉換為d3可用的數據格式
adapter/ol.js:用於將後臺數據轉換為openlayers可用的數據格式
adapter/provider.js:轉換器工廠入口
本示例主要以flip.js為主,在組合d3和ol相關功能。
class Flip { constructor(options){ this.options = _.assign(Flip.Default, options); this.d3 = new d3(this.options); this.ol = new ol(this.options); this.store = new store(); this.adapterProvider = new AdapterProvider(); } /** * 組件的渲染 */ render (){ //這裏發送數據到內部進行渲染 var promise = this.store.getData();//這裏應該是個異步 //還需要一個數據轉換工廠,實現數據=>d3,或者數據=>ol的轉換 promise.then((data)=>{ var d3Data = this.adapterProvider.convert(data, AdapterProvider.type.d3); //同步 var olData = this.adapterProvider.convert(data, AdapterProvider.type.ol); this.d3.render(d3Data); this.ol.render(olData); }); } }
在構造函數中對存儲器、轉換器、d3和ol進行實例化,然後提供render方法進行數據的獲取和繪制,具體細節下載代碼查看。
D3、openlayers的一次嘗試