jga*_*abb 6 requestanimationframe reactjs maptiler
在我的reactjs应用程序中,我使用了一个名为pidegon-maps的轻量级地图库来显示船只位置。在不尝试使用更大的库(传单、谷歌地图反应)的情况下,我尝试为船只所走的路线制作动画。
从这个问题中汲取灵感,我尝试创建一个类似的实现。
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();
}, []);
Run Code Online (Sandbox Code Playgroud)
由于某种原因,它在动画中运行得非常快,然后就消失了。它还仅将线显示为直线(南北,根本没有角度),因此它实际上并没有连接。距离是正确的,但角度不正确。我尝试将其移动到状态,因为放大和缩小时,它会导致地图重新渲染。这工作得很好,但它只在放大和缩小时才会有动画效果。因此,我可以将其速度减慢至 1000 倍,然后放大和缩小并观看它的动画,但它不会自行执行此操作。
目前,它位于 useEffect 中,但我也将其删除并尝试不使用它。
有两种方法可以实现此目的,一种是lineString通过修改坐标来增加 ,就像您想要实现的那样。
另一种方法是使用 CSS 让 svg 自行绘制,这种方法更简单,推荐使用。关键的 CSS 属性stroke-dashoffset现在已得到现代浏览器的广泛支持。
方法 1:通过 CSS 使用带有两个点的线
注意:不要忘记指定 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;
}
}
Run Code Online (Sandbox Code Playgroud)
import { GeoJson, GeoJsonFeature, Map, Marker } from "pigeon-maps";
const start = [0.108266, 52.202758];
const end = [0.11556, 52.201733];
export function MyMap() {
const feature = {
"type": "Feature",
"properties": {
},
"geometry": {
"type": "LineString",
"coordinates": [start, end]
}
}
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={{
id: "VesslePath1",
strokeWidth: "4",
stroke: "black",
pathLength:"1"
}}
>
<GeoJsonFeature feature={feature} />
</GeoJson>
</Map>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
方法 2:您原来的方法,其中有多个点LineString
我不确定您的代码有什么问题,因为只useEffect显示了方法。然而,也存在一些潜在的问题:
[lng,lat]相反[lat,lng]requestAnimationFrame框架在这里如何使用以及是否正确使用。因此,我已经切换到setIntervals.lineString如果它是一条直线,则没有必要使用两个以上的点。setCoordinates((prevCoordinates) => [
//...prevCoordinates,
start,
[start[0] + currentDiff[0], start[1] + currentDiff[1]],
]);
Run Code Online (Sandbox Code Playgroud)
修改后的代码如下所示:
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>
);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
124 次 |
| 最近记录: |