iwmlib/lib/pixi/maps/mapview.js

124 lines
3.4 KiB
JavaScript

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
*/
constructor({
map = null,
focus = null,
zoom = null,
viewport = { min: { x: -85, y: -180 }, max: { x: 85, y: 180 } }
} = {}) {
this.viewport = viewport
this._focus = focus
this._zoom = zoom
this._map = map
this.referenceHeight = 256
}
get focus() {
return this._focus
}
get zoom() {
return this._zoom
}
get map() {
return this._map
}
/**
* Sets the map to the given focuspoint and zoom factor.
*/
setMap(map) {
this._map = map
this.update()
return true
}
update() {
this.map.moveTo(this._focus, this._zoom)
}
transformed(e) {
this.updateZoom()
this.updateFocusPoint()
}
applyCameraPosition() {
this.updateFocusPoint()
this.updateZoom()
}
updateFocusPoint() {
const frame = this.map.getFrame()
this._focus = this.coordinatesFromWindowPoint(frame.localCenter)
}
updateZoom() {
/**
* TODO: This relies on the fact, that all maps have the same tileSize,
* if a set would have a smaller tileSize. Improve that.
*/
if (this.map instanceof DeepZoomMap) this._zoom = this.map.floatingLevelForScale(this.map.image.scatter.scale)
else {
this._zoom = this.map.zoom
console.warn('Zoom is not yet correctly implemented in this Map type: ' + this.map)
}
}
mapPointToWindowPoint(point) {
let container = this.map.image.parent
let _point = new PIXI.Point(
this.map.scatter.position.x + this.map.scatter.scale * point.x,
this.map.scatter.position.y + this.map.scatter.scale * point.y
)
return container.toGlobal(_point)
}
windowPointToMapPoint(point) {
let offset = this.map.image.parent.toGlobal({ x: 0, y: 0 })
let _point = new PIXI.Point(
(point.x - this.map.scatter.position.x - offset.x) / this.map.scatter.scale,
(point.y - this.map.scatter.position.y - offset.y) / this.map.scatter.scale
)
return _point
}
/**
* 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
*/
coordinatesFromWindowPoint(point) {
let position = {
x: point.x - this.map.scatter.position.x,
y: point.y - this.map.scatter.position.y
}
let normalized = {
x: position.x / (this.map.width * this.map.scatter.scale),
y: position.y / (this.map.height * this.map.scatter.scale)
}
let coordinates = this.map.mapdata.toCoordinates(normalized)
return coordinates
}
}