Открывающие слои: градиент свечения на LineString - PullRequest
1 голос
/ 03 февраля 2020

У меня есть слой, который визуализирует LineStrings и пытаюсь применить эффект свечения к линиям. Созданный мною стиль использует пользовательский рендер для создания обводки с градиентом, перпендикулярным каждому отрезку линии:

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();
    }
  }
});

Этот стиль работает для абсолютно прямых линий, но разбивается по углам, поскольку градиент не соединить красиво между отрезками. Если ctx.lineCap оставить как butt, градиент будет прерывистым по углам. Если установлено значение round, сегменты соприкасаются, но градиент становится прерывистым из-за перекрытия. Вот примеры каждого из них:

gradient glow w/ gradient glow w/

Какие варианты у меня есть для создания плавного градиента вдоль всей LineString

1 Ответ

4 голосов
/ 04 февраля 2020

Было бы проще визуализировать всю линейную строку, не разбивая ее на сегменты, рисуя линии уменьшающейся ширины. Для плавного градиента непрозрачность каждой линии должна быть определена как доля оставшейся прозрачности. Это можно сделать даже в виде массива в стиле OpenLayers:

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
            })
        })
    );
}
...