2019-11-04 10:59:08 +01:00
|
|
|
import { DeepZoomMap } from './map.js'
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The MapView class is responsible for a consistent map view.
|
|
|
|
* It is aware of the current viewposition, the scale and viewport.
|
|
|
|
* It ensures, that maps can be changed, without the user noticing it.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
export default class MapView {
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @param {object} [focus = {x:0, y:0}] - Defines the startup focuspoint of the app.
|
|
|
|
* @param {number} [zoom = 0] - Defines the startup zoom of the app. Note that this is just a request.
|
|
|
|
* The MapView will prioritize a full scale app, than displaying the demanded zoom factor
|
|
|
|
*/
|
2019-11-04 18:20:32 +01:00
|
|
|
constructor({ focus = null, zoom = null, viewport = { min: { x: -85, y: -180 }, max: { x: 85, y: 180 } } } = {}) {
|
2019-11-04 10:59:08 +01:00
|
|
|
this.viewport = viewport
|
|
|
|
this._focus = focus
|
|
|
|
this._zoom = zoom
|
|
|
|
this.referenceHeight = 256
|
|
|
|
}
|
|
|
|
|
|
|
|
get focus() {
|
|
|
|
return this._focus
|
|
|
|
}
|
|
|
|
get zoom() {
|
|
|
|
return this._zoom
|
|
|
|
}
|
|
|
|
|
2019-11-13 12:42:06 +01:00
|
|
|
apply(map) {
|
2019-11-04 18:20:32 +01:00
|
|
|
map.moveTo(this._focus, this._zoom)
|
2019-11-04 10:59:08 +01:00
|
|
|
}
|
|
|
|
|
2019-11-04 18:20:32 +01:00
|
|
|
transformed(map) {
|
|
|
|
this.updateZoom(map)
|
|
|
|
this.updateFocusPoint(map)
|
2019-11-04 10:59:08 +01:00
|
|
|
}
|
|
|
|
|
2019-11-13 12:42:06 +01:00
|
|
|
updatePosition(map) {
|
2019-11-04 18:20:32 +01:00
|
|
|
this.updateFocusPoint(map)
|
|
|
|
this.updateZoom(map)
|
2019-11-04 10:59:08 +01:00
|
|
|
}
|
|
|
|
|
2019-11-04 18:20:32 +01:00
|
|
|
updateFocusPoint(map) {
|
|
|
|
const frame = map.getFrame()
|
|
|
|
this._focus = this.coordinatesFromWindowPoint(map, frame.localCenter)
|
2019-11-04 10:59:08 +01:00
|
|
|
}
|
|
|
|
|
2019-11-04 18:20:32 +01:00
|
|
|
updateZoom(map) {
|
2019-11-04 10:59:08 +01:00
|
|
|
/**
|
|
|
|
* TODO: This relies on the fact, that all maps have the same tileSize,
|
|
|
|
* if a set would have a smaller tileSize. Improve that.
|
|
|
|
*/
|
2019-11-04 18:20:32 +01:00
|
|
|
if (map instanceof DeepZoomMap) this._zoom = map.floatingLevelForScale(map.image.scatter.scale)
|
2019-11-04 10:59:08 +01:00
|
|
|
else {
|
2019-11-04 18:20:32 +01:00
|
|
|
this._zoom = map.zoom
|
2019-11-04 10:59:08 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-04 18:20:32 +01:00
|
|
|
mapPointToWindowPoint(map, point) {
|
2019-11-13 12:42:06 +01:00
|
|
|
let windowPoint = { x: 0, y: 0 }
|
2019-11-04 10:59:08 +01:00
|
|
|
|
2019-11-13 12:42:06 +01:00
|
|
|
if (map['image'] && map.image['parent']) {
|
|
|
|
let container = map.image.parent
|
2019-11-04 10:59:08 +01:00
|
|
|
|
2019-11-13 12:42:06 +01:00
|
|
|
windowPoint = new PIXI.Point(
|
|
|
|
map.scatter.position.x + map.scatter.scale * point.x,
|
|
|
|
map.scatter.position.y + map.scatter.scale * point.y
|
|
|
|
)
|
|
|
|
|
|
|
|
windowPoint = container.toGlobal(windowPoint)
|
|
|
|
} else {
|
|
|
|
console.error(this._noParentError)
|
|
|
|
}
|
|
|
|
|
|
|
|
return windowPoint
|
2019-11-04 10:59:08 +01:00
|
|
|
}
|
|
|
|
|
2019-11-04 18:20:32 +01:00
|
|
|
windowPointToMapPoint(map, point) {
|
2019-11-13 12:42:06 +01:00
|
|
|
let pointOnMap = { x: 0, y: 0 }
|
|
|
|
if (map['image'] && map.image['parent']) {
|
|
|
|
let offset = map.image.parent.toGlobal({ x: 0, y: 0 })
|
|
|
|
pointOnMap = new PIXI.Point(
|
|
|
|
(point.x - map.scatter.position.x - offset.x) / map.scatter.scale,
|
|
|
|
(point.y - map.scatter.position.y - offset.y) / map.scatter.scale
|
|
|
|
)
|
|
|
|
} else console.error(this._noParentError)
|
|
|
|
|
|
|
|
return pointOnMap
|
|
|
|
}
|
2019-11-04 10:59:08 +01:00
|
|
|
|
2019-11-13 12:42:06 +01:00
|
|
|
get _noParentError() {
|
|
|
|
return 'Cannot compute map point when map has no parent.'
|
2019-11-04 10:59:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the coordinates of a specific point in the viewport.
|
|
|
|
*
|
|
|
|
* @param {PIXI.Point | {x,y}} point - Pixel position in the viewport.
|
|
|
|
* @returns {{x,y}} Coordinates on the map of the provided position.
|
|
|
|
* @memberof MapView
|
|
|
|
*/
|
2019-11-04 18:20:32 +01:00
|
|
|
coordinatesFromWindowPoint(map, point) {
|
2019-11-04 10:59:08 +01:00
|
|
|
let position = {
|
2019-11-04 18:20:32 +01:00
|
|
|
x: point.x - map.scatter.position.x,
|
|
|
|
y: point.y - map.scatter.position.y
|
2019-11-04 10:59:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
let normalized = {
|
2019-11-04 18:20:32 +01:00
|
|
|
x: position.x / (map.width * map.scatter.scale),
|
|
|
|
y: position.y / (map.height * map.scatter.scale)
|
2019-11-04 10:59:08 +01:00
|
|
|
}
|
|
|
|
|
2019-11-04 18:20:32 +01:00
|
|
|
let coordinates = map.mapdata.toCoordinates(normalized)
|
2019-11-04 10:59:08 +01:00
|
|
|
|
|
|
|
return coordinates
|
|
|
|
}
|
|
|
|
}
|