deck.gl + tripslayer без реагирования
Как я могу включить анимацию TripsLayer без реакции? Пример TripsLayer использует React, и я действительно не знаю, как преобразовать его в чистый JS. Пожалуйста, посмотрите на "одушевленную" функцию в коде ниже. Я пытался обновить состояние слоя, но он не работает (нет анимации TripsLayer). Я не знаю, где я должен назначить переменную времени.
Демонстрация TripsLayer: https://deck.gl/#/examples/custom-layers/trip-routes
Реагируйте на версию моего кода: https://github.com/uber/deck.gl/blob/master/examples/website/trips/app.js
Документы для TripsLayer: https://github.com/uber/deck.gl/tree/master/modules/experimental-layers/src/trips-layer
Мой код:
import {MapboxLayer} from '@deck.gl/mapbox';
import {TripsLayer} from '@deck.gl/experimental-layers';
import mapboxgl from 'mapbox-gl';
class App
{
constructor()
{
this.stateInfo = { time: 600 };
}
get state()
{
return this.stateInfo;
}
animate() {
var loopLength = 18000; // unit corresponds to the timestamp in source data
var animationSpeed = 30; // unit time per second
const timestamp = Date.now() / 1000;
const loopTime = loopLength / animationSpeed;
var time = Math.round(((timestamp % loopTime) / loopTime) * loopLength);
// HOW SHOULD I USE time VARIABLE???
window.requestAnimationFrame(this.animate.bind(this));
}
}
var obido = new App();
var tripsLayerObido = new TripsLayer({
id: 'trips',
data: 'trips/tripsKR.json',
getPath: d => d.segments,
getColor: d => (d.vendor === 0 ? [253, 128, 93] : [23, 184, 190]),
opacity: 0.6,
strokeWidth: 30,
trailLength: 180,
currentTime: obido.state.time
});
const LIGHT_SETTINGS = {
lightsPosition: [-74.05, 40.7, 8000, -73.5, 41, 5000],
ambientRatio: 0.05,
diffuseRatio: 0.6,
specularRatio: 0.8,
lightsStrength: [2.0, 0.0, 0.0, 0.0],
numberOfLights: 2
};
export const INITIAL_VIEW_STATE = {
longitude: 19.93,
latitude: 50.03,
zoom: 12.8,
maxZoom: 19,
pitch: 60,
bearing: 0
};
mapboxgl.accessToken = "XXX";
const map = new mapboxgl.Map({
container: 'app',
style: 'mapbox://styles/elninopl/cjnlge6rl094w2so70l1cf8y5',
center: [INITIAL_VIEW_STATE.longitude, INITIAL_VIEW_STATE.latitude],
zoom: INITIAL_VIEW_STATE.zoom,
pitch: INITIAL_VIEW_STATE.pitch,
layers: [tripsLayerObido]
});
map.on('load', () => {
obido.animate(0);
});
3 ответа
Я здесь немного опоздал, но вот пример использования deck.gl
TripsLayer
с помощью Scripting API (без React).
<script src="https://unpkg.com/deck.gl@^8.4.0/dist.min.js"></script>
<script src="https://unpkg.com/@deck.gl/carto@^8.4.0/dist.min.js"></script>
<script src="https://libs.cartocdn.com/mapbox-gl/v1.13.0/mapbox-gl.js"></script>
<link href="https://libs.cartocdn.com/mapbox-gl/v1.13.0/mapbox-gl.css" rel="stylesheet" />
<div id="map" style="width: 100vw; height: 100vh"></div>
const ambientLight = new deck.AmbientLight({
color: [255, 255, 255],
intensity: 1.0
});
const pointLight = new deck.PointLight({
color: [255, 255, 255],
intensity: 2.0,
position: [-74.05, 40.7, 8000]
});
const lightingEffect = new deck.LightingEffect({ ambientLight, pointLight });
const material = {
ambient: 0.1,
diffuse: 0.6,
shininess: 32,
specularColor: [60, 64, 70]
};
const theme = {
buildingColor: [74, 80, 87],
trailColor0: [253, 128, 93],
trailColor1: [23, 184, 190],
material,
effects: [lightingEffect]
};
const LOOP_LENGTH = 1800;
const ANIMATION_SPEED = 0.4;
async function initialize() {
deck.carto.setDefaultCredentials({
username: 'public',
apiKey: 'default_public',
});
// Fetch Data from CARTO
// Notice that you can use any Deck.gl layer with CARTO datasets getting GeoJSON data from CARTO's API. This method is recommended for complex layers with datasets below 50Mb
const tripsUrl = 'https://public.carto.com/api/v2/sql?q=SELECT the_geom, vendor, timestamps FROM sf_trips_v7&format=geojson';
const geojsonTripsData = await fetch(tripsUrl).then(response => response.json());
// TripsLayer needs data in the following format
const layerData = geojsonTripsData.features.map(f => ({
vendor: f.properties.vendor,
timestamps: f.properties.timestamps,
path: f.geometry.coordinates[0]
}));
const staticLayers = [
// This is only needed when using shadow effects
new deck.PolygonLayer({
id: 'ground-layer',
data: [[[-74.0, 40.7], [-74.02, 40.7], [-74.02, 40.72], [-74.0, 40.72]]],
getPolygon: f => f,
stroked: false,
getFillColor: [0, 0, 0, 0]
}),
new deck.carto.CartoSQLLayer({
id: 'buildings-layer',
data: 'SELECT the_geom_webmercator, height FROM sf_buildings',
extruded: true,
wireframe: true,
opacity: 0.5,
getElevation: f => f.properties.height,
getFillColor: [74, 80, 87],
material: theme.material
})
];
// Create Deck.GL map
const deckgl = new deck.DeckGL({
container: 'map',
mapStyle: 'https://basemaps.cartocdn.com/gl/dark-matter-nolabels-gl-style/style.json',
initialViewState: {
longitude: -74,
latitude: 40.73,
zoom: 12,
pitch: 45,
bearing: 0
},
controller: true,
layers: staticLayers,
effects: theme.effects
});
let time = 0;
function animate() {
time = (time + ANIMATION_SPEED) % LOOP_LENGTH;
window.requestAnimationFrame(animate);
}
setInterval(() => {
deckgl.setProps({
layers: [
...staticLayers,
new deck.TripsLayer({
id: 'trips-layer',
data: layerData,
getPath: d => d.path,
getTimestamps: d => d.timestamps,
getColor: d => (d.vendor === 0 ? theme.trailColor0 : theme.trailColor1),
opacity: 0.3,
widthMinPixels: 2,
rounded: true,
trailLength: 180,
currentTime: time,
shadowEnabled: false
})
]
});
}, 50);
window.requestAnimationFrame(animate);
}
initialize();
Да, это работает.
function animate(timestamp) {
var timestamp = Date.now() / 1000;
var loopTime = loopLength / animationSpeed;
curtime= ((timestamp % loopTime) / loopTime) * loopLength;
requestAnimationFrame(animate);
tripLayer.setProps({ currentTime: curtime });
}
Пожалуйста попробуйте setProps
, который обновляет слой моих поездок:
this.tripsLayer.setProps({ currentTime: this.currentTime });