Холст Техника Киткат (2) Рисунок Путь со стрелкой Эффект

внешний интерфейс Ресурсы изображений Icon Canvas

Несколько дней назад многие спрашивали, как нарисовать карту Гаоде.навигационная стрелкаЭффект, я думал об этом в свое время и было не сложно сделать его сначала холстом, а потоминтегрирован в мапбокс, при переходе на другую библиотеку карт также нужно только применить соответствующийГео для отображения координатфункция.

стиль рисования линий

При применении холста мы часто сталкиваемся с отрисовкой различных стилей линий, таких как пунктирные линии, градиентные линии, линии с узорами (стрелки, значки рельсов и т. д.) или анимационные эффекты пунктирных линий и узоров. Как показано на рисунке ниже, метод реализации суммирован.

各种线样式

Пунктирный стиль

  • Используйте метод CanvasRenderingContext2D.setLineDash, чтобы задать стиль пунктирной линии, который принимает параметр типа массива ([solid: number, empty:number]), который представляет соотношение пикселей сплошной пунктирной линии.

Например, ctx.setLineDash([10, 5]), вы можете нарисовать эффект пунктирной линии на картинке выше. Вы можете использовать свое воображение, чтобы создавать более необычные эффекты. Например, пусть движется пунктирная линия, появляется ощущение вращающегося света. .

Стиль градиентной линии

Создайте градиент с помощью функции createLinearGradient, затем установите его сегмент градиента, назначьте его для strokeStyle, и эффект градиента показан на начальном рисунке.

// 创建一个从左到右的渐变,从绿色渐变到几乎透明,
var gradient = ctx.createLinearGradient(0, 0, 600, 0);
gradient.addColorStop(0, "rgba(0,255,100,0.9)");
gradient.addColorStop(1, "rgba(255,255,255,0.1)");
ctx.strokeStyle = gradient;

Одна проблема заключается в том, что если вам нужноНаправление градиента соответствует направлению линии, это общее требование. Вам нужно только заранее рассчитать диапазон и направление каждой линии и создать соответствующий LinearGradient. По сути, это похоже на рисунок стрелки ниже.Обратный атан уголтоже самое.

стиль линии для рисунка значка

Наконец, это всеобъемлющее приложение.Я написал несколько функций холста и поместил их в предыдущий canvasOverlay.Его можно легко интегрировать в различные библиотеки, поддерживающие холст. Основная идея такова: (лень рисовать, идея относительно проста)

  • Каждыйнаправленный отрезокВ соответствии с координатами startPnt, endPnt обратно вычисляется угол тангенса в радианах.

  • Задайте stepSize, сгенерируйте координаты значка рисования на отрезке линии, переведите ctx.origin в эту точку и поверните угол в радианах, чтобы нарисовать смещение значка (те, кто знаком с холстом, должны понимать, что, манипулируя ось координат холста для рисования вращающихся элементов)

должен быть в курсе, расчет угла атан в радианах производится во втором и третьем квадрантах, которые будут перепутаны с первым и четвертым квадрантами. например внизу слевавектор направленных линийЕсть два отрицательных значения, но значение тангенса положительное, такое же, как и в первом квадранте, поэтому обратный расчет также будет вычислять угол меньше 90 градусов, который на самом деле больше 180 градусов, вам нужно + Math.PI

image.png

Вероятно, процесс рисования, код выглядит следующим образом:

function generatePoints(startP, endP, stepSize = 30, ctx, aniOffset = 0.5, img) {
    let radA = Math.atan((endP[1] - startP[1]) / (endP[0] - startP[0]));
    if ((endP[0] - startP[0]) < 0) {
        radA += Math.PI;
    }
    const dist = calcDist(startP, endP);
    let points = [];
    const steps = dist / stepSize;

    const drawImg = (pX, pY) => {
        if (img && ctx) {
            ctx.save();
            ctx.translate(pX , pY);  // consider img position and imgWidth/Height.
            ctx.rotate(radA);
            ctx.drawImage(img, -img.width / 2,  -img.width/2);
            ctx.restore();
        }
    }

    // gen points by stepSize.. if enable corner arrow, start s with (0~1) float number.
    for (let s = aniOffset; s <= steps; s += 1) {
        const pX = Math.round(startP[0] + s * stepSize * Math.cos(radA));
        const pY = Math.round(startP[1] + s * stepSize * Math.sin(radA));
        points.push([pX, pY]);
        drawImg(pX, pY);
    }
    // console.warn(`icon Number: ${points.length}`);
    return points;
}

Есть еще вопрос, который очень часто упоминается в последнее время, это тоже визуальная проблема, как иконки на канве соответствуют наклону карты. Вероятно, вы можете сделать это с точки зрения CSS3d или холста, первое должно быть проще. Практикуйтесь, когда у вас есть время.

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

Недавнее обновление (2019-10):

  • Повторно оптимизирован процесс расчета и рендеринга шаблона значка, что делает расчет положения значка вдоль линии более эффективным и плавным, что может обеспечить расчет + рендеринг со скоростью 60 кадров в секунду, а также плавную анимацию перехода стрелки.ОПЫТ ДЕМО ОНЛАЙН
  • Проблема с тем, что иконка подходит под угол наклона карты, уже решалась ранее и не публиковалась. По сути, это синхронизация наклона и угла поворота Вида карты с иконкой, или маркером, очень просто, не нужно вдаваться в подробности.онлайн опыт