Update canvas gradient example

This commit is contained in:
Tim Schaub
2022-01-07 13:14:52 -07:00
parent eed400ca1c
commit 35e1d29d6b
3 changed files with 27 additions and 76 deletions

File diff suppressed because one or more lines are too long

View File

@@ -1,13 +1,11 @@
---
layout: example.html
title: Styling feature with CanvasGradient or CanvasPattern
shortdesc: Example showing the countries vector layer styled with patterns and gradients.
shortdesc: Example showing a vector layer styled with a gradient.
docs: >
This example creates a [`CanvasPattern`](https://developer.mozilla.org/en-US/docs/Web/API/CanvasPattern)
and a [`CanvasGradient`](https://developer.mozilla.org/en/docs/Web/API/CanvasGradient). 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).
This example creates a [`CanvasGradient`](https://developer.mozilla.org/en/docs/Web/API/CanvasGradient).
The vector data is loaded from a file and features are filled with the gradient.
The same technique can be used with a [`CanvasPattern`](https://developer.mozilla.org/en-US/docs/Web/API/CanvasPattern).
tags: "canvas, gradient, pattern, style"
---
<div id="map" class="map"></div>

View File

@@ -1,4 +1,4 @@
import GeoJSON from '../src/ol/format/GeoJSON.js';
import KML from '../src/ol/format/KML.js';
import Map from '../src/ol/Map.js';
import VectorLayer from '../src/ol/layer/Vector.js';
import VectorSource from '../src/ol/source/Vector.js';
@@ -7,84 +7,42 @@ import {DEVICE_PIXEL_RATIO} from '../src/ol/has.js';
import {Fill, Stroke, Style} from '../src/ol/style.js';
import {fromLonLat} from '../src/ol/proj.js';
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
// Gradient and pattern are in canvas pixel space, so we adjust for the
// renderer's pixel ratio
const pixelRatio = DEVICE_PIXEL_RATIO;
// Generate a rainbow gradient
const gradient = (function () {
const 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;
})();
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
const gradient = context.createLinearGradient(0, 0, 1024 * pixelRatio, 0);
gradient.addColorStop(0, 'red');
gradient.addColorStop(1 / 6, 'orange');
gradient.addColorStop(2 / 6, 'yellow');
gradient.addColorStop(3 / 6, 'green');
gradient.addColorStop(4 / 6, 'aqua');
gradient.addColorStop(5 / 6, 'blue');
gradient.addColorStop(1, 'purple');
// Generate a canvasPattern with two circles on white background
const 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
const fill = new Fill();
const style = new Style({
fill: fill,
const vectorLayer = new VectorLayer({
background: 'white',
source: new VectorSource({
url: 'data/kml/states.kml',
format: new KML({extractStyles: false}),
}),
style: new Style({
fill: new Fill({color: gradient}),
stroke: new Stroke({
color: '#333',
width: 2,
width: 1,
}),
}),
});
/**
* 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.
*/
const getStackedStyle = function (feature) {
const id = feature.getId();
fill.setColor(id > 'J' ? gradient : pattern);
return style;
};
// Create a vector layer that makes use of the style function above…
const vectorLayer = new VectorLayer({
source: new VectorSource({
url: 'data/geojson/countries.geojson',
format: new GeoJSON(),
}),
style: getStackedStyle,
});
// … finally create a map with that layer.
const map = new Map({
layers: [vectorLayer],
target: 'map',
view: new View({
center: fromLonLat([16, 48]),
zoom: 3,
center: fromLonLat([-100, 38.5]),
zoom: 4,
}),
});