目錄
- 1.前言
- 2.添加一個面要素
- 3.線性漸變
- 3.1 第一個注意點
- 3.2 第二個注意點
- 4.中心漸變(徑向漸變)
- 5.總結
1.前言
??OpenLayers
官網有整個圖層的漸變示例,但是沒有單個要素的漸變示例,我們這里來補充一下。OpenLayers
中的漸變是通過fill
選項中實現的。fill
選項可以傳一個ColorLike
,本質是通過Canvas
實現的,此時ColorLike
對應的是CanvasPattern
或CanvasGradient
。
2.添加一個面要素
const source = new VectorSource();let polygon = new Feature({geometry:new Polygon([[[106.542384,30.485627],[106.542384,40.485627],[117.542384,40.485627],[117.542384,30.485627],[106.542384,30.485627],]])});source.addFeature(polygon)const vectorLayer = new VectorLayer({source: source,});const map = new Map({layers: [vectorLayer],target: 'map',view: new View({center: [126.980366, 37.52654],zoom: 1,projection:'EPSG:4326'}),});
3.線性漸變
//import {DEVICE_PIXEL_RATIO} from 'ol/has'
getLineGradientStyle(){const canvas = document.createElement('canvas');const context = canvas.getContext('2d');const pixelRatio = DEVICE_PIXEL_RATIO;let gradient = context.createLinearGradient(0,0,1024*pixelRatio,0);let mainColor = '#56e90e';let secondColor = '#0e57e9';gradient.addColorStop(0,mainColor);gradient.addColorStop(1,secondColor);return gradient;
}
let style = new Style({fill:new Fill({color:this.getLineGradientStyle()})
})
polygon.setStyle(style)
3.1 第一個注意點
??現在我們的要素在地圖的正中間,能看到兩個顏色之間的過渡。我們把地圖左鍵進行移動一下,使得要素分別在最后邊和最后邊,然后再來看看效果。
??發現了什么?效果是變化的!所以我們的漸變策略是不太對的,漸變填充應該根據面的范圍以及當前所處的位置來進行動態計算。具體來說就是要在createLinearGradient
的時候去動態計算.現在我把漸變改成從【512,0】到【1024,0】的漸變,然后我們把地圖往左移動,再看看效果
let gradient = context.createLinearGradient(512*pixelRatio,0,1024*pixelRatio,0);
??這次發現了什么?貌似始終是在【512,0】到【1024,0】漸變。但如果你真的這樣以為了,那你就錯了。現在把地圖往右移動,看看會發生什么事?
??好像漸變的位置發生了偏移,不是我們最初設定的【512,0】到【1024,0】了。為什么揮發生這種現象。我們來看OpenLayers
官網是是怎么解釋的。在OpenLayers
官網關于漸變有這樣一段描述:
翻譯過來就是
CanvasRenderingContext2D.fillStyle或CanvasRendering Context2D.strokeStyle接受的類型。表示顏色、圖案或漸變。圖案和漸變作為填充樣式的原點是從地圖坐標[0,0]增加512個css像素。對于無縫重復圖案,圖案圖像的寬度和高度必須是兩倍(2,4,8,…,512)。
??重點是這一句:圖案和漸變作為填充樣式的原點是從地圖坐標[0,0]增加512個css像素
??也就是說這個[0,0]是屏幕坐標,不是我們以為的經緯度坐標。而且漸變的位置也不是我們想要的,我們想要的是從某個經緯度到某個經緯度的漸變。
3.2 第二個注意點
??512個css像素是什么意思?
??答:屏幕在出廠時就從硬件上面決定了,用幾個物理像素來代表一個css像素。因此才有設備像素比這個參數,也就是我們上文導入的DEVICE_PIXEL_RATIO
。
4.中心漸變(徑向漸變)
getCenterGradientStyle(polygon){let canvas = document.createElement('canvas');const context = canvas.getContext('2d');let extent = polygon.getExtent()let minLon = extent[0]let maxLon = extent[2]let minLat = extent[1]let maxLat = extent[3]let resolution = this.map.getView().getResolution()const pixelRatio = DEVICE_PIXEL_RATIO;let height = (maxLat - minLat)/resolution*pixelRatiolet width = (maxLon-minLon)/resolution*pixelRatiocanvas.width = widthcanvas.height = heightlet radius = Math.max(height,width)let center = map.getPixelFromCoordinate([(minLon+maxLon)/2,(maxLat+minLat)/2])let gradient = context.createRadialGradient(center[0],center[1],radius/6,center[0],center[1],radius/2)let mainColor = '#56e90e';let secondColor = '#0e57e9';gradient.addColorStop(0,mainColor);gradient.addColorStop(1,secondColor);return gradient;
}
let style = new Style({fill:new Fill({color:this.getCenterGradientStyle()})
})
polygon.setStyle(style)
在change:resolution事件中去調用,保證算出來的寬高的正確性
5.總結
??OpenLayers
中的漸變效果實在很難令人滿意,又或者是我們理解的有問題,因為其是動態變化的,我們很難得到想要的結果。目前,我們要時刻注意監聽視圖的變化來修改漸變的效果。本文算是拋磚引玉吧,如果某位有志之士能誰能解決掉這個問題,希望能告訴我一下,回見~