Skip to content

Commit

Permalink
feat: improve updateCamera()
Browse files Browse the repository at this point in the history
* add support for 'duration' and 'bounds'
* return promise for camera animation
  • Loading branch information
Hsieh Chin Fan committed Nov 3, 2024
1 parent b35dc99 commit 962bdeb
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 28 deletions.
28 changes: 23 additions & 5 deletions src/BasicLeafletRenderer.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -169,13 +169,31 @@ const Renderer = class extends defaultExport {
}
}

updateCamera (options, animation) {
const latLon = L.latLng(options.center[1], options.center[0])
if (animation) {
this.map.flyTo(latLon, options.zoom)
async updateCamera ({ center, zoom, bounds, animation, padding, duration }) {
const latLon = center ? L.latLng(center[1], center[0]) : this.map.getCenter()
const options = {
animate: animation ?? false,
padding: [padding, padding],
duration: (duration ?? 250) / 1000,
}

if (bounds) {
const [[w, s], [e, n]] = bounds
const latLngBounds = new this.L.LatLngBounds([[s, w], [n, e]])
if (!latLngBounds.isValid()) {
throw new Error('Bounds are not valid.')
}
const target = this.map._getBoundsCenterZoom(latLngBounds, options)
this.map.flyTo(target.center, target.zoom, options)
} else if (animation) {
this.map.flyTo(latLon, zoom ?? this.map.getZoom(), options)
} else {
this.map.setView(latLon, options.zoom)
this.map.setView(latLon, zoom)
}

return new Promise(resolve => {
setTimeout(resolve, duration ?? 0)
})
}

project ([lng, lat]) {
Expand Down
23 changes: 16 additions & 7 deletions src/BasicMaplibreRenderer.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
renderByScriptTargetWith,
} from './mapclay.mjs'
/* eslint-disable-next-line no-unused-vars */
import * as M from 'maplibre-gl'
import maplibregl from 'maplibre-gl'
import { addProtocols } from 'maplibre-gl-vector-text-protocol'
import { TerraDrawMapLibreGLAdapter } from 'terra-draw'
loadCSS('https://unpkg.com/[email protected]/dist/maplibre-gl.css')
Expand Down Expand Up @@ -190,16 +190,25 @@ const Renderer = class extends defaultExport {
}
}

updateCamera (options, useAnimation) {
if (useAnimation) {
async updateCamera ({ bounds, center, zoom, animation, ...others }, useAnimation) {
if (bounds) {
this.map.fitBounds(bounds, { linear: true, ...others })
} else if (animation || useAnimation) {
this.map.flyTo({
center: options.center,
zoom: options.zoom,
center: center ?? this.map.getCenter(),
zoom: zoom ?? this.map.getZoom(),
...others,
})
} else {
this.map.setCenter(options.center)
this.map.setZoom(options.zoom)
this.map.setCenter(center)
this.map.setZoom(zoom)
}

return new Promise(resolve => {
this.map.on('zoomend', () => {
resolve('zoomend')
})
})
}

project ([lng, lat]) {
Expand Down
34 changes: 18 additions & 16 deletions src/BasicOpenlayersRenderer.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -184,20 +184,20 @@ const Renderer = class extends defaultExport {
return element
}

async addTileData ({ map, data }) {
async addTileData ({ map, data, ol }) {
const tileData = data.filter(record => record.type === 'tile')

const styleDatum = tileData.filter(datum => datum.type === 'style')[0]
if (!styleDatum && tileData.length === 0) {
const baseLayer = new layer.Tile({
source: new source.OSM(),
source: new ol.source.OSM(),
title: 'OSM Carto',
})
map.addLayer(baseLayer)
} else {
tileData.forEach(datum => {
const tileLayer = new layer.Tile({
source: new source.XYZ({ url: datum.url }),
source: new ol.source.XYZ({ url: datum.url }),
title: datum.title ? datum.title : 'Anonymous',
})
map.addLayer(tileLayer)
Expand Down Expand Up @@ -245,23 +245,26 @@ const Renderer = class extends defaultExport {
// }
}

updateCamera (options, useAnimation) {
async updateCamera ({ center: lonLat, zoom, bounds, duration, padding }) {
const map = this.map
const view = map.getView()
const xy = this.ol.proj.fromLonLat(options.center, this.crs)
if (useAnimation) {
flyTo(
map,
{ center: xy, zoom: options.zoom },
() => null,
)
const center = lonLat ? this.ol.proj.fromLonLat(lonLat, this.crs) : view.getCenter()

if (bounds) {
const boundsTransformed = bounds
.map(lonLat => this.ol.proj.fromLonLat(lonLat, this.crs))
view.fit(boundsTransformed.flat(), { duration, padding: Array(4).fill(padding) })
} else {
view.animate({
center: options.center,
zoom: options.zoom,
duration: 300,
center,
zoom: zoom ?? view.getZoom(),
duration,
})
}

return new Promise(resolve => {
setTimeout(resolve, duration ?? 0)
})
}

project = ([x, y]) =>
Expand All @@ -280,8 +283,7 @@ const Renderer = class extends defaultExport {
}

// Pan map to a specific location
function flyTo (map, status, done) {
const duration = 2500
function flyTo (map, status, done, { duration = 2500 } = {}) {
const view = map.getView()
const nextZoom = status.zoom ? status.zoom : view.getZoom()
const nextCenter = status.center ? status.center : view.center
Expand Down

0 comments on commit 962bdeb

Please sign in to comment.