Skip to content
目录

线的箭头

MO(H%25K5JS5%60_%60PTK6U%7BH%25CF.png

这里我们来介绍下怎样实现线的箭头效果,这里主要介绍四种需求下的箭头的实现

line arrow demo

VectorLayer的自带箭头

289_M45J4K%604X24OZ%2502T%5DR.png

使用起来比较简单,配置LineString的arrowStylearrowPlacement即可,可以用来进行简单的箭头需求

注意箭头的颜色和线条的样式是一样的,不可独立的配置箭头的样式的

js
const layer = new maptalks.VectorLayer("layer").addTo(map);

const line = new maptalks.LineString(getFeatureCoordinates(0), {
    arrowStyle: "classic",
    arrowPlacement: "point", // 'vertex-last', //vertex-first, vertex-last, vertex-firstlast, point,
    symbol: {
        lineColor: "red",
    },
}).addTo(layer);

LineStringLayer进行贴图

%250XVZUO%7DO%24DC536)S8D%60XDO.png

LineStringLayer 属于webgl图层,在包 maptalks-gl里. 这个效果最好

WARNING

linePatternGap 这个参数只有webgl图层里支持,VectorLayer里不支持的

复杂的道路效果我们可以进行创建多个路线并配置不同的样式来实现

js
const lineLayer = new maptalks.LineStringLayer("line").addTo(groupLayer);

const line1 = new maptalks.LineString(getFeatureCoordinates(1), {
    symbol: {
        lineStrokeColor: [1, 1, 1],
        lineStrokeWidth: 2,
        lineWidth: 26,
        lineColor: "#000",
    },
}).addTo(lineLayer);
const line2 = new maptalks.LineString(
    getFeatureCoordinates(1).map((c) => {
        return [...c, 0.1];
    }),
    {
        symbol: {
            linePatternFile: "./../assets/image/arrow.png",
            // linePatternDx: 0,
            linePatternGap: 1,
            // linePatternAnimSpeed: 0.1,
            lineWidth: 24,
        },
    },
).addTo(lineLayer);

顶点箭头且可交互

612%5B%5B%401B)L96_IIY%5DNR0YS7.png

有时我们不仅需要箭头,且箭头可以点击交互这样的需求,这时我们可以为每个顶点创建个Marker来实现

TIP

箭头的偏转角度计算用了 geolib 第三方库

js
const line3 = new maptalks.LineString(getFeatureCoordinates(2), {
    symbol: {
        lineWidth: 16,
        lineColor: "black",
    },
}).addTo(layer);

const vertexs = line3.getCoordinates();
for (let i = 0, len = vertexs.length; i < len; i++) {
    let c = vertexs[i];
    let c1 = vertexs[i],
        c2 = vertexs[i + 1];
    if (i === len - 1) {
        c1 = vertexs[i - 1];
        c2 = vertexs[i];
    }
    c1 = c1.toArray();
    c2 = c2.toArray();
    const rotationZ = getMarkerRotation(c1.slice(0, 2), c2.slice(0, 2));
    const point = new maptalks.Marker(c, {
        properties: {
            rotationZ,
        },
        symbol: {
            markerRotation: rotationZ,
            markerVerticalAlignment: "middle",
            markerFile: "./../assets/icon/arrow.png",
            markerWidth: 20,
            markerHeight: 20,
        },
    }).addTo(layer);
    arrows.push(point);
}
updateArrowRotation();

WARNING

当地图旋转时我们需要更新Marker的 markerRotation

js
function updateArrowRotation() {
    const bearing = map.getBearing();
    arrows.forEach((arrow) => {
        const rotationZ = arrow.getProperties().rotationZ;
        arrow.updateSymbol({
            markerRotation: rotationZ + bearing,
        });
    });
}

map.on("rotate", (e) => {
    updateArrowRotation();
});

等距箭头且箭头可交互

~S%7DLB0R7%60KVARDI%7DH%5BKA%24(I.png

在箭头可交互的基础上我们希望箭头分布是等距的,路径的切割我们使用了第三方库 lineseg

js
const line3 = new maptalks.LineString(getFeatureCoordinates(3), {
    symbol: {
        lineWidth: 16,
        lineColor: "blue",
    },
}).addTo(layer);

const vertexs = line3.getCoordinates();
const coordinates = vertexs.map((c) => {
    return c.toArray();
});
const chunks = lineseg.lineSeg(coordinates, { segDistance: 100 });

function createMarker(c, c1, c2) {
    const rotationZ = getMarkerRotation(c1.slice(0, 2), c2.slice(0, 2));
    const point = new maptalks.Marker(c, {
        properties: {
            rotationZ,
        },
        symbol: {
            markerRotation: rotationZ,
            markerVerticalAlignment: "middle",
            markerFile: "./../assets/icon/arrow.png",
            markerWidth: 20,
            markerHeight: 20,
        },
    }).addTo(layer);
    arrows.push(point);
}
for (let i = 0, len = chunks.length; i < len; i++) {
    const chunk = chunks[i];
    const chunkLen = chunk.length;
    let c = chunk[chunkLen - 1];
    let c1 = chunk[chunkLen - 2],
        c2 = chunk[chunkLen - 1];
    createMarker(c, c1, c2);
    if (i === 0) {
        c = chunk[0];
        c1 = c;
        c2 = chunk[1];
        createMarker(c, c1, c2);
    }
}

扩展

这里简单介绍了几种的箭头的实现,其他的效果你可以根据这里提供的思路进行不断的组合来实现,这里只是提供一些 思路

maptalks教程 document auto generated by mdpress and vitepress