2020-11-07 11:35:29 +01:00
|
|
|
export default class Camera {
|
2021-04-17 19:11:43 +02:00
|
|
|
constructor() {
|
2020-12-24 20:17:01 +01:00
|
|
|
this.x = 0
|
|
|
|
|
this.y = 0
|
|
|
|
|
|
|
|
|
|
this.zoom = 1
|
|
|
|
|
this.minZoom = .1
|
|
|
|
|
this.maxZoom = 6
|
|
|
|
|
this.zoomStep = .05
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
move(x, y) {
|
|
|
|
|
this.x += x / this.zoom
|
|
|
|
|
this.y += y / this.zoom
|
|
|
|
|
}
|
2020-11-07 17:49:42 +01:00
|
|
|
|
2021-04-15 10:36:44 +02:00
|
|
|
setZoom(newzoom, viewportCoordCenter) {
|
2020-12-24 20:17:01 +01:00
|
|
|
const zoom = Math.min(Math.max(newzoom, this.minZoom), this.maxZoom)
|
|
|
|
|
if (zoom == this.zoom) {
|
|
|
|
|
return false
|
2020-11-07 11:35:29 +01:00
|
|
|
}
|
|
|
|
|
|
2021-04-17 19:11:43 +02:00
|
|
|
const zoomToCoord = viewportCoordCenter
|
2021-04-15 10:01:27 +02:00
|
|
|
const zoomFactor = (1 / this.zoom) - (1 / zoom)
|
|
|
|
|
|
|
|
|
|
this.x -= Math.round(zoomToCoord.x * zoomFactor)
|
|
|
|
|
this.y -= Math.round(zoomToCoord.y * zoomFactor)
|
2020-11-12 19:19:02 +01:00
|
|
|
|
2020-12-24 20:17:01 +01:00
|
|
|
this.zoom = zoom
|
2021-04-15 10:01:27 +02:00
|
|
|
|
2020-12-24 20:17:01 +01:00
|
|
|
return true
|
|
|
|
|
}
|
2020-11-12 19:19:02 +01:00
|
|
|
|
2021-04-15 10:36:44 +02:00
|
|
|
zoomOut(viewportCoordCenter) {
|
|
|
|
|
return this.setZoom(
|
|
|
|
|
this.zoom - this.zoomStep * this.zoom,
|
|
|
|
|
viewportCoordCenter
|
|
|
|
|
)
|
2020-12-24 20:17:01 +01:00
|
|
|
}
|
|
|
|
|
|
2021-04-15 10:36:44 +02:00
|
|
|
zoomIn(viewportCoordCenter) {
|
|
|
|
|
return this.setZoom(
|
|
|
|
|
this.zoom + this.zoomStep * this.zoom,
|
|
|
|
|
viewportCoordCenter
|
|
|
|
|
)
|
2020-12-24 20:17:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Translate a coordinate in the viewport to a
|
|
|
|
|
* coordinate in the world, rounded
|
2021-04-15 10:36:44 +02:00
|
|
|
* @param {x, y} viewportCoord
|
2020-12-24 20:17:01 +01:00
|
|
|
*/
|
2021-04-15 10:36:44 +02:00
|
|
|
viewportToWorld(viewportCoord) {
|
|
|
|
|
const worldCoord = this.viewportToWorldRaw(viewportCoord)
|
2020-12-24 20:17:01 +01:00
|
|
|
return {
|
|
|
|
|
x: Math.round(worldCoord.x),
|
|
|
|
|
y: Math.round(worldCoord.y),
|
2020-11-07 11:35:29 +01:00
|
|
|
}
|
2020-12-24 20:17:01 +01:00
|
|
|
}
|
2020-11-07 11:35:29 +01:00
|
|
|
|
2020-12-24 20:17:01 +01:00
|
|
|
/**
|
|
|
|
|
* Translate a coordinate in the viewport to a
|
|
|
|
|
* coordinate in the world, not rounded
|
2021-04-15 10:36:44 +02:00
|
|
|
* @param {x, y} viewportCoord
|
2020-12-24 20:17:01 +01:00
|
|
|
*/
|
2021-04-15 10:36:44 +02:00
|
|
|
viewportToWorldRaw(viewportCoord) {
|
2020-12-24 20:17:01 +01:00
|
|
|
return {
|
2021-04-15 10:36:44 +02:00
|
|
|
x: (viewportCoord.x / this.zoom) - this.x,
|
|
|
|
|
y: (viewportCoord.y / this.zoom) - this.y,
|
2020-11-12 19:19:02 +01:00
|
|
|
}
|
2020-12-24 20:17:01 +01:00
|
|
|
}
|
2020-11-07 11:35:29 +01:00
|
|
|
|
2020-12-24 20:17:01 +01:00
|
|
|
/**
|
|
|
|
|
* Translate a coordinate in the world to a
|
|
|
|
|
* coordinate in the viewport, rounded
|
2021-04-15 10:36:44 +02:00
|
|
|
* @param {x, y} worldCoord
|
2020-12-24 20:17:01 +01:00
|
|
|
*/
|
2021-04-15 10:36:44 +02:00
|
|
|
worldToViewport(worldCoord) {
|
|
|
|
|
const viewportCoord = this.worldToViewportRaw(worldCoord)
|
2020-12-24 20:17:01 +01:00
|
|
|
return {
|
|
|
|
|
x: Math.round(viewportCoord.x),
|
|
|
|
|
y: Math.round(viewportCoord.y),
|
2020-11-07 11:35:29 +01:00
|
|
|
}
|
2020-12-24 20:17:01 +01:00
|
|
|
}
|
2020-11-07 11:35:29 +01:00
|
|
|
|
2020-12-24 20:17:01 +01:00
|
|
|
/**
|
|
|
|
|
* Translate a coordinate in the world to a
|
|
|
|
|
* coordinate in the viewport, not rounded
|
2021-04-15 10:36:44 +02:00
|
|
|
* @param {x, y} worldCoord
|
2020-12-24 20:17:01 +01:00
|
|
|
*/
|
2021-04-15 10:36:44 +02:00
|
|
|
worldToViewportRaw(worldCoord) {
|
2020-12-24 20:17:01 +01:00
|
|
|
return {
|
2021-04-15 10:36:44 +02:00
|
|
|
x: (worldCoord.x + this.x) * this.zoom,
|
|
|
|
|
y: (worldCoord.y + this.y) * this.zoom,
|
2020-11-07 11:35:29 +01:00
|
|
|
}
|
2020-12-24 20:17:01 +01:00
|
|
|
}
|
2020-11-07 17:49:42 +01:00
|
|
|
|
2020-12-24 20:17:01 +01:00
|
|
|
/**
|
|
|
|
|
* Translate a 2d dimension (width/height) in the world to
|
|
|
|
|
* one in the viewport, rounded
|
2021-04-15 10:36:44 +02:00
|
|
|
* @param {w, h} worldDim
|
2020-12-24 20:17:01 +01:00
|
|
|
*/
|
2021-04-15 10:36:44 +02:00
|
|
|
worldDimToViewport(worldDim) {
|
|
|
|
|
const viewportDim = this.worldDimToViewportRaw(worldDim)
|
2020-12-24 20:17:01 +01:00
|
|
|
return {
|
|
|
|
|
w: Math.round(viewportDim.w),
|
|
|
|
|
h: Math.round(viewportDim.h),
|
2020-11-07 17:49:42 +01:00
|
|
|
}
|
2020-12-24 20:17:01 +01:00
|
|
|
}
|
|
|
|
|
|
2020-11-10 18:48:16 +01:00
|
|
|
|
2020-12-24 20:17:01 +01:00
|
|
|
/**
|
|
|
|
|
* Translate a 2d dimension (width/height) in the world to
|
|
|
|
|
* one in the viewport, not rounded
|
2021-04-15 10:36:44 +02:00
|
|
|
* @param {w, h} worldDim
|
2020-12-24 20:17:01 +01:00
|
|
|
*/
|
2021-04-15 10:36:44 +02:00
|
|
|
worldDimToViewportRaw(worldDim) {
|
2020-12-24 20:17:01 +01:00
|
|
|
return {
|
2021-04-15 10:36:44 +02:00
|
|
|
w: worldDim.w * this.zoom,
|
|
|
|
|
h: worldDim.h * this.zoom,
|
2020-11-10 18:48:16 +01:00
|
|
|
}
|
2020-12-24 20:17:01 +01:00
|
|
|
}
|
2020-11-07 17:49:42 +01:00
|
|
|
}
|