summaryrefslogtreecommitdiff
path: root/opendc-web/opendc-web-ui/src/redux
diff options
context:
space:
mode:
authorFabian Mastenbroek <mail.fabianm@gmail.com>2021-07-16 17:37:01 +0200
committerFabian Mastenbroek <mail.fabianm@gmail.com>2021-07-16 17:37:01 +0200
commitf2aeecccc096728d3df955b71e711c8d9c429427 (patch)
tree14494ef902f054a38f93af29976be81f8d5dba75 /opendc-web/opendc-web-ui/src/redux
parente5caf6c6122684e441d1d73e2e0507fdd36c67e0 (diff)
refactor(ui): Isolate world coordinate space
This change updates the topology view in the OpenDC frontend to isolate the world coordinate space. This means that zooming and panning should not affect the coordinates in world space (but only in camera space). In turn, this allows us to remove the dependency on Redux for the camera controls.
Diffstat (limited to 'opendc-web/opendc-web-ui/src/redux')
-rw-r--r--opendc-web/opendc-web-ui/src/redux/actions/map.js83
-rw-r--r--opendc-web/opendc-web-ui/src/redux/index.js3
-rw-r--r--opendc-web/opendc-web-ui/src/redux/middleware/viewport-adjustment.js73
-rw-r--r--opendc-web/opendc-web-ui/src/redux/reducers/index.js2
-rw-r--r--opendc-web/opendc-web-ui/src/redux/reducers/map.js35
5 files changed, 1 insertions, 195 deletions
diff --git a/opendc-web/opendc-web-ui/src/redux/actions/map.js b/opendc-web/opendc-web-ui/src/redux/actions/map.js
deleted file mode 100644
index aa14cacd..00000000
--- a/opendc-web/opendc-web-ui/src/redux/actions/map.js
+++ /dev/null
@@ -1,83 +0,0 @@
-import {
- MAP_MAX_SCALE,
- MAP_MIN_SCALE,
- MAP_SCALE_PER_EVENT,
- MAP_SIZE_IN_PIXELS,
-} from '../../components/app/map/MapConstants'
-
-export const SET_MAP_POSITION = 'SET_MAP_POSITION'
-export const SET_MAP_DIMENSIONS = 'SET_MAP_DIMENSIONS'
-export const SET_MAP_SCALE = 'SET_MAP_SCALE'
-
-export function setMapPosition(x, y) {
- return {
- type: SET_MAP_POSITION,
- x,
- y,
- }
-}
-
-export function setMapDimensions(width, height) {
- return {
- type: SET_MAP_DIMENSIONS,
- width,
- height,
- }
-}
-
-export function setMapScale(scale) {
- return {
- type: SET_MAP_SCALE,
- scale,
- }
-}
-
-export function zoomInOnCenter(zoomIn) {
- return (dispatch, getState) => {
- const state = getState()
-
- dispatch(zoomInOnPosition(zoomIn, state.map.dimensions.width / 2, state.map.dimensions.height / 2))
- }
-}
-
-export function zoomInOnPosition(zoomIn, x, y) {
- return (dispatch, getState) => {
- const state = getState()
-
- const centerPoint = {
- x: x / state.map.scale - state.map.position.x / state.map.scale,
- y: y / state.map.scale - state.map.position.y / state.map.scale,
- }
- const newScale = zoomIn ? state.map.scale * MAP_SCALE_PER_EVENT : state.map.scale / MAP_SCALE_PER_EVENT
- const boundedScale = Math.min(Math.max(MAP_MIN_SCALE, newScale), MAP_MAX_SCALE)
-
- const newX = -(centerPoint.x - x / boundedScale) * boundedScale
- const newY = -(centerPoint.y - y / boundedScale) * boundedScale
-
- dispatch(setMapPositionWithBoundsCheck(newX, newY))
- dispatch(setMapScale(boundedScale))
- }
-}
-
-export function setMapPositionWithBoundsCheck(x, y) {
- return (dispatch, getState) => {
- const state = getState()
-
- const scaledMapSize = MAP_SIZE_IN_PIXELS * state.map.scale
-
- const updatedX =
- x > 0
- ? 0
- : x < -scaledMapSize + state.map.dimensions.width
- ? -scaledMapSize + state.map.dimensions.width
- : x
- const updatedY =
- y > 0
- ? 0
- : y < -scaledMapSize + state.map.dimensions.height
- ? -scaledMapSize + state.map.dimensions.height
- : y
-
- dispatch(setMapPosition(updatedX, updatedY))
- }
-}
diff --git a/opendc-web/opendc-web-ui/src/redux/index.js b/opendc-web/opendc-web-ui/src/redux/index.js
index 3c7ad55f..fa0c9d23 100644
--- a/opendc-web/opendc-web-ui/src/redux/index.js
+++ b/opendc-web/opendc-web-ui/src/redux/index.js
@@ -5,7 +5,6 @@ import createSagaMiddleware from 'redux-saga'
import thunk from 'redux-thunk'
import rootReducer from './reducers'
import rootSaga from './sagas'
-import { viewportAdjustmentMiddleware } from './middleware/viewport-adjustment'
import { createReduxEnhancer } from '@sentry/react'
let store
@@ -13,7 +12,7 @@ let store
function initStore(initialState, ctx) {
const sagaMiddleware = createSagaMiddleware({ context: ctx })
- const middlewares = [thunk, sagaMiddleware, viewportAdjustmentMiddleware]
+ const middlewares = [thunk, sagaMiddleware]
if (process.env.NODE_ENV !== 'production') {
middlewares.push(createLogger())
diff --git a/opendc-web/opendc-web-ui/src/redux/middleware/viewport-adjustment.js b/opendc-web/opendc-web-ui/src/redux/middleware/viewport-adjustment.js
deleted file mode 100644
index c2fc5004..00000000
--- a/opendc-web/opendc-web-ui/src/redux/middleware/viewport-adjustment.js
+++ /dev/null
@@ -1,73 +0,0 @@
-import { SET_MAP_DIMENSIONS, setMapPosition, setMapScale } from '../actions/map'
-import { SET_CURRENT_TOPOLOGY } from '../actions/topology/building'
-import {
- MAP_MAX_SCALE,
- MAP_MIN_SCALE,
- SIDEBAR_WIDTH,
- TILE_SIZE_IN_PIXELS,
- VIEWPORT_PADDING,
-} from '../../components/app/map/MapConstants'
-import { calculateRoomListBounds } from '../../util/tile-calculations'
-
-export const viewportAdjustmentMiddleware = (store) => (next) => (action) => {
- const state = store.getState()
-
- let topologyId = '-1'
- let mapDimensions = {}
- if (action.type === SET_CURRENT_TOPOLOGY && action.topologyId !== '-1') {
- topologyId = action.topologyId
- mapDimensions = state.map.dimensions
- } else if (action.type === SET_MAP_DIMENSIONS && state.currentTopologyId !== '-1') {
- topologyId = state.currentTopologyId
- mapDimensions = { width: action.width, height: action.height }
- }
-
- if (topologyId && topologyId !== '-1') {
- const roomIds = state.objects.topology[topologyId].rooms
- const rooms = roomIds.map((id) => Object.assign({}, state.objects.room[id]))
- rooms.forEach((room) => (room.tiles = room.tiles.map((tileId) => state.objects.tile[tileId])))
-
- let hasNoTiles = true
- for (let i in rooms) {
- if (rooms[i].tiles.length > 0) {
- hasNoTiles = false
- break
- }
- }
-
- if (!hasNoTiles) {
- const viewportParams = calculateParametersToZoomInOnRooms(rooms, mapDimensions.width, mapDimensions.height)
- store.dispatch(setMapPosition(viewportParams.newX, viewportParams.newY))
- store.dispatch(setMapScale(viewportParams.newScale))
- }
- }
-
- next(action)
-}
-
-function calculateParametersToZoomInOnRooms(rooms, mapWidth, mapHeight) {
- const bounds = calculateRoomListBounds(rooms)
- const newScale = calculateNewScale(bounds, mapWidth, mapHeight)
-
- // Coordinates of the center of the room, relative to the global origin of the map
- const roomCenterCoordinates = {
- x: bounds.center.x * TILE_SIZE_IN_PIXELS * newScale,
- y: bounds.center.y * TILE_SIZE_IN_PIXELS * newScale,
- }
-
- const newX = -roomCenterCoordinates.x + mapWidth / 2
- const newY = -roomCenterCoordinates.y + mapHeight / 2
-
- return { newScale, newX, newY }
-}
-
-function calculateNewScale(bounds, mapWidth, mapHeight) {
- const width = bounds.max.x - bounds.min.x
- const height = bounds.max.y - bounds.min.y
-
- const scaleX = (mapWidth - 2 * SIDEBAR_WIDTH) / (width * TILE_SIZE_IN_PIXELS + 2 * VIEWPORT_PADDING)
- const scaleY = mapHeight / (height * TILE_SIZE_IN_PIXELS + 2 * VIEWPORT_PADDING)
- const newScale = Math.min(scaleX, scaleY)
-
- return Math.min(Math.max(MAP_MIN_SCALE, newScale), MAP_MAX_SCALE)
-}
diff --git a/opendc-web/opendc-web-ui/src/redux/reducers/index.js b/opendc-web/opendc-web-ui/src/redux/reducers/index.js
index 1b17a206..2f1359d6 100644
--- a/opendc-web/opendc-web-ui/src/redux/reducers/index.js
+++ b/opendc-web/opendc-web-ui/src/redux/reducers/index.js
@@ -2,13 +2,11 @@ import { combineReducers } from 'redux'
import { construction } from './construction-mode'
import { currentTopologyId } from './current-ids'
import { interactionLevel } from './interaction-level'
-import { map } from './map'
import { objects } from './objects'
const rootReducer = combineReducers({
objects,
construction,
- map,
currentTopologyId,
interactionLevel,
})
diff --git a/opendc-web/opendc-web-ui/src/redux/reducers/map.js b/opendc-web/opendc-web-ui/src/redux/reducers/map.js
deleted file mode 100644
index de712c15..00000000
--- a/opendc-web/opendc-web-ui/src/redux/reducers/map.js
+++ /dev/null
@@ -1,35 +0,0 @@
-import { combineReducers } from 'redux'
-import { SET_MAP_DIMENSIONS, SET_MAP_POSITION, SET_MAP_SCALE } from '../actions/map'
-
-export function position(state = { x: 0, y: 0 }, action) {
- switch (action.type) {
- case SET_MAP_POSITION:
- return { x: action.x, y: action.y }
- default:
- return state
- }
-}
-
-export function dimensions(state = { width: 600, height: 400 }, action) {
- switch (action.type) {
- case SET_MAP_DIMENSIONS:
- return { width: action.width, height: action.height }
- default:
- return state
- }
-}
-
-export function scale(state = 1, action) {
- switch (action.type) {
- case SET_MAP_SCALE:
- return action.scale
- default:
- return state
- }
-}
-
-export const map = combineReducers({
- position,
- dimensions,
- scale,
-})