来源:https://openlayers.org/en/latest/examples/canvas-gradient-pattern.html
这里需要注意的是渐变填充的是大背景,国家版图相当于一个蒙版,跟我想的那种每个国家单独填充不一样。。。
先看一下效果:
涉及两种填充方式 CanvasPattern
和 CanvasGradient。
国家名称数据加载自一个GeoJSON文件。有一个函数用来确定每个国家的填充风格。
The countries are loaded from a GeoJSON file. A style function determines for each country whether to use a fill with the CanvasGradient (rainbow colors) or a CanvasPattern (repeating stacked circles). Note: For seamless repeat patterns, image width and height of the pattern image must be a factor of two (2, 4, 8, ..., 512).
index.html
<!DOCTYPE html> <html lang="en"> <head> <title>Styling feature with CanvasGradient or CanvasPattern</title> <!-- The line below is only needed for old environments like Internet Explorer and Android 4.x --> <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=fetch,requestAnimationFrame,Element.prototype.classList,URL"></script> <style> .map { width: 100%; height:400px; } #map { /* Image craeted by tatyana, from https://sftextures.com/2014/10/22/blue-sky-with-blurred-white-clouds-seamless-textures/ */ background-image: url(ULR太长,点顶部连接自行复制-_-||); background-repeat: repeat; } </style> </head> <body> <div id="map" class="map"></div> <script src="index.js"></script> </body> </html>
index.js
import 'ol/ol.css'; import Map from 'ol/Map'; import View from 'ol/View'; import GeoJSON from 'ol/format/GeoJSON'; import {DEVICE_PIXEL_RATIO} from 'ol/has'; import VectorLayer from 'ol/layer/Vector'; import {fromLonLat} from 'ol/proj'; import VectorSource from 'ol/source/Vector'; import {Fill, Stroke, Style} from 'ol/style'; var canvas = document.createElement('canvas'); var context = canvas.getContext('2d'); // Gradient and pattern are in canvas pixel space, so we adjust for the // renderer's pixel ratio var pixelRatio = DEVICE_PIXEL_RATIO; // Generate a rainbow gradient var gradient = (function() { var grad = context.createLinearGradient(0, 0, 512 * pixelRatio, 0); grad.addColorStop(0, 'red'); grad.addColorStop(1 / 6, 'orange'); grad.addColorStop(2 / 6, 'yellow'); grad.addColorStop(3 / 6, 'green'); grad.addColorStop(4 / 6, 'aqua'); grad.addColorStop(5 / 6, 'blue'); grad.addColorStop(1, 'purple'); return grad; })(); // Generate a canvasPattern with two circles on white background var pattern = (function() { canvas.width = 8 * pixelRatio; canvas.height = 8 * pixelRatio; // white background context.fillStyle = 'white'; context.fillRect(0, 0, canvas.width, canvas.height); // outer circle context.fillStyle = 'rgba(102, 0, 102, 0.5)'; context.beginPath(); context.arc(4 * pixelRatio, 4 * pixelRatio, 3 * pixelRatio, 0, 2 * Math.PI); context.fill(); // inner circle context.fillStyle = 'rgb(55, 0, 170)'; context.beginPath(); context.arc(4 * pixelRatio, 4 * pixelRatio, 1.5 * pixelRatio, 0, 2 * Math.PI); context.fill(); return context.createPattern(canvas, 'repeat'); }()); // Generate style for gradient or pattern fill var fill = new Fill(); var style = new Style({ fill: fill, stroke: new Stroke({ color: '#333', 2 }) }); /** * The styling function for the vector layer, will return an array of styles * which either contains the aboove gradient or pattern. * * @param {import("../src/ol/Feature.js").default} feature The feature to style. * @return {Style} The style to use for the feature. */ var getStackedStyle = function(feature) { var id = feature.getId(); fill.setColor(id > 'J' ? gradient : pattern); return style; }; // Create a vector layer that makes use of the style function above… var vectorLayer = new VectorLayer({ source: new VectorSource({ url: 'data/geojson/countries.geojson', format: new GeoJSON() }), style: getStackedStyle }); // … finally create a map with that layer. var map = new Map({ layers: [ vectorLayer ], target: 'map', view: new View({ center: fromLonLat([16, 48]), zoom: 3 }) });
package.json
{ "name": "canvas-gradient-pattern", "dependencies": { "ol": "6.2.1" }, "devDependencies": { "parcel": "1.11.0" }, "scripts": { "start": "parcel index.html", "build": "parcel build --experimental-scope-hoisting --public-url . index.html" } }