Reputation: 1146
I have a layer that renders LineStrings and am trying to apply a glow effect to the lines. The Style I created uses a custom renderer to create a stroke with a gradient perpendicular to each line segment:
const glow_style = new Style({
renderer: (_coords, state) => {
const ctx = state.context;
const coords = _coords as Coordinate[];
ctx.lineWidth = 25;
for (let i = 1; i < coords.length; i++) {
const start = coords[i - 1];
const end = coords[i];
const [grd_start, grd_end] = getPerpendicularPoints(start, end, ctx.lineWidth);
const grd = ctx.createLinearGradient(grd_start[0], grd_start[1], grd_end[0], grd_end[1]);
grd.addColorStop(0, '#ffffff00');
grd.addColorStop(0.5, 'white');
grd.addColorStop(1, '#ffffff00');
ctx.strokeStyle = grd;
ctx.beginPath();
ctx.moveTo(start[0], start[1]);
ctx.lineTo(end[0], end[1]);
ctx.stroke();
}
}
});
This style works for completely straight lines, but breaks down at corners, because the gradient doesn't connect nicely between line segments. If ctx.lineCap
is left as butt
, the gradient is discontiguous around corners. If it's set to round
, the segments touch, but the gradient becomes discontinuous because of overlapping. Here are examples of each:
What options do I have for creating a smooth gradient along the entire LineString?
Upvotes: 2
Views: 1451
Reputation: 17962
It would be simpler to render the entire linestring without breaking it into segments by drawing lines of decreasing width. For a smooth gradient the opacity of each line should be defined as the fraction of the remaining transparency. It could even be done as an OpenLayers style array:
var steps = 13;
var styles = [];
for (var i = 0; i < steps; i++) {
styles.push(
new ol.style.Style({
stroke: new ol.style.Stroke({
color: [255, 255, 255, 1/(steps - i)],
width: (steps-i)*2 - 1
})
})
);
}
Upvotes: 5