From cbf8eb9cbf2f4082cb1a83955d435ebcb73be3ab Mon Sep 17 00:00:00 2001 From: Georgios Andreadis Date: Mon, 11 Sep 2017 14:49:17 +0200 Subject: Center datacenter on site load --- src/actions/topology/building.js | 2 -- src/components/map/MapConstants.js | 3 ++ src/index.js | 2 +- src/store/configure-store.js | 31 +++++++++++++++++ src/store/configureStore.js | 29 ---------------- src/store/middlewares/viewport-adjustment.js | 51 ++++++++++++++++++++++++++++ src/util/tile-calculations.js | 10 +----- 7 files changed, 87 insertions(+), 41 deletions(-) create mode 100644 src/store/configure-store.js delete mode 100644 src/store/configureStore.js create mode 100644 src/store/middlewares/viewport-adjustment.js diff --git a/src/actions/topology/building.js b/src/actions/topology/building.js index 9f2d4590..4138d2b5 100644 --- a/src/actions/topology/building.js +++ b/src/actions/topology/building.js @@ -1,5 +1,3 @@ -export const FETCH_TOPOLOGY_OF_DATACENTER = "FETCH_TOPOLOGY_OF_DATACENTER"; -export const FETCH_TOPOLOGY_OF_DATACENTER_SUCCEEDED = "FETCH_TOPOLOGY_OF_DATACENTER_SUCCEEDED"; export const FETCH_LATEST_DATACENTER = "FETCH_LATEST_DATACENTER"; export const FETCH_LATEST_DATACENTER_SUCCEEDED = "FETCH_LATEST_DATACENTER_SUCCEEDED"; export const RESET_CURRENT_DATACENTER = "RESET_CURRENT_DATACENTER"; diff --git a/src/components/map/MapConstants.js b/src/components/map/MapConstants.js index f24e450f..524dd1ae 100644 --- a/src/components/map/MapConstants.js +++ b/src/components/map/MapConstants.js @@ -11,6 +11,9 @@ export const WALL_WIDTH_IN_PIXELS = TILE_SIZE_IN_PIXELS / 8; export const OBJECT_BORDER_WIDTH_IN_PIXELS = TILE_SIZE_IN_PIXELS / 12; export const TILE_PLUS_WIDTH_IN_PIXELS = TILE_SIZE_IN_PIXELS / 10; +export const SIDEBAR_WIDTH = 350; +export const VIEWPORT_PADDING = 50; + export const RACK_FILL_ICON_WIDTH = OBJECT_SIZE_IN_PIXELS / 3; export const RACK_FILL_ICON_OPACITY = 0.8; diff --git a/src/index.js b/src/index.js index 8fa45ebf..84d5329c 100644 --- a/src/index.js +++ b/src/index.js @@ -5,7 +5,7 @@ import {setupSocketConnection} from "./api/socket"; import "./index.css"; import registerServiceWorker from "./registerServiceWorker"; import Routes from "./routes"; -import configureStore from "./store/configureStore"; +import configureStore from "./store/configure-store"; setupSocketConnection(() => { const store = configureStore(); diff --git a/src/store/configure-store.js b/src/store/configure-store.js new file mode 100644 index 00000000..a7f3ec31 --- /dev/null +++ b/src/store/configure-store.js @@ -0,0 +1,31 @@ +import {applyMiddleware, compose, createStore} from "redux"; +import persistState from "redux-localstorage"; +import {createLogger} from "redux-logger"; +import createSagaMiddleware from 'redux-saga'; +import thunk from "redux-thunk"; +import {authRedirectMiddleware} from "../auth/index"; +import rootReducer from "../reducers/index"; +import rootSaga from "../sagas/index"; +import {viewportAdjustmentMiddleware} from "./middlewares/viewport-adjustment"; + +const sagaMiddleware = createSagaMiddleware(); +const logger = createLogger(); + +export default function configureStore() { + const store = createStore( + rootReducer, + compose( + persistState("auth"), + applyMiddleware( + logger, + thunk, + sagaMiddleware, + authRedirectMiddleware, + viewportAdjustmentMiddleware, + ) + ) + ); + sagaMiddleware.run(rootSaga); + + return store; +} diff --git a/src/store/configureStore.js b/src/store/configureStore.js deleted file mode 100644 index 5bbaf811..00000000 --- a/src/store/configureStore.js +++ /dev/null @@ -1,29 +0,0 @@ -import {applyMiddleware, compose, createStore} from "redux"; -import persistState from "redux-localstorage"; -import {createLogger} from "redux-logger"; -import createSagaMiddleware from 'redux-saga'; -import thunk from "redux-thunk"; -import {authRedirectMiddleware} from "../auth/index"; -import rootReducer from "../reducers/index"; -import rootSaga from "../sagas/index"; - -const sagaMiddleware = createSagaMiddleware(); -const logger = createLogger(); - -export default function configureStore() { - const store = createStore( - rootReducer, - compose( - persistState("auth"), - applyMiddleware( - logger, - thunk, - sagaMiddleware, - authRedirectMiddleware, - ) - ) - ); - sagaMiddleware.run(rootSaga); - - return store; -} diff --git a/src/store/middlewares/viewport-adjustment.js b/src/store/middlewares/viewport-adjustment.js new file mode 100644 index 00000000..75ad6a2f --- /dev/null +++ b/src/store/middlewares/viewport-adjustment.js @@ -0,0 +1,51 @@ +import {SET_MAP_DIMENSIONS, setMapPosition, setMapScale} from "../../actions/map"; +import { + MAP_MAX_SCALE, + MAP_MIN_SCALE, + SIDEBAR_WIDTH, + TILE_SIZE_IN_PIXELS, + VIEWPORT_PADDING +} from "../../components/map/MapConstants"; +import {calculateRoomListBounds} from "../../util/tile-calculations"; + +export const viewportAdjustmentMiddleware = store => next => action => { + const state = store.getState(); + if (action.type === SET_MAP_DIMENSIONS && state.currentDatacenterId !== -1) { + const roomIds = state.objects.datacenter[state.currentDatacenterId].roomIds; + const rooms = roomIds.map(id => Object.assign({}, state.objects.room[id])); + rooms.forEach(room => room.tiles = room.tileIds.map(tileId => state.objects.tile[tileId])); + + const viewportParams = calculateParametersToZoomInOnRooms(rooms, action.width, action.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/src/util/tile-calculations.js b/src/util/tile-calculations.js index 260f28e6..31b5d8aa 100644 --- a/src/util/tile-calculations.js +++ b/src/util/tile-calculations.js @@ -239,13 +239,5 @@ export function calculateRoomListBounds(rooms) { y: min.y + (max.y - min.y) / 2.0 }; - return { - min, - center, - max - }; -} - -export function calculateRoomBounds(room) { - return calculateRoomListBounds([room]); + return {min, center, max}; } -- cgit v1.2.3