summaryrefslogtreecommitdiff
path: root/src/components/app/map/elements
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/app/map/elements')
-rw-r--r--src/components/app/map/elements/Backdrop.js16
-rw-r--r--src/components/app/map/elements/GrayLayer.js17
-rw-r--r--src/components/app/map/elements/HoverTile.js27
-rw-r--r--src/components/app/map/elements/ImageComponent.js48
-rw-r--r--src/components/app/map/elements/RackFillBar.js67
-rw-r--r--src/components/app/map/elements/RoomTile.js20
-rw-r--r--src/components/app/map/elements/TileObject.js25
-rw-r--r--src/components/app/map/elements/TilePlusIcon.js44
-rw-r--r--src/components/app/map/elements/WallSegment.js39
9 files changed, 303 insertions, 0 deletions
diff --git a/src/components/app/map/elements/Backdrop.js b/src/components/app/map/elements/Backdrop.js
new file mode 100644
index 00000000..9c01df63
--- /dev/null
+++ b/src/components/app/map/elements/Backdrop.js
@@ -0,0 +1,16 @@
+import React from "react";
+import {Rect} from "react-konva";
+import {BACKDROP_COLOR} from "../../../../util/colors";
+import {MAP_SIZE_IN_PIXELS} from "../MapConstants";
+
+const Backdrop = () => (
+ <Rect
+ x={0}
+ y={0}
+ width={MAP_SIZE_IN_PIXELS}
+ height={MAP_SIZE_IN_PIXELS}
+ fill={BACKDROP_COLOR}
+ />
+);
+
+export default Backdrop;
diff --git a/src/components/app/map/elements/GrayLayer.js b/src/components/app/map/elements/GrayLayer.js
new file mode 100644
index 00000000..c5994d06
--- /dev/null
+++ b/src/components/app/map/elements/GrayLayer.js
@@ -0,0 +1,17 @@
+import React from "react";
+import {Rect} from "react-konva";
+import {GRAYED_OUT_AREA_COLOR} from "../../../../util/colors";
+import {MAP_SIZE_IN_PIXELS} from "../MapConstants";
+
+const GrayLayer = ({onClick}) => (
+ <Rect
+ x={0}
+ y={0}
+ width={MAP_SIZE_IN_PIXELS}
+ height={MAP_SIZE_IN_PIXELS}
+ fill={GRAYED_OUT_AREA_COLOR}
+ onClick={onClick}
+ />
+);
+
+export default GrayLayer;
diff --git a/src/components/app/map/elements/HoverTile.js b/src/components/app/map/elements/HoverTile.js
new file mode 100644
index 00000000..fc12cbdd
--- /dev/null
+++ b/src/components/app/map/elements/HoverTile.js
@@ -0,0 +1,27 @@
+import PropTypes from "prop-types";
+import React from "react";
+import {Rect} from "react-konva";
+import {ROOM_HOVER_INVALID_COLOR, ROOM_HOVER_VALID_COLOR} from "../../../../util/colors";
+import {TILE_SIZE_IN_PIXELS} from "../MapConstants";
+
+const HoverTile = ({pixelX, pixelY, isValid, scale, onClick}) => (
+ <Rect
+ x={pixelX}
+ y={pixelY}
+ scaleX={scale}
+ scaleY={scale}
+ width={TILE_SIZE_IN_PIXELS}
+ height={TILE_SIZE_IN_PIXELS}
+ fill={isValid ? ROOM_HOVER_VALID_COLOR : ROOM_HOVER_INVALID_COLOR}
+ onClick={onClick}
+ />
+);
+
+HoverTile.propTypes = {
+ pixelX: PropTypes.number.isRequired,
+ pixelY: PropTypes.number.isRequired,
+ isValid: PropTypes.bool.isRequired,
+ onClick: PropTypes.func.isRequired,
+};
+
+export default HoverTile;
diff --git a/src/components/app/map/elements/ImageComponent.js b/src/components/app/map/elements/ImageComponent.js
new file mode 100644
index 00000000..486296ea
--- /dev/null
+++ b/src/components/app/map/elements/ImageComponent.js
@@ -0,0 +1,48 @@
+import PropTypes from "prop-types";
+import React from "react";
+import {Image} from "react-konva";
+
+class ImageComponent extends React.Component {
+ static imageCaches = {};
+ static propTypes = {
+ src: PropTypes.string.isRequired,
+ x: PropTypes.number.isRequired,
+ y: PropTypes.number.isRequired,
+ width: PropTypes.number.isRequired,
+ height: PropTypes.number.isRequired,
+ opacity: PropTypes.number.isRequired,
+ };
+
+ state = {
+ image: null
+ };
+
+ componentDidMount() {
+ if (ImageComponent.imageCaches[this.props.src]) {
+ this.setState({image: ImageComponent.imageCaches[this.props.src]});
+ return;
+ }
+
+ const image = new window.Image();
+ image.src = this.props.src;
+ image.onload = () => {
+ this.setState({image});
+ ImageComponent.imageCaches[this.props.src] = image;
+ }
+ }
+
+ render() {
+ return (
+ <Image
+ image={this.state.image}
+ x={this.props.x}
+ y={this.props.y}
+ width={this.props.width}
+ height={this.props.height}
+ opacity={this.props.opacity}
+ />
+ )
+ }
+}
+
+export default ImageComponent;
diff --git a/src/components/app/map/elements/RackFillBar.js b/src/components/app/map/elements/RackFillBar.js
new file mode 100644
index 00000000..3a8a1137
--- /dev/null
+++ b/src/components/app/map/elements/RackFillBar.js
@@ -0,0 +1,67 @@
+import PropTypes from "prop-types";
+import React from "react";
+import {Group, Rect} from "react-konva";
+import {
+ RACK_ENERGY_BAR_BACKGROUND_COLOR,
+ RACK_ENERGY_BAR_FILL_COLOR,
+ RACK_SPACE_BAR_BACKGROUND_COLOR,
+ RACK_SPACE_BAR_FILL_COLOR
+} from "../../../../util/colors";
+import {
+ OBJECT_BORDER_WIDTH_IN_PIXELS,
+ OBJECT_MARGIN_IN_PIXELS,
+ RACK_FILL_ICON_OPACITY,
+ RACK_FILL_ICON_WIDTH,
+ TILE_SIZE_IN_PIXELS
+} from "../MapConstants";
+import ImageComponent from "./ImageComponent";
+
+const RackFillBar = ({positionX, positionY, type, fillFraction}) => {
+ const halfOfObjectBorderWidth = OBJECT_BORDER_WIDTH_IN_PIXELS / 2;
+ const x = positionX * TILE_SIZE_IN_PIXELS + OBJECT_MARGIN_IN_PIXELS
+ + (type === "space" ? halfOfObjectBorderWidth :
+ 0.5 * (TILE_SIZE_IN_PIXELS - 2 * OBJECT_MARGIN_IN_PIXELS));
+ const startY = positionY * TILE_SIZE_IN_PIXELS + OBJECT_MARGIN_IN_PIXELS + halfOfObjectBorderWidth;
+ const width = 0.5 * (TILE_SIZE_IN_PIXELS - OBJECT_MARGIN_IN_PIXELS * 2) - halfOfObjectBorderWidth;
+ const fullHeight = TILE_SIZE_IN_PIXELS - OBJECT_MARGIN_IN_PIXELS * 2 - OBJECT_BORDER_WIDTH_IN_PIXELS;
+
+ const fractionHeight = fillFraction * fullHeight;
+ const fractionY = (positionY + 1) * TILE_SIZE_IN_PIXELS - OBJECT_MARGIN_IN_PIXELS - halfOfObjectBorderWidth
+ - fractionHeight;
+
+ return (
+ <Group>
+ <Rect
+ x={x}
+ y={startY}
+ width={width}
+ height={fullHeight}
+ fill={type === "space" ? RACK_SPACE_BAR_BACKGROUND_COLOR : RACK_ENERGY_BAR_BACKGROUND_COLOR}
+ />
+ <Rect
+ x={x}
+ y={fractionY}
+ width={width}
+ height={fractionHeight}
+ fill={type === "space" ? RACK_SPACE_BAR_FILL_COLOR : RACK_ENERGY_BAR_FILL_COLOR}
+ />
+ <ImageComponent
+ src={"/img/topology/rack-" + type + "-icon.png"}
+ x={x + width * 0.5 - RACK_FILL_ICON_WIDTH * 0.5}
+ y={startY + fullHeight * 0.5 - RACK_FILL_ICON_WIDTH * 0.5}
+ width={RACK_FILL_ICON_WIDTH}
+ height={RACK_FILL_ICON_WIDTH}
+ opacity={RACK_FILL_ICON_OPACITY}
+ />
+ </Group>
+ );
+};
+
+RackFillBar.propTypes = {
+ positionX: PropTypes.number.isRequired,
+ positionY: PropTypes.number.isRequired,
+ type: PropTypes.string.isRequired,
+ fillFraction: PropTypes.number.isRequired,
+};
+
+export default RackFillBar;
diff --git a/src/components/app/map/elements/RoomTile.js b/src/components/app/map/elements/RoomTile.js
new file mode 100644
index 00000000..11948a7a
--- /dev/null
+++ b/src/components/app/map/elements/RoomTile.js
@@ -0,0 +1,20 @@
+import React from "react";
+import {Rect} from "react-konva";
+import Shapes from "../../../../shapes/index";
+import {TILE_SIZE_IN_PIXELS} from "../MapConstants";
+
+const RoomTile = ({tile, color}) => (
+ <Rect
+ x={tile.positionX * TILE_SIZE_IN_PIXELS}
+ y={tile.positionY * TILE_SIZE_IN_PIXELS}
+ width={TILE_SIZE_IN_PIXELS}
+ height={TILE_SIZE_IN_PIXELS}
+ fill={color}
+ />
+);
+
+RoomTile.propTypes = {
+ tile: Shapes.Tile,
+};
+
+export default RoomTile;
diff --git a/src/components/app/map/elements/TileObject.js b/src/components/app/map/elements/TileObject.js
new file mode 100644
index 00000000..73bfddba
--- /dev/null
+++ b/src/components/app/map/elements/TileObject.js
@@ -0,0 +1,25 @@
+import PropTypes from "prop-types";
+import React from "react";
+import {Rect} from "react-konva";
+import {OBJECT_BORDER_COLOR} from "../../../../util/colors";
+import {OBJECT_BORDER_WIDTH_IN_PIXELS, OBJECT_MARGIN_IN_PIXELS, TILE_SIZE_IN_PIXELS} from "../MapConstants";
+
+const TileObject = ({positionX, positionY, color}) => (
+ <Rect
+ x={positionX * TILE_SIZE_IN_PIXELS + OBJECT_MARGIN_IN_PIXELS}
+ y={positionY * TILE_SIZE_IN_PIXELS + OBJECT_MARGIN_IN_PIXELS}
+ width={TILE_SIZE_IN_PIXELS - OBJECT_MARGIN_IN_PIXELS * 2}
+ height={TILE_SIZE_IN_PIXELS - OBJECT_MARGIN_IN_PIXELS * 2}
+ fill={color}
+ stroke={OBJECT_BORDER_COLOR}
+ strokeWidth={OBJECT_BORDER_WIDTH_IN_PIXELS}
+ />
+);
+
+TileObject.propTypes = {
+ positionX: PropTypes.number.isRequired,
+ positionY: PropTypes.number.isRequired,
+ color: PropTypes.string.isRequired,
+};
+
+export default TileObject;
diff --git a/src/components/app/map/elements/TilePlusIcon.js b/src/components/app/map/elements/TilePlusIcon.js
new file mode 100644
index 00000000..b96bf0f5
--- /dev/null
+++ b/src/components/app/map/elements/TilePlusIcon.js
@@ -0,0 +1,44 @@
+import PropTypes from "prop-types";
+import React from "react";
+import {Group, Line} from "react-konva";
+import {TILE_PLUS_COLOR} from "../../../../util/colors";
+import {TILE_PLUS_MARGIN_IN_PIXELS, TILE_PLUS_WIDTH_IN_PIXELS, TILE_SIZE_IN_PIXELS} from "../MapConstants";
+
+const TilePlusIcon = ({pixelX, pixelY, mapScale}) => {
+ const linePoints = [
+ [
+ pixelX + 0.5 * TILE_SIZE_IN_PIXELS * mapScale,
+ pixelY + TILE_PLUS_MARGIN_IN_PIXELS * mapScale,
+ pixelX + 0.5 * TILE_SIZE_IN_PIXELS * mapScale,
+ pixelY + TILE_SIZE_IN_PIXELS * mapScale - TILE_PLUS_MARGIN_IN_PIXELS * mapScale,
+ ],
+ [
+ pixelX + TILE_PLUS_MARGIN_IN_PIXELS * mapScale,
+ pixelY + 0.5 * TILE_SIZE_IN_PIXELS * mapScale,
+ pixelX + TILE_SIZE_IN_PIXELS * mapScale - TILE_PLUS_MARGIN_IN_PIXELS * mapScale,
+ pixelY + 0.5 * TILE_SIZE_IN_PIXELS * mapScale,
+ ],
+ ];
+ return (
+ <Group>
+ {linePoints.map((points, index) => (
+ <Line
+ key={index}
+ points={points}
+ lineCap="round"
+ stroke={TILE_PLUS_COLOR}
+ strokeWidth={TILE_PLUS_WIDTH_IN_PIXELS * mapScale}
+ listening={false}
+ />
+ ))}
+ </Group>
+ )
+};
+
+TilePlusIcon.propTypes = {
+ pixelX: PropTypes.number,
+ pixelY: PropTypes.number,
+ mapScale: PropTypes.number,
+};
+
+export default TilePlusIcon;
diff --git a/src/components/app/map/elements/WallSegment.js b/src/components/app/map/elements/WallSegment.js
new file mode 100644
index 00000000..14efd3fc
--- /dev/null
+++ b/src/components/app/map/elements/WallSegment.js
@@ -0,0 +1,39 @@
+import React from "react";
+import {Line} from "react-konva";
+import Shapes from "../../../../shapes/index";
+import {WALL_COLOR} from "../../../../util/colors";
+import {TILE_SIZE_IN_PIXELS, WALL_WIDTH_IN_PIXELS} from "../MapConstants";
+
+const WallSegment = ({wallSegment}) => {
+ let points;
+ if (wallSegment.isHorizontal) {
+ points = [
+ wallSegment.startPosX * TILE_SIZE_IN_PIXELS,
+ wallSegment.startPosY * TILE_SIZE_IN_PIXELS,
+ (wallSegment.startPosX + wallSegment.length) * TILE_SIZE_IN_PIXELS,
+ wallSegment.startPosY * TILE_SIZE_IN_PIXELS
+ ];
+ } else {
+ points = [
+ wallSegment.startPosX * TILE_SIZE_IN_PIXELS,
+ wallSegment.startPosY * TILE_SIZE_IN_PIXELS,
+ wallSegment.startPosX * TILE_SIZE_IN_PIXELS,
+ (wallSegment.startPosY + wallSegment.length) * TILE_SIZE_IN_PIXELS,
+ ];
+ }
+
+ return (
+ <Line
+ points={points}
+ lineCap="round"
+ stroke={WALL_COLOR}
+ strokeWidth={WALL_WIDTH_IN_PIXELS}
+ />
+ )
+};
+
+WallSegment.propTypes = {
+ wallSegment: Shapes.WallSegment,
+};
+
+export default WallSegment;