forked from MapComplete/MapComplete
71 lines
2.3 KiB
TypeScript
71 lines
2.3 KiB
TypeScript
import { UIEventSource } from "../Logic/UIEventSource"
|
|
import { Utils } from "../Utils"
|
|
|
|
/**
|
|
* Utilities to (re)set user zoom (this is when the user enlarges HTML-elements by pinching out a non-map element).
|
|
* If the user zooms in and goes back to the map, it should reset to 1.0
|
|
*/
|
|
export default class Zoomcontrol {
|
|
private static readonly singleton = new Zoomcontrol()
|
|
private static readonly initialValue =
|
|
"width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=5.0, user-scalable=1"
|
|
private static readonly noZoom =
|
|
"width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=1"
|
|
|
|
private readonly viewportElement: HTMLMetaElement
|
|
|
|
private readonly _allowZooming: UIEventSource<boolean>
|
|
private readonly _lockTokens: Set<any> = new Set<any>()
|
|
|
|
private constructor() {
|
|
if (Utils.runningFromConsole) {
|
|
return
|
|
}
|
|
const metaElems = document.getElementsByTagName("head")[0].getElementsByTagName("meta")
|
|
this.viewportElement = Array.from(metaElems).find(
|
|
(meta) => meta.getAttribute("name") === "viewport"
|
|
)
|
|
this._allowZooming = new UIEventSource<boolean>(true)
|
|
this._allowZooming.addCallback((allowed) => {
|
|
this.apply(allowed ? Zoomcontrol.initialValue : Zoomcontrol.noZoom)
|
|
})
|
|
}
|
|
|
|
public static createLock(): () => void {
|
|
return Zoomcontrol.singleton._createLock()
|
|
}
|
|
|
|
public static resetzoom() {
|
|
this.singleton._resetZoom()
|
|
}
|
|
|
|
private _resetZoom() {
|
|
this.apply(Zoomcontrol.noZoom)
|
|
requestAnimationFrame(() => {
|
|
// Does not work on firefox, see https://bugzilla.mozilla.org/show_bug.cgi?id=1873934
|
|
this.allowZoomIfUnlocked()
|
|
})
|
|
}
|
|
|
|
private apply(fullSpec: string) {
|
|
this.viewportElement?.setAttribute("content", fullSpec)
|
|
}
|
|
|
|
private allowZoomIfUnlocked() {
|
|
if (this._lockTokens.size > 0) {
|
|
return
|
|
}
|
|
this.apply(Zoomcontrol.initialValue)
|
|
}
|
|
|
|
private _createLock(): () => void {
|
|
const token = {}
|
|
const lockTokens = this._lockTokens
|
|
lockTokens.add(token)
|
|
this._resetZoom()
|
|
return () => {
|
|
lockTokens.delete(token)
|
|
this.allowZoomIfUnlocked()
|
|
}
|
|
}
|
|
}
|