switch to typescript

This commit is contained in:
Zutatensuppe 2021-05-17 00:27:47 +02:00
parent 031ca31c7e
commit 23559b1a3b
63 changed files with 7943 additions and 1397 deletions

136
src/frontend/Camera.ts Normal file
View file

@ -0,0 +1,136 @@
const MIN_ZOOM = .1
const MAX_ZOOM = 6
const ZOOM_STEP = .05
type ZOOM_DIR = 'in'|'out'
interface Point {
x: number
y: number
}
interface Dim {
w: number
h: number
}
export default function Camera () {
let x = 0
let y = 0
let curZoom = 1
const move = (byX: number, byY: number) => {
x += byX / curZoom
y += byY / curZoom
}
const calculateNewZoom = (inout: ZOOM_DIR): number => {
const factor = inout === 'in' ? 1 : -1
const newzoom = curZoom + ZOOM_STEP * curZoom * factor
const capped = Math.min(Math.max(newzoom, MIN_ZOOM), MAX_ZOOM)
return capped
}
const canZoom = (inout: ZOOM_DIR): boolean => {
return curZoom != calculateNewZoom(inout)
}
const setZoom = (newzoom: number, viewportCoordCenter: Point): boolean => {
if (curZoom == newzoom) {
return false
}
const zoomFactor = 1 - (curZoom / newzoom)
move(
-viewportCoordCenter.x * zoomFactor,
-viewportCoordCenter.y * zoomFactor,
)
curZoom = newzoom
return true
}
/**
* Zooms towards/away from the provided coordinate, if possible.
* If at max or min zoom respectively, no zooming is performed.
*/
const zoom = (inout: ZOOM_DIR, viewportCoordCenter: Point): boolean => {
return setZoom(calculateNewZoom(inout), viewportCoordCenter)
}
/**
* Translate a coordinate in the viewport to a
* coordinate in the world, rounded
* @param {x, y} viewportCoord
*/
const viewportToWorld = (viewportCoord: Point): Point => {
const { x, y } = viewportToWorldRaw(viewportCoord)
return { x: Math.round(x), y: Math.round(y) }
}
/**
* Translate a coordinate in the viewport to a
* coordinate in the world, not rounded
* @param {x, y} viewportCoord
*/
const viewportToWorldRaw = (viewportCoord: Point): Point => {
return {
x: (viewportCoord.x / curZoom) - x,
y: (viewportCoord.y / curZoom) - y,
}
}
/**
* Translate a coordinate in the world to a
* coordinate in the viewport, rounded
* @param {x, y} worldCoord
*/
const worldToViewport = (worldCoord: Point): Point => {
const { x, y } = worldToViewportRaw(worldCoord)
return { x: Math.round(x), y: Math.round(y) }
}
/**
* Translate a coordinate in the world to a
* coordinate in the viewport, not rounded
* @param {x, y} worldCoord
*/
const worldToViewportRaw = (worldCoord: Point): Point => {
return {
x: (worldCoord.x + x) * curZoom,
y: (worldCoord.y + y) * curZoom,
}
}
/**
* Translate a 2d dimension (width/height) in the world to
* one in the viewport, rounded
* @param {w, h} worldDim
*/
const worldDimToViewport = (worldDim: Dim): Dim => {
const { w, h } = worldDimToViewportRaw(worldDim)
return { w: Math.round(w), h: Math.round(h) }
}
/**
* Translate a 2d dimension (width/height) in the world to
* one in the viewport, not rounded
* @param {w, h} worldDim
*/
const worldDimToViewportRaw = (worldDim: Dim): Dim => {
return {
w: worldDim.w * curZoom,
h: worldDim.h * curZoom,
}
}
return {
move,
canZoom,
zoom,
worldToViewport,
worldToViewportRaw,
worldDimToViewport, // not used outside
worldDimToViewportRaw,
viewportToWorld,
viewportToWorldRaw, // not used outside
}
}