Showing the line styling possibilities with canvas rendering.
This example demonstrates the line stroke styling capabilities when rendering with canvas. All stroke properties provided by ol/style/Stroke.js can be modified dynamically to observe their visual effect. In addition to the predefined line features, you can draw new lines directly on the map to experiment with different stroke configurations in real time.
import Map from 'ol/Map.js';
import View from 'ol/View.js';
import GeoJSON from 'ol/format/GeoJSON.js';
import Draw from 'ol/interaction/Draw.js';
import Modify from 'ol/interaction/Modify.js';
import Snap from 'ol/interaction/Snap.js';
import {defaults as defaultInteractions} from 'ol/interaction/defaults.js';
import TileLayer from 'ol/layer/Tile.js';
import VectorLayer from 'ol/layer/Vector.js';
import OSM from 'ol/source/OSM.js';
import VectorSource from 'ol/source/Vector.js';
import Stroke from 'ol/style/Stroke.js';
import Style from 'ol/style/Style.js';
const source = new VectorSource({
url: 'data/geojson/line-samples.geojson',
format: new GeoJSON(),
});
const vector = new VectorLayer({source: source});
const styleOptionsForm = document.getElementById('line-style-options-form');
function updateStyles() {
const formData = new FormData(styleOptionsForm);
const styles = [
new Style({
stroke: new Stroke({
color: formData.get('color'),
lineCap: formData.get('lineCap'),
lineJoin: formData.get('lineJoin'),
lineDash: formData
.get('lineDash')
?.split(',')
?.map((value) => Number(value)),
lineDashOffset: formData.get('lineDashOffset'),
miterLimit: formData.get('miterLimit'),
width: formData.get('width'),
offset: formData.get('offset'),
}),
}),
];
// If offset is defined, add a reference line style to also see the original line without offset
if (Math.abs(formData.get('offset')) > 0) {
styles.push(
new Style({
stroke: new Stroke({
color: '#aaa',
width: 1,
lineDash: [3, 3],
}),
}),
);
}
vector.setStyle(styles);
}
updateStyles();
styleOptionsForm.addEventListener('change', updateStyles);
const modify = new Modify({source});
const draw = new Draw({source, type: 'Polygon'});
const snap = new Snap({source: source});
const map = new Map({
layers: [
new TileLayer({
source: new OSM(),
}),
vector,
],
target: 'map',
view: new View({
center: [-8161939, 6095025],
zoom: 8,
}),
interactions: defaultInteractions().extend([modify, draw, snap]),
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Line Styles</title>
<link rel="stylesheet" href="node_modules/ol/ol.css">
<style>
.map {
width: 100%;
height: 400px;
}
#line-style-options-form {
display: grid;
grid-template-columns: 140px auto;
grid-template-rows: repeat(8, 1fr);
gap: 6px 10px;
align-items: center;
}
#line-style-options-form input[type="text"],
#line-style-options-form input[type="number"] {
padding: 2px 4px;
width: 100px;
}
.radios {
display: flex;
gap: 10px;
}
.radios input {
margin-right: 3px;
}
</style>
</head>
<body>
<div id="map" class="map"></div>
<form id="line-style-options-form">
<label for="color">Color</label>
<input type="color" id="color" name="color" value="#004D7D">
<span>Line Cap</span>
<div class="radios">
<label><input type="radio" name="lineCap" value="butt"> butt</label>
<label><input type="radio" name="lineCap" value="round" checked> round</label>
<label><input type="radio" name="lineCap" value="square"> square</label>
</div>
<span>Line Join</span>
<div class="radios">
<label><input type="radio" name="lineJoin" value="bevel"> bevel</label>
<label><input type="radio" name="lineJoin" value="round" checked> round</label>
<label><input type="radio" name="lineJoin" value="miter"> miter</label>
</div>
<label for="lineDash">Line Dash</label>
<input type="text" id="lineDash" name="lineDash" placeholder="1, 3">
<label for="lineDashOffset">Line Dash Offset</label>
<input type="number" id="lineDashOffset" name="lineDashOffset" min="-200" max="20" value="0">
<label for="miterLimit">Miter Limit</label>
<input type="number" id="miterLimit" name="miterLimit" min="1" max="20" value="10">
<label for="offset">Offset</label>
<input type="number" id="offset" name="offset" min="-20" max="20" value="0">
<label for="width">Width</label>
<input type="number" id="width" name="width" min="1" max="40" value="2">
</form>
<script type="module" src="main.js"></script>
</body>
</html>
{
"name": "line-styles",
"dependencies": {
"ol": "10.8.0"
},
"devDependencies": {
"vite": "^3.2.3"
},
"scripts": {
"start": "vite",
"build": "vite build"
}
}