如何在Reactjs中使用pidgeon-maps动画化Map上的点之间的线?

k3bvogb1  于 12个月前  发布在  React
关注(0)|答案(1)|浏览(127)

在我的reactjs应用程序中,我使用了一个名为pidegon-maps的轻量级 matplotlib 来显示船只的位置,我没有尝试使用更大的库(传单,谷歌Mapreact),而是尝试用动画来显示船只的路线。
从这个question中获得灵感,我试图创建一个类似的实现。

useEffect(() => {

let start = [0.108266, 52.202758];
let end = [0.11556, 52.201733];

const speedFactor = 500;

let diffX = parseFloat(end[0]) - parseFloat(start[0]);
let diffY = parseFloat(end[1]) - parseFloat(start[1]);
let sfX = diffX / speedFactor;
let sfY = diffY / speedFactor;

let i = 0;
let j = 0;

let lineCoordinates = [];

while (i < diffX || Math.abs(j) < Math.abs(diffY)) {
  lineCoordinates.push([start[0] + i, start[0] + j]);

  if (i < diffX) {
    i += sfX;
  }

  if (Math.abs(j) < Math.abs(diffY)) {
    j += sfY;
  }
}

console.log(lineCoordinates);
let animationCounter = 0;

const animateLine = () => {
  if (animationCounter < lineCoordinates.length) {
    geojson.features[0].geometry.coordinates.push(lineCoordinates[animationCounter]);
    requestAnimationFrame(animateLine);
    animationCounter++;
    
  }

}

animateLine();

}, []);

字符串
由于某些原因,它在动画中运行得非常快,然后就消失了。它也只显示直线(南北,没有Angular ),所以它实际上没有连接。距离是正确的,但不是Angular 。我试着将其移动到状态,bc放大和缩小时,它会导致Map重新渲染。这工作正常,但是它只有在放大和缩小的时候才有动画效果,所以我可以把它放慢到1000的速度,然后放大和缩小,看它有动画效果,但是它不会自己做。
目前,它在一个使用效果,但我也删除了它,并尝试没有以及。

at0kjp5o

at0kjp5o1#

有两种方法可以实现这一点,一种是通过修改坐标来增长lineString,就像你试图实现的那样。
另一种方法是使用CSS来绘制svg本身,这是更容易和推荐的方法。关键的CSS属性stroke-dashoffset现在是现代浏览器的widely supported

方法1:使用CSS使用两点直线

Sandbox Demo
注意:不要忘记为SVG指定路径长度,如下所示。

#VesslePath1 {
    stroke-dasharray: 1;
    stroke-dashoffset: 0;
    /*remove 'infinite' if you don't want the animation to repeat*/
    animation: dash 3s linear forward infinite;
}

@keyframes dash {
    from{
        stroke-dashoffset: 1;
    }
    to {
        stroke-dashoffset: 0;
    }
}

个字符

方法2:你原来的方法,在LineString中有多个点

我不确定你的代码有什么问题,因为只显示了useEffect方法。但是,有一些潜在的问题:

  1. GeoJson坐标([lng,lat])与鸽子Map坐标([lat,lng])相反
    1.不知道你的requestAnimationFrame框架在这里是如何使用的,如果它使用正确。因此,我已经切换到setIntervals
    1.如果lineString是一条直线,则没有必要使用两个以上的点。
setCoordinates((prevCoordinates) => [
    //...prevCoordinates,
    start,
    [start[0] + currentDiff[0], start[1] + currentDiff[1]],
]);


修改后的代码如下:

import { GeoJson, GeoJsonFeature, Map, Marker } from "pigeon-maps";
import { useEffect, useState } from "react";

const speedFactor = 300;
const start = [0.108266, 52.202758];
const end = [0.11556, 52.201733];
const diffX = parseFloat(end[0]) - parseFloat(start[0]);
const diffY = parseFloat(end[1]) - parseFloat(start[1]);
const sfX = diffX / speedFactor;
const sfY = diffY / speedFactor;

export function MyMap() {

    const [coordinates, setCoordinates] = useState([start, [start[0] + sfX, start[1] + sfY]]);

    useEffect(() => {
        let currentDiff = [sfX, sfY]
        const interval = setInterval(() => {
            
            currentDiff[0] += sfX;
            currentDiff[1] += sfY;

            if (Math.abs(currentDiff[0]) > Math.abs(diffX)  || Math.abs(currentDiff[1]) > Math.abs(diffY)) {
                setCoordinates([
                    start,
                    end,
                ]);
                clearInterval(interval);
                return;
            }
            
            setCoordinates([
                start,
                [start[0] + currentDiff[0], start[1] + currentDiff[1]],
            ]);
        }, 10);

        return () => clearInterval(interval);
    }, []);

    const feature = {
        "type": "Feature",
        "properties": {
        },
        "geometry": {
            "type": "LineString",
            "coordinates": coordinates
        }
    }

    return (
        <div>
            <Map height={600} width={1000} defaultCenter={[52.202245, 0.111913]} defaultZoom={15}>
            <Marker width={50} anchor={[52.202758, 0.108266]} />
            <Marker width={50} anchor={[52.201733, 0.11556]} />

                <GeoJson
                    svgAttributes={{
                        strokeWidth: "4",
                        stroke: "black",
                    }}
                >
                    <GeoJsonFeature feature={feature} />
                </GeoJson>
            </Map>
        </div>
    );
}

相关问题