我想实现一个相当复杂的功能,将一次全部动画在以GeoJSON多的FeatureCollection点(在网络上类似的项目:https://hvv.live/)。 我尝试使用react native映射框库随附的官方Drive线路示例,并将其修改为可用于多个点。
的问题是,具有多于6到7分动画后的性能显著点更新只有几次,而不是下降,并且平稳地进行动画的第二个。我的猜测是,这是由高数上由多个听众产生以GeoJSON几何的setState呼叫引起在RouteSimulator类的requestAnimationFrame方法被解雇。
我认为,解决办法是莫名其妙地等待RouteSimulator与新GeoJSON的源计算下一个点所有的点,然后更新状态,但是,我无法弄清楚如何做到这一点。任何帮助将不胜感激。
RouteSimulator类用于处理所有动画:
import { Animated, Easing } from 'react-native'
import MapboxGL from '@mapbox/react-native-mapbox-gl'
import cheapRuler from 'cheap-ruler'
var ruler = cheapRuler(55.7)
class Polyline {
constructor(lineStringFeature) {
this._trip = lineStringFeature.properties.trip
this._coordinates = lineStringFeature.geometry.coordinates
this._timestamps = lineStringFeature.properties.time
this._lineStringFeature = lineStringFeature
this._totalDistance = 0
this._departureTime = lineStringFeature.properties.time[0] / 1000
this._arrivalTime =
lineStringFeature.properties.time[
lineStringFeature.properties.time.length - 1
] / 1000
this._totalTime = this._arrivalTime - this._departureTime
this._totalDistance += ruler.lineDistance(this._coordinates)
this._speed = this._totalDistance / this._totalTime / 30
}
coordinateFromStart(distance) {
const pointAlongCheap = ruler.along(this._coordinates, distance)
const trip = this._trip
const pointAlong = MapboxGL.geoUtils.makePoint(pointAlongCheap, {
distance,
trip
})
return pointAlong
}
get totalDistance() {
return this._totalDistance
}
}
class RouteSimulator {
constructor(lineStrings) {
this._lineStrings = lineStrings.map(line => ({
polyline: new Polyline(line),
curDist: 0,
prevDist: 0
}))
}
addListener(listener) {
this._listener = listener
}
start() {
this.tick()
}
reset() {
this._previousDistance = 0
this._currentDistance = 0
this.start()
}
stop() {
if (this._anim) {
this._anim.stop()
}
}
tick() {
requestAnimationFrame(() => {
const animArray = []
this._lineStrings.forEach(line => {
line.prevDist = line.curDist
line.curDist += line.polyline._speed
const listener = step => {
const currentPosition = line.polyline.coordinateFromStart(
step.value
)
this.emit(currentPosition)
}
line._animatedValue = new Animated.Value(line.prevDist)
line._animatedValue.addListener(listener)
line._listener = listener
animArray.push(
Animated.timing(line._animatedValue, {
toValue: line.curDist,
duration: 1,
easing: Easing.linear,
useNativeDriver: false
})
)
})
Animated.parallel(animArray).start(() => {
this._lineStrings.forEach(line => {
line._animatedValue.removeListener(line.listener)
})
this.tick()
})
})
}
emit(pointFeature) {
this._listener(pointFeature)
}
}
export default RouteSimulator
然后我在具有地图的屏幕中调用此类
class MainMap extends React.Component {
constructor() {
super()
this.state = {
stopsAround: Mapbox.geoUtils.makeFeatureCollection(),
zoomLevel: 13,
fetching: false,
routes: null,
newRoutes: Mapbox.geoUtils.makeFeatureCollection(),
bounds: null,
currentPoint: null,
routeSimulator: null
}
}
componentDidMount() {
this.setState(
{
routes: nowTrips
},
() => {
this.onStart()
}
)
}
onStart() {
const routeSimulator = new RouteSimulator(this.state.routes)
routeSimulator.addListener(currentPoint => {
//Check if zoomed in to show the animation
if (this.state.zoomLevel >= 13) {
const newTransit = this.state.newRoutes
//Check if element was already added to the feature collection or is it the first time the function was called
const index = newTransit.features.findIndex(
element =>
element.properties.trip.id ===
currentPoint.properties.trip.id
)
if (index > -1) {
newTransit.features[index] = currentPoint
} else {
Mapbox.geoUtils.addToFeatureCollection(
newTransit,
currentPoint
)
}
//This is fired as much as possible and I think is causing all of the lag and problems
this.setState({ newRoutes: newTransit })
}
})
routeSimulator.start()
}
renderCurrentPoint() {
if (!this.state.newRoutes) {
return
}
return (
<Mapbox.ShapeSource id="animatable" shape={this.state.newRoutes}>
<Mapbox.CircleLayer
id="animatableStop"
style={{
circleRadius: 7,
circleColor: '#266ef1',
circleStrokeWidth: 3,
circleStrokeColor: '#FFFFFF'
}}
/>
</Mapbox.ShapeSource>
)
}
初始数据只是带有一堆时间戳记的geoJSON Linestrings数组。余计算开始和结束时间,然后内插。