Changeset 0c6b92a for imaps-frontend/src/scripts
- Timestamp:
- 12/12/24 17:06:06 (5 weeks ago)
- Branches:
- main
- Parents:
- d565449
- Location:
- imaps-frontend/src/scripts
- Files:
-
- 12 added
- 1 deleted
- 14 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
imaps-frontend/src/scripts/base/MapShape.js
rd565449 r0c6b92a 6 6 throw new Error("Cannot instantiate abstract class BaseShape directly."); 7 7 } 8 9 console.log(config.x,"FFF"); 8 10 super(config); 9 11 this.layer = layer; … … 12 14 this.snappable = snap; 13 15 this._info = {}; 14 this. modalEventName = "";16 this.eventName = ""; 15 17 this.infoText = null; 18 this.floorNum; 16 19 17 20 this.shadowForStrokeEnabled(false); 18 21 this.on("mouseover", () => (document.body.style.cursor = "pointer")); 19 22 this.on("mouseout", () => (document.body.style.cursor = "default")); 20 // this.on("dblclick", (e) => { 21 // this.moveToTop(); 22 // this.getLayer() 23 // .find("Transformer") 24 // .forEach((t) => t.moveToTop()); 25 // }); 23 this.on("click", (e) => { 24 if(e.evt.altKey){ 25 this.moveToTop(); 26 this.getLayer() 27 .find("Transformer") 28 .forEach((t) => t.moveToTop()); 29 } 30 31 }); 26 32 27 33 if (snap) { 28 34 this.on("dragend", this.snapToGrid.bind(this)); 29 this.on('dblclick', this.snapToGrid.bind(this)) 35 this.on('dblclick', this.snapToGrid.bind(this)); 30 36 } 31 37 … … 36 42 }); 37 43 38 this.on('dragend', () => { 44 45 this.on('dragmove', () => { 39 46 if (this.infoText) { 40 47 this.updateTextPosition(); … … 76 83 } 77 84 85 86 destroy() { 87 super.destroy(); 88 if (this.infoText !== null) { 89 this.infoText.remove() 90 console.log("cleared text") 91 } 92 } 93 94 setInfo(infoObj){ 95 this.info = infoObj; 96 } 97 98 load(){ 99 console.log("Abstract function") 100 } 101 78 102 _sceneFunc(context) { 79 103 let width = this.width(); … … 93 117 } 94 118 119 updateText(shapeName){ 120 this.infoText.text = shapeName; 121 console.log("Updated text to : " + shapeName) 122 } 123 95 124 snapToGrid() { 96 125 this.position({ … … 98 127 y: Math.round(this.y() / this.blockSize) * this.blockSize, 99 128 }); 129 100 130 } 101 131 -
imaps-frontend/src/scripts/main/MapBuilder.js
rd565449 r0c6b92a 2 2 import Konva from "konva"; 3 3 import HttpService from "../net/HttpService.js"; 4 import { zoomStage } from "../util/zoomStage.js"; 4 import {zoomStage} from "../util/zoomStage.js"; 5 import {addEventHandling} from "../util/addEventHandling.js"; 6 import MapNode from "../base/MapNode.js"; 7 import {json} from "react-router-dom"; 8 import log from "eslint-plugin-react/lib/util/log.js"; 9 import ShapeRegistry from "../util/ShapeRegistry.js"; 10 import shapeRegistry from "../util/ShapeRegistry.js"; 11 import triggerMapSave from "../util/triggerMapSave.js"; 5 12 6 13 export class MapBuilder { 7 constructor(containerId) { 8 this.container = document.getElementById(containerId); 9 this.stage = new Konva.Stage({ 10 container: containerId, 11 width: this.container.clientWidth, 12 height: this.container.clientHeight, 13 }); 14 15 // TODO AKO DRAGNIT NEKOJ OD POCETOK NA STAGE POZICIIVE KE SA ZEZNAT 16 // TODO jwt vo cookie 17 // TODO placed shape i mouseMoveHandler da ne callback ( da ne vrakjat funkcija) 18 19 this.gridLayer = new Konva.Layer(); 20 this.mainLayer = new Konva.Layer(); 21 this.dragLayer = new Konva.Layer(); 22 this.infoPinLayer = new Konva.Layer(); 23 this.textLayer = new Konva.Layer(); 24 this.gridLayer.listening(false); 25 26 this.originalWidth = this.container.clientWidth; 27 this.originalHeight = this.container.clientHeight; 28 29 this.shapes = []; 30 this.blockSize = 10; 31 this.efficientDrawingMode = false; 32 this.roomTypes = []; 33 34 this.gridLine = new Konva.Line({ 35 points: [], 36 stroke: "grey", 37 strokeWidth: 1, 38 opacity: 0.3, 39 }); 40 41 this.gridLine.cache(); 42 43 this.mainTransformer = new Konva.Transformer({ 44 centeredScaling: false, 45 rotationSnaps: [0, 90, 180, 270], 46 anchorSize: 5, 47 padding: 2, 48 anchorFill: "#ef7539", 49 borderStroke: "black", 50 anchorStroke: "black", 51 cornerRadius: 20, 52 anchorCornerRadius: 10, 53 anchorDragBoundFunc: this.transformerSnapFunc(), 54 }); 55 56 this.selectionRectangle = new Konva.Rect({ 57 fill: "rgba(200,0,255,0.5)", 58 visible: false, 59 listening: false, 60 zIndex: 100, 61 }); 62 63 this.x1 = 0; 64 this.y1 = 0; 65 this.x2 = 0; 66 this.y2 = 0; 67 68 this.selecting = false; 69 70 this.initialize(); 71 } 72 73 initialize() { 74 this.drawGrid(); 75 this.mainLayer.add(this.mainTransformer); 76 this.mainLayer.add(this.selectionRectangle); 77 this.stage.add(this.gridLayer); 78 this.stage.add(this.dragLayer); 79 this.stage.add(this.mainLayer); 80 this.stage.add(this.infoPinLayer); 81 this.stage.add(this.textLayer); 82 this.setupEventListeners(); 83 } 84 85 setupEventListeners() { 86 document.getElementById("shapeOptions").addEventListener("click", this.selectShape.bind(this)); 87 document.getElementById("render-button").addEventListener("click", this.render.bind(this)); 88 window.addEventListener("keydown", this.handleExitSelection.bind(this)); 89 window.addEventListener("keydown", this.handleDelete.bind(this)); 90 window.addEventListener("keydown", this.rotateShapesBy90Deg.bind(this)); 91 window.addEventListener("keydown", this.toggleEfficientDrawingMode.bind(this)); 92 window.addEventListener("resize", this.handleResize.bind(this)); 93 this.stage.on("mousedown touchstart", this.handleMouseDown.bind(this)); 94 this.stage.on("mousemove touchmove", this.handleMouseMove.bind(this)); 95 this.stage.on("mouseup touchend", this.handleMouseUp.bind(this)); 96 this.stage.on("click tap", this.handleStageClick.bind(this)); 97 this.stage.on("contextmenu", this.placeInfoPin.bind(this)); 98 this.stage.on("dragmove", this.dragStage.bind(this)); 99 this.stage.on("wheel", this.zoom.bind(this)); 100 } 101 102 detachKeyPressEventListeners() { 103 window.removeEventListener("keydown", this.handleExitSelection.bind(this)); 104 window.removeEventListener("keydown", this.handleDelete.bind(this)); 105 window.removeEventListener("keydown", this.rotateShapesBy90Deg.bind(this)); 106 window.removeEventListener("keydown", this.toggleEfficientDrawingMode.bind(this)); 107 } 108 attachKeyPressEventListeners() { 109 window.addEventListener("keydown", this.handleExitSelection.bind(this)); 110 window.addEventListener("keydown", this.handleDelete.bind(this)); 111 window.addEventListener("keydown", this.rotateShapesBy90Deg.bind(this)); 112 window.addEventListener("keydown", this.toggleEfficientDrawingMode.bind(this)); 113 } 114 115 dragStage(e) { 116 if (!e.evt.shiftKey) return; 117 this.drawGrid(); 118 } 119 120 transformerSnapFunc() { 121 return (oldPos, newPos) => { 122 const snapDistance = 8; 123 124 if (this.mainTransformer.getActiveAnchor() === "rotater") { 125 return newPos; 126 } 127 128 const distance = Math.sqrt(Math.pow(newPos.x - oldPos.x, 2) + Math.pow(newPos.y - oldPos.y, 2)); 129 130 if (distance > snapDistance) { 131 return newPos; 132 } 133 134 const nextX = Math.round(newPos.x / this.blockSize) * this.blockSize; 135 const diffX = Math.abs(newPos.x - nextX); 136 137 const nextY = Math.round(newPos.y / this.blockSize) * this.blockSize; 138 const diffY = Math.abs(newPos.y - nextY); 139 140 const snapToX = diffX < snapDistance; 141 const snapToY = diffY < snapDistance; 142 143 if (snapToX && !snapToY) { 14 constructor(containerId,floorNum,mapName) { 15 this.container = document.getElementById(containerId); 16 this.stage = new Konva.Stage({ 17 container: containerId, 18 width: this.container.clientWidth, 19 height: this.container.clientHeight, 20 }); 21 22 // TODO AKO DRAGNIT NEKOJ OD POCETOK NA STAGE POZICIIVE KE SA ZEZNAT 23 // TODO jwt vo cookie 24 // TODO placed shape i mouseMoveHandler da ne callback ( da ne vrakjat funkcija) 25 // TODO text na top layer sekogas 26 27 this._floorNum = floorNum; 28 this.mapName = mapName; 29 30 this.gridLayer = new Konva.Layer(); 31 this.mainLayer = new Konva.Layer(); 32 this.dragLayer = new Konva.Layer(); 33 this.infoPinLayer = new Konva.Layer(); 34 this.prioLayer = new Konva.Layer(); 35 this.textLayer = new Konva.Layer(); 36 this.gridLayer.listening(false); 37 38 39 this.othStairs = []; 40 41 this.blockSize = 10; 42 this.efficientDrawingMode = false; 43 this.roomTypes = []; 44 45 this.gridLine = new Konva.Line({ 46 points: [], 47 stroke: "grey", 48 strokeWidth: 1, 49 opacity: 0.3, 50 }); 51 52 this.gridLine.cache(); 53 54 this.mainTransformer = new Konva.Transformer({ 55 centeredScaling: false, 56 rotationSnaps: [0, 90, 180, 270], 57 anchorSize: 5, 58 padding: 2, 59 anchorFill: "#f6031f", 60 borderStroke: "black", 61 anchorStroke: "black", 62 cornerRadius: 20, 63 anchorCornerRadius: 10, 64 anchorDragBoundFunc: this.transformerSnapFunc(), 65 }); 66 67 this.selectionRectangle = new Konva.Rect({ 68 fill: "rgba(56,194,245,0.5)", 69 visible: false, 70 listening: false, 71 zIndex: 100, 72 }); 73 74 this.x1 = 0; 75 this.y1 = 0; 76 this.x2 = 0; 77 this.y2 = 0; 78 79 this.selecting = false; 80 81 this.initialize(); 82 } 83 84 initialize() { 85 this.drawGrid(); 86 this.mainLayer.add(this.mainTransformer); 87 this.mainLayer.add(this.selectionRectangle); 88 this.stage.add(this.gridLayer); 89 this.stage.add(this.dragLayer); 90 this.stage.add(this.mainLayer); 91 this.stage.add(this.infoPinLayer); 92 this.stage.add(this.textLayer); 93 this.setupEventListeners(); 94 } 95 96 setupEventListeners() { 97 document.getElementById("shapeOptions").addEventListener("click", this.selectShape.bind(this)); 98 window.addEventListener("keydown", this.handleExitSelection.bind(this)); 99 window.addEventListener("keydown", this.handleDelete.bind(this)); 100 window.addEventListener("keydown", this.rotateShapesBy90Deg.bind(this)); 101 window.addEventListener("keydown", this.toggleEfficientDrawingMode.bind(this)); 102 window.addEventListener("resize", this.handleResize.bind(this)); 103 104 this.boundEscapeEventListener = this.handleExitSelection.bind(this); 105 this.boundDeleteEventListener = this.handleDelete.bind(this); 106 this.boundRotateShapeEventListener = this.rotateShapesBy90Deg.bind(this) 107 this.boundEfficientDrawingModeEventListener = this.toggleEfficientDrawingMode.bind(this); 108 109 //this.attachKeyPressEventListeners(); 110 111 this.stage.on("mousedown touchstart", this.handleMouseDown.bind(this)); 112 this.stage.on("mousemove touchmove", this.handleMouseMove.bind(this)); 113 this.stage.on("mouseup touchend", this.handleMouseUp.bind(this)); 114 this.stage.on("click tap", this.handleStageClick.bind(this)); 115 this.stage.on("contextmenu", this.placeInfoPin.bind(this)); 116 this.stage.on("dragmove", this.dragStage.bind(this)); 117 this.stage.on("wheel", this.zoom.bind(this)); 118 } 119 120 detachKeyPressEventListeners() { 121 window.removeEventListener("keydown", this.boundEscapeEventListener); 122 window.removeEventListener("keydown", this.boundDeleteEventListener); 123 window.removeEventListener("keydown", this.boundRotateShapeEventListener); 124 window.removeEventListener("keydown", this.boundEfficientDrawingModeEventListener); 125 } 126 127 attachKeyPressEventListeners() { 128 window.addEventListener("keydown", this.boundEscapeEventListener); 129 window.addEventListener("keydown", this.boundDeleteEventListener); 130 window.addEventListener("keydown", this.boundRotateShapeEventListener); 131 window.addEventListener("keydown", this.boundEfficientDrawingModeEventListener); 132 } 133 134 dragStage(e) { 135 if (!e.evt.shiftKey) return; 136 this.drawGrid(); 137 } 138 139 transformerSnapFunc() { 140 return (oldPos, newPos) => { 141 const snapDistance = 8; 142 143 if (this.mainTransformer.getActiveAnchor() === "rotater") { 144 return newPos; 145 } 146 147 const distance = Math.sqrt(Math.pow(newPos.x - oldPos.x, 2) + Math.pow(newPos.y - oldPos.y, 2)); 148 149 if (distance > snapDistance) { 150 return newPos; 151 } 152 153 const nextX = Math.round(newPos.x / this.blockSize) * this.blockSize; 154 const diffX = Math.abs(newPos.x - nextX); 155 156 const nextY = Math.round(newPos.y / this.blockSize) * this.blockSize; 157 const diffY = Math.abs(newPos.y - nextY); 158 159 const snapToX = diffX < snapDistance; 160 const snapToY = diffY < snapDistance; 161 162 if (snapToX && !snapToY) { 163 return { 164 x: nextX, 165 y: oldPos.y, 166 }; 167 } else if (!snapToX && snapToY) { 168 return { 169 x: oldPos.x, 170 y: nextY, 171 }; 172 } else if (snapToX && snapToY) { 173 return { 174 x: nextX, 175 y: nextY, 176 }; 177 } 178 179 return newPos; 180 }; 181 } 182 183 handleResize() { 184 this.stage.width(this.container.offsetWidth); 185 this.stage.height(this.container.offsetHeight); 186 this.drawGrid(); 187 } 188 189 zoom(e) { 190 zoomStage(e, this.stage, true); 191 this.drawGrid(); 192 } 193 194 get floorNum(){ 195 return this._floorNum; 196 } 197 198 set floorNum(val){ 199 this._floorNum = val; 200 } 201 202 drawGrid() { 203 this.gridLayer.destroyChildren(); 204 205 let width = this.stage.width(); 206 let height = this.stage.height(); 207 208 //presmetka od globalen koordinaten sistem vo lokalen na canvasot 209 let transform = this.stage.getAbsoluteTransform().copy().invert(); 210 let topLeft = transform.point({ 211 x: 0, 212 y: 0, 213 }); 214 215 let bottomRight = transform.point({ 216 x: width, 217 y: height, 218 }); 219 220 let startX = Math.floor(topLeft.x / this.blockSize) * this.blockSize; 221 let startY = Math.floor(topLeft.y / this.blockSize) * this.blockSize; 222 223 let endX = Math.ceil(bottomRight.x / this.blockSize) * this.blockSize; 224 let endY = Math.ceil(bottomRight.y / this.blockSize) * this.blockSize; 225 226 for (let x = startX; x <= endX; x += this.blockSize) { 227 let line = this.gridLine.clone({ 228 points: [x + 0.5, topLeft.y - this.blockSize, x + 0.5, bottomRight.y + this.blockSize], 229 }); 230 231 line.transformsEnabled("position"); 232 line.perfectDrawEnabled(false); 233 line.shadowForStrokeEnabled(false); 234 235 this.gridLayer.add(line); 236 } 237 238 for (let y = startY; y <= endY; y += this.blockSize) { 239 let line = this.gridLine.clone({ 240 points: [topLeft.x - this.blockSize, y + 0.5, bottomRight.x + this.blockSize, y + 0.5], 241 }); 242 243 line.perfectDrawEnabled(false); 244 line.shadowForStrokeEnabled(false); 245 line.transformsEnabled("position"); 246 this.gridLayer.add(line); 247 } 248 249 this.mainLayer.moveToTop(); 250 this.infoPinLayer.moveToTop(); 251 252 this.gridLayer.batchDraw(); 253 } 254 255 placeInfoPin(e) { 256 e.evt.preventDefault(); 257 let mousePos = this.stage.getRelativePointerPosition(); 258 const attrs = { 259 type: "InfoPin", 260 position: mousePos, 261 blockSize: this.blockSize, 262 layer: this.mainLayer, 263 rotation: 0, 264 scaleX: 1, 265 scaleY: 1, 266 increment: true, 267 floorNum: this.floorNum 268 }; 269 let infoPin = Factory.createShape("InfoPin", attrs); 270 addEventHandling(infoPin, this, "dblclick"); 271 //this.shapes.push(infoPin); 272 ShapeRegistry.add(infoPin) 273 this.mainLayer.add(infoPin); 274 infoPin.displayName(this.textLayer); 275 triggerMapSave() 276 277 console.log(infoPin.name()); 278 } 279 280 toggleEfficientDrawingMode(e) { 281 if (e.key === "e" || e.key === "E") { 282 this.efficientDrawingMode = !this.efficientDrawingMode; 283 console.log("EFFICIENT DRAWING MODE is: ", this.efficientDrawingMode); 284 285 if (!this.efficientDrawingMode) { 286 this.stopDrawing(); 287 } 288 } 289 } 290 291 placeShape() { 292 const mousePos = this.stage.getRelativePointerPosition(); 293 const attrs = { 294 position: mousePos, 295 width: this.blockSize, 296 height: this.blockSize, 297 layer: this.mainLayer, 298 rotation: this.hoverObj.rotation(), 299 scaleX: 1, 300 scaleY: 1, 301 increment: true, 302 snap: true, 303 fromLoad: false, 304 blockSize: this.blockSize, 305 floorNum: this.floorNum 306 }; 307 308 const placedObj = Factory.createShape(this.hoverObj.type, attrs); 309 if (!placedObj) return; 310 311 console.info("ATTRS FNUM",attrs.floorNum) 312 313 this.mainLayer.add(placedObj); 314 //this.shapes.push(placedObj); 315 console.log("VO PLACED SHAEPS WALL ZITI SE: " + placedObj.className); 316 ShapeRegistry.add(placedObj); 317 addEventHandling(placedObj, this, "dblclick"); 318 this.mainLayer.draw(); 319 320 // site ovie func da se vo edna funkcija vo shape. 321 322 placedObj.displayName(this.textLayer); 323 placedObj.snapToGrid(); 324 325 triggerMapSave(); 326 327 if (!this.efficientDrawingMode) { 328 this.stopDrawing(); 329 } 330 } 331 332 stopDrawing() { 333 this.mainTransformer.nodes([]); 334 if (this.hoverObj != null) this.hoverObj.remove(); 335 this.dragLayer.removeChildren(); 336 this.stage.off("mousemove", this.boundMouseMoveHandler); 337 this.stage.off("click", this.boundPlaceShapeHandler); 338 } 339 340 mouseMoveHandler() { 341 const mousePos = this.stage.getRelativePointerPosition(); 342 this.hoverObj.position({x: mousePos.x, y: mousePos.y}); 343 this.hoverObj.visible(true); 344 } 345 346 startDrawing(shapeType) { 347 const attrs = { 348 position: {x: 0, y: 0}, 349 width: this.blockSize, 350 height: this.blockSize, 351 layer: this.mainLayer, 352 rotation: 0, 353 scaleX: 1, 354 scaleY: 1, 355 increment: false, 356 snap: true, 357 fromLoad: false, 358 blockSize: this.blockSize 359 }; 360 this.hoverObj = Factory.createShape(shapeType, attrs); 361 362 console.log("HOVBER OBK:", this.hoverObj) 363 364 this.hoverObj.visible(false); 365 this.dragLayer.add(this.hoverObj); 366 this.dragLayer.moveToTop(); 367 this.boundMouseMoveHandler = this.mouseMoveHandler.bind(this); 368 this.boundPlaceShapeHandler = this.placeShape.bind(this); 369 370 this.stage.on("mousemove", this.boundMouseMoveHandler); 371 this.stage.on("click", this.boundPlaceShapeHandler); 372 } 373 374 selectShape(e) { 375 if (e.target.tagName === "LI") { 376 const shapeType = e.target.getAttribute("data-info"); 377 this.startDrawing(shapeType); 378 this.mainTransformer.nodes([]); 379 } 380 } 381 382 rotateShapesBy90Deg(e) { 383 if (e.key === "r" || e.key === "R") { 384 if (this.hoverObj) { 385 this.hoverObj.rotate(90); 386 } 387 this.mainTransformer.nodes().forEach((node) => { 388 node.rotate(90); 389 }); 390 } 391 } 392 393 handleDelete(e) { 394 if (e.key === "Delete") { 395 this.mainTransformer.nodes().forEach((node) => { 396 node.remove(); 397 node.destroy(); 398 ShapeRegistry.delete(node); 399 triggerMapSave(); 400 }); 401 this.mainTransformer.nodes([]); 402 this.mainLayer.batchDraw(); 403 } 404 } 405 406 handleExitSelection(e) { 407 if (e.key === "Escape") { 408 this.mainTransformer.nodes([]); 409 this.stopDrawing(); 410 } 411 } 412 413 handleMouseDown(e) { 414 this.stage.draggable(e.evt.shiftKey); 415 416 if (e.target !== this.stage) { 417 return; 418 } 419 420 e.evt.preventDefault(); 421 this.x1 = this.stage.getRelativePointerPosition().x; 422 this.y1 = this.stage.getRelativePointerPosition().y; 423 this.x2 = this.stage.getRelativePointerPosition().x; 424 this.y2 = this.stage.getRelativePointerPosition().y; 425 426 this.selectionRectangle.width(0); 427 this.selectionRectangle.height(0); 428 this.selecting = true; 429 } 430 431 handleMouseMove(e) { 432 if (!this.selecting) { 433 return; 434 } 435 e.evt.preventDefault(); 436 this.x2 = this.stage.getRelativePointerPosition().x; 437 this.y2 = this.stage.getRelativePointerPosition().y; 438 439 this.selectionRectangle.setAttrs({ 440 visible: true, 441 x: Math.min(this.x1, this.x2), 442 y: Math.min(this.y1, this.y2), 443 width: Math.abs(this.x2 - this.x1), 444 height: Math.abs(this.y2 - this.y1), 445 }); 446 } 447 448 handleMouseUp(e) { 449 this.selecting = false; 450 this.stage.draggable(false); 451 452 if (!this.selectionRectangle.visible()) { 453 return; 454 } 455 456 e.evt.preventDefault(); 457 this.selectionRectangle.visible(false); 458 const shapes = this.stage.find(".mapObj"); 459 const box = this.selectionRectangle.getClientRect(); 460 const selected = shapes.filter((shape) => Konva.Util.haveIntersection(box, shape.getClientRect())); 461 this.mainTransformer.nodes(selected); 462 console.log(this.mainTransformer.nodes()); 463 } 464 465 saveShapeDetails() { 466 // this.shapes.forEach(shape => { 467 // shape.saveShapeDetails(); 468 // console.log(shape.info); 469 // }); 470 ShapeRegistry.saveDetails(); 471 console.log("thisflornum",this.floorNum) 472 return { 473 shapes: ShapeRegistry.getShapes(this.floorNum), 474 roomTypes: JSON.stringify(this.roomTypes), 475 mapName: this.mapName, 476 floorNum: this.floorNum 477 } 478 } 479 480 getPayload(){ 481 this.saveShapeDetails(); 144 482 return { 145 x: nextX, 146 y: oldPos.y, 147 }; 148 } else if (!snapToX && snapToY) { 149 return { 150 x: oldPos.x, 151 y: nextY, 152 }; 153 } else if (snapToX && snapToY) { 154 return { 155 x: nextX, 156 y: nextY, 157 }; 158 } 159 160 return newPos; 161 }; 162 } 163 164 handleResize() { 165 this.stage.width(this.container.offsetWidth); 166 this.stage.height(this.container.offsetHeight); 167 this.drawGrid(); 168 } 169 170 zoom(e) { 171 zoomStage(e,this.stage); 172 this.drawGrid(); 173 } 174 175 drawGrid() { 176 this.gridLayer.destroyChildren(); 177 178 let width = this.stage.width(); 179 let height = this.stage.height(); 180 181 //presmetka od globalen koordinaten sistem vo lokalen na canvasot 182 let transform = this.stage.getAbsoluteTransform().copy().invert(); 183 let topLeft = transform.point({ 184 x: 0, 185 y: 0, 186 }); 187 188 let bottomRight = transform.point({ 189 x: width, 190 y: height, 191 }); 192 193 let startX = Math.floor(topLeft.x / this.blockSize) * this.blockSize; 194 let startY = Math.floor(topLeft.y / this.blockSize) * this.blockSize; 195 196 let endX = Math.ceil(bottomRight.x / this.blockSize) * this.blockSize; 197 let endY = Math.ceil(bottomRight.y / this.blockSize) * this.blockSize; 198 199 for (let x = startX; x <= endX; x += this.blockSize) { 200 let line = this.gridLine.clone({ 201 points: [x + 0.5, topLeft.y - this.blockSize, x + 0.5, bottomRight.y + this.blockSize], 202 }); 203 204 line.transformsEnabled("position"); 205 line.perfectDrawEnabled(false); 206 line.shadowForStrokeEnabled(false); 207 208 this.gridLayer.add(line); 209 } 210 211 for (let y = startY; y <= endY; y += this.blockSize) { 212 let line = this.gridLine.clone({ 213 points: [topLeft.x - this.blockSize, y + 0.5, bottomRight.x + this.blockSize, y + 0.5], 214 }); 215 216 line.perfectDrawEnabled(false); 217 line.shadowForStrokeEnabled(false); 218 line.transformsEnabled("position"); 219 this.gridLayer.add(line); 220 } 221 222 this.mainLayer.moveToTop(); 223 this.infoPinLayer.moveToTop(); 224 225 this.gridLayer.batchDraw(); 226 } 227 228 placeInfoPin(e) { 229 e.evt.preventDefault(); 230 let mousePos = this.stage.getRelativePointerPosition(); 231 let infoPin = Factory.createShape("InfoPin", mousePos, this.blockSize, this.mainLayer, 0,1,1,true); 232 this.addModalHandling(infoPin); 233 this.shapes.push(infoPin); 234 this.mainLayer.add(infoPin) 235 infoPin.displayName(this.textLayer); 236 console.log(infoPin.name()); 237 } 238 239 toggleEfficientDrawingMode(e) { 240 if (e.key === "e" || e.key === "E") { 241 this.efficientDrawingMode = !this.efficientDrawingMode; 242 console.log("EFFICIENT DRAWING MODE is: ", this.efficientDrawingMode); 243 244 if (!this.efficientDrawingMode) { 245 this.stopDrawing(); 246 } 247 } 248 } 249 250 placeShape() { 251 const mousePos = this.stage.getRelativePointerPosition(); 252 const placedObj = Factory.createShape( 253 this.hoverObj.type, 254 mousePos, 255 this.blockSize, 256 this.mainLayer, 257 this.hoverObj.rotation(), 258 1, 259 1, 260 true 261 ); 262 263 if (!placedObj) return; 264 265 this.mainLayer.add(placedObj); 266 this.shapes.push(placedObj); 267 this.addModalHandling(placedObj); 268 this.mainLayer.draw(); 269 placedObj.displayName(this.textLayer); 270 placedObj.snapToGrid(); 271 272 if (!this.efficientDrawingMode) { 273 this.stopDrawing(); 274 } 275 } 276 277 stopDrawing() { 278 this.mainTransformer.nodes([]); 279 this.hoverObj.remove(); 280 this.dragLayer.removeChildren(); 281 this.stage.off("mousemove", this.boundMouseMoveHandler); 282 this.stage.off("click", this.boundPlaceShapeHandler); 283 } 284 285 mouseMoveHandler() { 286 const mousePos = this.stage.getRelativePointerPosition(); 287 this.hoverObj.position({ x: mousePos.x, y: mousePos.y }); 288 this.hoverObj.visible(true); 289 } 290 291 startDrawing(shapeType) { 292 let pos = { x: 0, y: 0 }; 293 this.hoverObj = Factory.createShape(shapeType, pos, this.blockSize, this.dragLayer, 0); 294 295 this.hoverObj.visible(false); 296 this.dragLayer.add(this.hoverObj); 297 this.dragLayer.moveToTop(); 298 this.boundMouseMoveHandler = this.mouseMoveHandler.bind(this); 299 this.boundPlaceShapeHandler = this.placeShape.bind(this); 300 301 this.stage.on("mousemove", this.boundMouseMoveHandler); 302 this.stage.on("click", this.boundPlaceShapeHandler); 303 } 304 305 selectShape(e) { 306 if (e.target.tagName === "LI") { 307 const shapeType = e.target.getAttribute("data-info"); 308 this.startDrawing(shapeType); 309 this.mainTransformer.nodes([]); 310 } 311 } 312 313 addModalHandling(shape) { 314 shape.on("dblclick", () => { 315 const eventName = shape.modalEventName; 316 if (eventName) { 317 const data = { 318 room: shape, 319 map: this, 320 }; 321 const event = new CustomEvent(eventName, { detail: data }); 322 window.dispatchEvent(event); 323 } 324 }); 325 } 326 327 rotateShapesBy90Deg(e) { 328 if (e.key === "r" || e.key === "R") { 329 if (this.hoverObj) { 330 this.hoverObj.rotate(90); 331 } 332 this.mainTransformer.nodes().forEach((node) => { 333 node.rotate(90); 334 }); 335 } 336 } 337 338 handleDelete(e) { 339 if (e.key === "Delete") { 340 this.mainTransformer.nodes().forEach((node) => { 341 node.remove(); 342 this.shapes.splice(this.shapes.indexOf(node), 1); 343 }); 344 this.mainTransformer.nodes([]); 345 this.mainLayer.batchDraw(); 346 } 347 } 348 349 handleExitSelection(e) { 350 if (e.key === "Escape") { 351 this.mainTransformer.nodes([]); 352 this.stopDrawing(); 353 } 354 } 355 356 handleMouseDown(e) { 357 this.stage.draggable(e.evt.shiftKey); 358 359 if (e.target !== this.stage) { 360 return; 361 } 362 363 e.evt.preventDefault(); 364 this.x1 = this.stage.getRelativePointerPosition().x; 365 this.y1 = this.stage.getRelativePointerPosition().y; 366 this.x2 = this.stage.getRelativePointerPosition().x; 367 this.y2 = this.stage.getRelativePointerPosition().y; 368 369 this.selectionRectangle.width(0); 370 this.selectionRectangle.height(0); 371 this.selecting = true; 372 } 373 374 handleMouseMove(e) { 375 if (!this.selecting) { 376 return; 377 } 378 e.evt.preventDefault(); 379 this.x2 = this.stage.getRelativePointerPosition().x; 380 this.y2 = this.stage.getRelativePointerPosition().y; 381 382 this.selectionRectangle.setAttrs({ 383 visible: true, 384 x: Math.min(this.x1, this.x2), 385 y: Math.min(this.y1, this.y2), 386 width: Math.abs(this.x2 - this.x1), 387 height: Math.abs(this.y2 - this.y1), 388 }); 389 } 390 391 handleMouseUp(e) { 392 this.selecting = false; 393 this.stage.draggable(false); 394 395 if (!this.selectionRectangle.visible()) { 396 return; 397 } 398 399 e.evt.preventDefault(); 400 this.selectionRectangle.visible(false); 401 const shapes = this.stage.find(".mapObj"); 402 const box = this.selectionRectangle.getClientRect(); 403 const selected = shapes.filter((shape) => Konva.Util.haveIntersection(box, shape.getClientRect())); 404 this.mainTransformer.nodes(selected); 405 console.log(this.mainTransformer.nodes()); 406 } 407 408 saveShapeDetails() { 409 this.shapes.forEach((room) => { 410 room.saveShapeDetails(); 411 console.log(room.info); 412 }); 413 } 414 415 async render() { 416 this.saveShapeDetails(); 417 const httpService = new HttpService("http://localhost:8080/api/protected", true); 418 try { 419 const response = await httpService.post("/render", this.shapes); 420 console.log(response); 421 } catch (err) { 422 console.log("ERROR --> Could not render map --->", err); 423 } 424 } 425 426 async saveMap(mapName) { 427 this.saveShapeDetails(); 428 const httpService = new HttpService("http://localhost:8080/api/protected/maps", true); 429 try { 430 const response = await httpService.put(`/save?mapName=${mapName}`, this.shapes); 431 console.log(response, "resp in builder"); 432 } catch (err) { 433 console.log("ERROR --> Could not Save map --->", err); 434 } 435 } 436 437 handleStageClick(e) { 438 if (this.selectionRectangle.visible()) { 439 return; 440 } 441 442 if (e.target === this.stage) { 443 this.mainTransformer.nodes([]); 444 return; 445 } 446 447 if (!e.target.hasName("mapObj")) { 448 return; 449 } 450 451 const metaPressed = e.evt.shiftKey || e.evt.ctrlKey || e.evt.metaKey; 452 const isSelected = this.mainTransformer.nodes().indexOf(e.target) >= 0; 453 454 if (!metaPressed && !isSelected) { 455 this.mainTransformer.nodes([e.target]); 456 console.log("Sel 1"); 457 } else if (metaPressed && isSelected) { 458 const nodes = this.mainTransformer.nodes().slice(); 459 nodes.splice(nodes.indexOf(e.target), 1); 460 this.mainTransformer.nodes(nodes); 461 } else if (metaPressed && !isSelected) { 462 const nodes = this.mainTransformer.nodes().concat([e.target]); 463 this.mainTransformer.nodes(nodes); 464 } 465 } 466 467 addRoomType(roomType) { 468 this.roomTypes.push(roomType); 469 } 470 471 getRoomTypes() { 472 return this.roomTypes; 473 } 474 475 getRooms() { 476 return this.getShapeInfoByType("Room"); 477 } 478 479 getPins() { 480 return this.getShapeInfoByType("InfoPin"); 481 } 482 483 getEntrances() { 484 return this.getShapeInfoByType("Entrance"); 485 } 486 487 getConnections() { 488 const pins = this.getShapeInfoByType("InfoPin"); 489 const entrances = this.getShapeInfoByType("Entrance"); 490 return [...pins, ...entrances]; 491 } 492 493 getShapeInfoByType(type) { 494 return this.shapes.filter((shape) => shape.className === type).map((shape) => shape.info); 495 } 496 497 updateConnections() { 498 console.log("Update"); 499 500 this.shapes.forEach((shape) => { 501 if (shape.className === "InfoPin" || shape.className === "Entrance") { 502 shape.info.selectedPins.forEach((connectedShapeName) => { 503 const connectedShape = this.shapes.find((s) => s.info.name === connectedShapeName); 504 if ( 505 connectedShape && 506 (connectedShape.className === "InfoPin" || connectedShape.className === "Entrance") 507 ) { 508 if (!connectedShape.info.selectedPins.includes(shape.info.name)) { 509 connectedShape.info.selectedPins.push(shape.info.name); 510 } 511 } 512 }); 513 } 514 }); 515 } 516 517 removeConnection(from, to) { 518 this.shapes 519 .filter((s) => s.info.name === from || s.info.name === to) 520 .forEach((s) => { 521 s.info.selectedPins = s.info.selectedPins.filter((pin) => pin !== from && pin !== to); 522 }); 523 console.log("Remove"); 524 } 525 526 updateRoomNames() { 527 this.textLayer.removeChildren(); 528 this.shapes.forEach((shape) => { 529 shape.displayName(this.textLayer); 530 }); 531 this.textLayer.children.forEach((child) => console.log(child)); 532 } 533 534 clearMap() { 535 this.mainLayer.removeChildren(); 536 this.shapes = []; 537 this.hoverObj = null; 538 } 539 540 deserializeMap(data) { 541 console.log("DESERIALIZING: ", data); 542 this.clearMap(); 543 let dsrData = JSON.parse(data); 544 dsrData.forEach((child) => { 545 const shape = JSON.parse(child); 546 const loadedShape = Factory.createShape( 547 shape.className, 548 { x: shape.attrs.x, y: shape.attrs.y }, 549 this.blockSize, 550 this.mainLayer, 551 shape.attrs.rotation, 552 shape.attrs.scaleX, 553 shape.attrs.scaleY 554 ); 555 loadedShape.loadInfo(shape.attrs); 556 this.shapes.push(loadedShape); 557 this.addModalHandling(loadedShape); 558 this.mainLayer.add(loadedShape); 559 }); 560 this.mainTransformer.nodes([]); 561 this.mainLayer.add(this.mainTransformer); 562 this.mainLayer.add(this.selectionRectangle); 563 564 this.shapes.forEach((shape) => shape.displayName(this.textLayer)); 565 } 483 shapes: ShapeRegistry.getShapes(this.floorNum), 484 roomTypes: JSON.stringify(this.roomTypes), 485 mapName: this.mapName, 486 floorNum: this.floorNum 487 } 488 } 489 490 491 handleStageClick(e) { 492 if (this.selectionRectangle.visible()) { 493 return; 494 } 495 496 if (e.target === this.stage) { 497 this.mainTransformer.nodes([]); 498 return; 499 } 500 501 if (!e.target.hasName("mapObj")) { 502 return; 503 } 504 505 const metaPressed = e.evt.shiftKey || e.evt.ctrlKey || e.evt.metaKey; 506 const isSelected = this.mainTransformer.nodes().indexOf(e.target) >= 0; 507 508 if (!metaPressed && !isSelected) { 509 this.mainTransformer.nodes([e.target]); 510 console.log("Sel 1"); 511 } else if (metaPressed && isSelected) { 512 const nodes = this.mainTransformer.nodes().slice(); 513 nodes.splice(nodes.indexOf(e.target), 1); 514 this.mainTransformer.nodes(nodes); 515 } else if (metaPressed && !isSelected) { 516 const nodes = this.mainTransformer.nodes().concat([e.target]); 517 this.mainTransformer.nodes(nodes); 518 } 519 } 520 521 addRoomType(type) { 522 this.roomTypes.push(type); 523 } 524 525 removeRoomType(targetType) { 526 this.roomTypes = this.roomTypes.filter(type => type !== targetType); 527 } 528 529 getRoomTypes() { 530 return this.roomTypes; 531 } 532 533 getRooms() { 534 return this.getShapeInfoByType("Room"); 535 } 536 537 getPins() { 538 return this.getShapeInfoByType("InfoPin"); 539 } 540 541 getEntrances() { 542 return this.getShapeInfoByType("Entrance"); 543 } 544 545 546 547 getShapeInfoByType(type) { 548 return ShapeRegistry.getShapes(this.floorNum).filter((shape) => shape.className === type).map((shape) => shape.info); 549 } 550 551 552 drawConnection(node1Name, node2Name) { 553 554 ShapeRegistry.drawConnection(node1Name,node2Name); 555 } 556 557 getNodeByName(name) { 558 return ShapeRegistry.getShapes(this.floorNum).filter(shape => shape instanceof MapNode && shape.info.name === name)[0]; 559 } 560 561 removeConnection(from, to) { 562 ShapeRegistry.removeConnection(from,to); 563 } 564 565 updateRoomNames() { 566 this.textLayer.removeChildren(); 567 ShapeRegistry.getShapes(this.floorNum).forEach((shape) => { 568 shape.displayName(this.textLayer); 569 }); 570 571 } 572 573 isMainEntranceSelected() { 574 console.log(this.getEntrances().forEach((en) => console.log(en.isMainEntrance, "asdsad"))); 575 576 let hasMainEntrance = false; 577 578 this.getEntrances().forEach((entrance) => { 579 if (entrance.isMainEntrance === true) hasMainEntrance = true; 580 }); 581 582 return hasMainEntrance; 583 584 } 585 586 clearMap() { 587 this.mainLayer.removeChildren(); 588 this.hoverObj = null; 589 } 590 591 592 // ova klasa i map display da nasledbat od glavna klasa 593 594 loadNewFloor(floor) { 595 596 this._floorNum = floor?.num; 597 let data = floor?.mapData; 598 599 if (data == null || data === "") return; 600 601 this.deserializeMap(data); 602 shapeRegistry.getShapes(this.floorNum).forEach((shape) => { 603 this.mainLayer.add(shape); 604 }); 605 606 607 } 608 609 //nov 610 deserializeMap(data) { 611 console.log("DESERIALIZING: ", data); 612 ShapeRegistry.clear(this.floorNum); 613 614 if (data != null) { 615 const dsrData = JSON.parse(data); 616 //load shapes 617 dsrData.forEach((shape) => { 618 const attrs = { 619 position: {x: shape.attrs.x, y: shape.attrs.y}, 620 width: shape.attrs.width, 621 height: shape.attrs.height, 622 layer: this.mainLayer, 623 blockSize: this.blockSize, 624 rotation: shape.attrs.rotation, 625 scaleX: shape.attrs.scaleX, 626 scaleY: shape.attrs.scaleY, 627 increment: false, 628 snap: true, 629 fromLoad: true, 630 floorNum: this.floorNum 631 }; 632 633 const loadedShape = Factory.createShape(shape.className, attrs); 634 loadedShape.loadInfo(shape.attrs); 635 ShapeRegistry.add(loadedShape); 636 // na destroy trebit events da sa trgnat 637 addEventHandling(loadedShape, this, "dblclick"); 638 }); 639 let nodes = ShapeRegistry.getShapes(this.floorNum).filter((shape) => shape.className === "InfoPin" || shape.className === "Entrance" || shape.className === "Stairs"); 640 nodes.forEach((pin) => { 641 let connectedPins = pin.info.selectedPins; 642 if (connectedPins) { 643 connectedPins.forEach((slPin) => { 644 console.log("CONN node1: " + pin + "conn node2: " + slPin) 645 this.drawConnection(pin.info.name, slPin); 646 }); 647 } 648 }); 649 } 650 651 this.mainTransformer.nodes([]); 652 this.mainLayer.add(this.mainTransformer); 653 this.mainLayer.add(this.selectionRectangle); 654 655 ShapeRegistry.getShapes(this.floorNum).forEach((shape) => shape.displayName(this.textLayer)); 656 } 657 566 658 } -
imaps-frontend/src/scripts/main/MapDisplay.js
rd565449 r0c6b92a 3 3 import HttpService from "../net/HttpService.js"; 4 4 import {zoomStage} from "../util/zoomStage.js"; 5 import {addEventHandling} from "../util/addEventHandling.js"; 6 import triggerNavigate from "../util/triggerNavigate.js"; 7 import config from "../net/netconfig.js"; 8 5 9 export class MapDisplay { 6 constructor(containerId) { 7 this.container = document.getElementById(containerId); 8 this.containerId = containerId; 9 this.stage = new Konva.Stage({ 10 container: containerId, 11 width: window.innerWidth, 12 height: window.innerHeight, 13 draggable: true, 14 }); 15 16 this.shapes = []; 17 this.loaded = false; 18 this.mainLayer = new Konva.Layer(); 19 this.routeLayer = new Konva.Layer(); 20 this.textLayer = new Konva.Layer(); 21 this.stage.add(this.mainLayer); 22 this.stage.add(this.routeLayer); 23 this.stage.add(this.textLayer); 24 this.route = new Konva.Line(); 25 26 this.stage.on("resize", () => { 27 this.stage.width = window.innerWidth; 28 this.stage.height = window.innerHeight; 29 }); 30 31 this.stage.on("wheel",(e) => { 32 zoomStage(e,this.stage); 33 }) 34 35 36 } 37 38 deserializeMap(data) { 39 data.forEach((child) => { 40 const shape = JSON.parse(child); 41 if (shape.className !== "InfoPin") { 42 const renderedShape = Factory.createRenderedShape( 43 shape.className, 44 shape.attrs 45 ); 46 this.shapes.push(renderedShape); 47 } 48 }); 49 } 50 51 displayRoomNames(){ 52 console.log("VLEZE") 53 this.shapes.forEach(shape => { 54 shape.displayName(this.textLayer); 55 }) 56 57 this.textLayer.children.forEach(child => console.log(child,"DECAAA")); 58 } 59 60 async loadMap() { 61 const httpService = new HttpService(); 62 const mapData = await httpService.get("/public/mapData"); 63 console.log("DESERIALIZED --->",mapData); 64 this.deserializeMap(mapData); 65 this.shapes.forEach((shape) => { 66 this.mainLayer.add(shape); 67 }); 68 this.displayRoomNames(); 69 } 70 71 drawRoute(path) { 72 this.routeLayer.removeChildren(); 73 console.log("====PATH===="); 74 path.forEach((point) => console.log(point.x, point.y)); 75 76 const pointsArray = path.flatMap((point) => [point.x, point.y]); 77 78 console.log(pointsArray, "POINTS"); 79 80 let buff = []; 81 let count = 0; 82 let index = 0; 83 84 const drawNextSegment = () => { 85 if (index >= pointsArray.length) return; 86 87 buff.push(pointsArray[index]); 88 count++; 89 90 if (count % 4 === 0) { 91 const line = new Konva.Arrow({ 92 points: buff, 93 stroke: "#e91332", 94 strokeWidth: 2.5, 95 dash: [5, 4], 96 lineCap: 'round', 97 lineJoin: 'round', 98 pointerLength: 7, 99 pointerWidth: 7, 100 fill:'red', 101 }); 102 103 this.routeLayer.add(line); 104 this.routeLayer.draw(); 105 106 console.log(buff, "BUFFER"); 107 buff = []; 108 index -= 2; 10 constructor(containerId, floorNum) { 11 this.container = document.getElementById(containerId); 12 this.containerId = containerId; 13 this.stage = new Konva.Stage({ 14 container: containerId, 15 width: window.innerWidth, 16 height: window.innerHeight, 17 draggable: true, 18 }); 19 20 this.shapes = []; 21 this.roomTypes = []; 22 this.loaded = false; 23 this.mainLayer = new Konva.Layer(); 24 this.routeLayer = new Konva.Layer(); 25 this.textLayer = new Konva.Layer(); 26 this.stage.add(this.mainLayer); 27 this.stage.add(this.routeLayer); 28 this.stage.add(this.textLayer); 29 30 this.floorNum = floorNum; 31 32 this.navArrow = new Konva.Arrow({ 33 stroke: "#bb0000", 34 strokeWidth: 3, 35 dash: [12, 7], 36 lineCap: "round", 37 tension: 10, 38 pointerLength: 2, 39 pointerWidth: 3, 40 }); 41 42 this.navArrow.cache(); 43 44 this.stage.on("resize", () => { 45 this.stage.width = window.innerWidth; 46 this.stage.height = window.innerHeight; 47 }); 48 49 this.stage.on("wheel", (e) => { 50 zoomStage(e, this.stage); 51 }); 52 } 53 54 clearMap() { 55 this.mainLayer.removeChildren(); 56 this.shapes.forEach(shape => shape.clearText()) 57 this.shapes = []; 58 } 59 60 deserializeMap(data) { 61 this.clearMap(); 62 63 let dsrData = JSON.parse(data); 64 dsrData.forEach((shape) => { 65 if (shape.className !== "InfoPin") { 66 const renderedShape = Factory.createRenderedShape(shape.className, shape.attrs); 67 addEventHandling(renderedShape, this, "click"); 68 this.shapes.push(renderedShape); 69 } 70 }); 71 } 72 73 displayRoomNames() { 74 this.shapes.forEach((shape) => { 75 shape.displayName(this.textLayer); 76 }); 77 78 } 79 80 81 82 loadMapN(floorData) { 83 if (floorData == null || floorData === "") return; 84 85 this.deserializeMap(floorData); 86 this.shapes.forEach((shape) => { 87 this.mainLayer.add(shape); 88 }); 89 this.displayRoomNames(); 90 this.initializeRoomTypes(); 91 92 } 93 94 clearRoute() { 95 this.routeLayer.removeChildren(); 96 } 97 98 99 drawRouteNEW(nodes, offset = 0) { 100 101 this.clearRoute(); 102 console.log("====PATH===="); 103 nodes.forEach((node) => console.log("NODE", node)); 104 105 let idx = offset; 106 let buff = [nodes[idx].coordinates.x, nodes[idx].coordinates.y]; 107 108 109 ++idx; 110 111 console.log("INIT BUFFER", buff); 112 console.log("INIT IDX", idx); 113 114 const drawNextSegment = () => { 115 116 if (idx >= nodes.length){ 117 return; 118 } 119 120 const currentNode = nodes[idx - 1]; 121 const nextNode = nodes[idx]; 122 123 if (nextNode.floorNumber !== currentNode.floorNumber) { 124 triggerNavigate(nodes, idx, nextNode.floorNumber, nextNode); 125 return; 126 } 127 128 const startX = currentNode.coordinates.x; 129 const startY = currentNode.coordinates.y; 130 const endX = nextNode.coordinates.x; 131 const endY = nextNode.coordinates.y; 132 133 const numSegments = 12; 134 135 const deltaX = (endX - startX) / numSegments; 136 const deltaY = (endY - startY) / numSegments; 137 138 const drawSegment = (i) => { 139 const segmentX = startX + deltaX * i; 140 const segmentY = startY + deltaY * i; 141 142 buff.push(segmentX, segmentY); 143 144 let line = this.navArrow.clone({ points: [...buff] }); 145 this.routeLayer.add(line); 146 this.routeLayer.draw(); 147 148 buff = [segmentX, segmentY]; 149 }; 150 151 let segmentIdx = 1; 152 const interval = setInterval(() => { 153 drawSegment(segmentIdx); 154 segmentIdx++; 155 156 if (segmentIdx > numSegments) { 157 clearInterval(interval); 158 idx++; 159 setTimeout(drawNextSegment, 150); 160 } 161 }, 50); 162 }; 163 164 drawNextSegment(); 165 } 166 167 168 169 initializeRoomTypes() { 170 this.roomTypes = this.shapes 171 .filter((shape) => shape.class === "Room" && shape.info.type !== "") 172 .map((shape) => shape.info.type); 173 } 174 175 getRoomTypes() { 176 return this.roomTypes; 177 } 178 179 180 getShapeByName(name){ 181 return this.shapes.find(shape => shape.info.name === name) 182 } 183 184 getShapeByType(type) { 185 return this.shapes.filter((shape) => shape.class === type) 186 } 187 188 toggleSearchRoom() { 189 this.toggleSearch = !this.toggleSearch; 190 } 191 192 //ova e loso ne trebit vaka 193 highlightShape(roomName) { 194 let foundShape = this.shapes.filter((shape) => shape.info.name === roomName)[0]; 195 foundShape.highlight(); 196 } 197 198 getMainEntrance() { 199 return this.shapes.filter(shape => shape.class === "Entrance").filter(el => el.info.isMainEntrance === true)[0]; 200 } 201 202 setFilter(filter) { 203 let rooms = this.getShapeByType("Room") 204 if (filter === "All") { 205 rooms.forEach((shape) => { 206 shape.unHighlight() 207 }) 208 } else { 209 rooms.filter((shape) => shape.info.type === filter).forEach((shape) => { 210 shape.highlight() 211 }) 212 rooms.filter((shape) => shape.info.type !== filter).forEach((shape) => { 213 shape.unHighlight() 214 }) 109 215 } 110 216 111 index++; 112 113 setTimeout(drawNextSegment, 25); 114 }; 115 116 drawNextSegment(); 217 } 117 218 } 118 119 120 search() {121 console.log("VLEZE VO SEARCH");122 }123 } -
imaps-frontend/src/scripts/net/HttpService.js
rd565449 r0c6b92a 3 3 4 4 class HttpService { 5 constructor(URL = config.apiBaseUrl, auth = false) { 6 this.baseURL = URL; 5 constructor(auth = false) { 7 6 this.auth = auth; 8 7 } … … 33 32 } 34 33 35 const response = await fetch(`${ this.baseURL}${endpoint}`, options);34 const response = await fetch(`${endpoint}`, options); 36 35 37 36 if (!response.ok) { -
imaps-frontend/src/scripts/net/netconfig.js
rd565449 r0c6b92a 1 export const API_BASE_URL = "http://localhost:8080/api"; 2 export const API_PROTECTED = `${API_BASE_URL}/protected` 3 export const API_PUBLIC = `${API_BASE_URL}/public` 4 export const API_AUTH = `${API_BASE_URL}/auth` 5 1 6 2 7 const config = { 3 apiBaseUrl: "http://localhost:8080/api", 8 my_maps: { 9 display: `${API_PROTECTED}/my-maps`, 10 save: `${API_PROTECTED}/my-maps/save`, 11 add: `${API_PROTECTED}/my-maps/create`, 12 load: `${API_PROTECTED}/my-maps/load`, 13 delete: `${API_PROTECTED}/my-maps/delete`, 14 publish: `${API_PROTECTED}/publish/add`, 15 publish_get: `${API_PROTECTED}/publish/get`, 16 }, 17 room_types: { 18 display: (auth) => { 19 return auth ? `${API_PROTECTED}/room-types` : `${API_PUBLIC}/room-types` 20 }, 21 add: `${API_PROTECTED}/room-types/add`, 4 22 5 endpoints: { 6 login: "/auth/login", 7 register: "/auth/register", 8 verify: "/auth/verify", 9 render: "/protected/render", 10 publicMapData: "/public/mapData" 23 }, 24 floors: { 25 add: `${API_PROTECTED}/floors/add`, 26 load: `${API_PROTECTED}/my-maps/load`, 27 delete: `${API_PROTECTED}/floors/delete`, 28 }, 29 view_maps: { 30 display: `${API_PUBLIC}/maps`, 31 load: (auth) => { 32 return auth ? `${API_PROTECTED}/load-map` : `${API_PUBLIC}/load-map` 33 }, 34 navigate: `${API_PUBLIC}/navigate`, 35 add_favourite: `${API_PROTECTED}/favourites/add`, 36 }, 37 favourites: { 38 display: `${API_PROTECTED}/favourites`, 39 add: `${API_PROTECTED}/favourites/add`, 40 delete: `${API_PROTECTED}/favourites/delete`, 41 }, 42 auth:{ 43 login: `${API_AUTH}/login`, 44 register: `${API_AUTH}/register`, 45 verify: `${API_AUTH}/verify` 46 47 }, 48 admin:{ 49 display: `${API_BASE_URL}/admin`, 50 load_pr: `${API_BASE_URL}/admin/load-pr`, 51 approve_pr: `${API_BASE_URL}/admin/pr/approve`, 52 deny_pr: `${API_BASE_URL}/admin/pr/deny` 11 53 } 12 54 }; 13 55 56 14 57 export default config; -
imaps-frontend/src/scripts/rendered_shapes/RenderedEntrance.js
rd565449 r0c6b92a 1 import RenderedMapShape from "./RenderedMapShape.js"; 1 import RenderedMapShape from "../base/RenderedMapShape.js"; 2 import {_registerNode} from "konva/lib/Global"; 3 import RenderedRoom from "./RenderedRoom.js"; 2 4 3 export default class RenderedEntrance extends RenderedMapShape {4 constructor(attrs,scaleX,scaleY){5 6 7 8 9 10 fill: '#1c3cff',11 stroke: 'black',12 13 14 15 cornerRadius:3,16 zIndex: 017 5 export default class RenderedEntrance extends RenderedMapShape { 6 constructor(attrs, scaleX, scaleY) { 7 super({ 8 x: attrs.x, 9 y: attrs.y, 10 width: attrs.width * scaleX, 11 height: attrs.height * scaleY, 12 fill: "#7fef83", 13 stroke: "black", 14 strokeWidth: 1, 15 draggable: false, 16 rotation: attrs.rotation, 17 cornerRadius: 3, 18 zIndex: 0, 19 }); 18 20 19 this.info.name = attrs.obj_name; 20 this.info.description = attrs.description; 21 22 23 this.on("mouseenter",() => { 24 console.log("HOVER ROOM IN", this.x()); 25 console.log(this.info.name,"NAME"); 26 this.stroke('purple'); 27 }) 28 this.on("mouseleave", () => { 29 console.log("HOVER ROOM OUT"); 30 this.opacity(1); 31 this.stroke('black') 21 this.info.name = attrs.obj_name; 22 this.info.description = attrs.description; 23 this.info.isMainEntrance = attrs.is_main_entrance; 32 24 33 })25 this.floorNum = attrs.floor_num 34 26 35 this.initText() 36 } 27 this.class = "Entrance"; 28 29 console.log("ATTRS VIEW: " + attrs) 30 31 this.on("mouseenter", () => { 32 this.stroke("purple"); 33 }); 34 this.on("mouseleave", () => { 35 this.opacity(1); 36 this.stroke("black"); 37 }); 38 39 //this.initText(); 40 } 37 41 } 42 43 RenderedEntrance.prototype.className = "RenderedEntrance"; 44 _registerNode(RenderedEntrance); -
imaps-frontend/src/scripts/rendered_shapes/RenderedRoom.js
rd565449 r0c6b92a 1 import RenderedMapShape from "./RenderedMapShape.js"; 1 import RenderedMapShape from "../base/RenderedMapShape.js"; 2 import {_registerNode} from "konva/lib/Global"; 2 3 3 export default class RenderedRoom extends RenderedMapShape{ 4 constructor(attrs,scaleX,scaleY){ 5 super({ 6 x: attrs.x, 7 y: attrs.y, 8 width: attrs.width * scaleX, 9 height: attrs.height * scaleY, 10 fill: 'white', 11 stroke: 'black', 12 strokeWidth: 1, 13 draggable: false, 14 rotation: attrs.rotation, 15 cornerRadius:3, 16 zIndex: 0 17 }); 4 export default class RenderedRoom extends RenderedMapShape { 5 constructor(attrs, scaleX, scaleY) { 6 super({ 7 x: attrs.x, 8 y: attrs.y, 9 width: attrs.width * scaleX, 10 height: attrs.height * scaleY, 11 fill: "#A2D9FF", 12 stroke: "black", 13 strokeWidth: 1, 14 draggable: false, 15 rotation: attrs.rotation, 16 cornerRadius: 3 17 }); 18 18 19 this.info.name = attrs.obj_name; 20 this.info.description = attrs.description; 19 console.info("FNUM RENDER:",attrs.floor_num) 21 20 22 this.textOffsetX = -50 23 24 25 this.on("mouseenter",() => { 26 console.log("HOVER ROOM IN", this.x()); 27 console.log(this.info.name,"NAME"); 28 this.opacity(0.7); 29 this.fill("pink"); 30 }) 31 this.on("mouseleave", () => { 32 console.log("HOVER ROOM OUT"); 33 this.opacity(1); 34 this.fill("white"); 35 }) 21 this.floorNum = attrs.floor_num 36 22 37 this.initText() 38 } 23 this.info.name = attrs.obj_name; 24 this.info.type = attrs.room_type; 25 this.info.description = attrs.description; 26 this.class = "Room"; 27 this.textOffsetX = -50; 39 28 40 29 this.eventName = "openRoomInfoPanel" 30 31 this.on("mouseenter", () => { 32 console.log(this.info.name, "NAME"); 33 this.fill("#65c3f8"); 34 }); 35 this.on("mouseleave", () => { 36 this.fill("#A2D9FF"); 37 }); 38 39 40 41 // searched(){ 42 // this.fill("#b92d39") 43 // } 44 // unsearched(){ 45 // this.fill("#A2D9FF"); 46 // } 47 48 // console.log("ATTRS: " + attrs); 49 50 this.initText(); 51 } 52 highlight(){ 53 this.fill("rgba(29,238,78,0.49)"); 54 this.strokeWidth(2) 55 } 56 unHighlight(){ 57 this.fill("#A2D9FF"); 58 this.strokeWidth(1); 59 } 41 60 } 61 RenderedRoom.prototype.className = "RenderedRoom"; 62 _registerNode(RenderedRoom); -
imaps-frontend/src/scripts/rendered_shapes/RenderedWall.js
rd565449 r0c6b92a 1 import RenderedMapShape from "./RenderedMapShape.js"; 1 import RenderedMapShape from "../base/RenderedMapShape.js"; 2 import {_registerNode} from "konva/lib/Global"; 2 3 3 4 export default class RenderedWall extends RenderedMapShape{ … … 8 9 width: attrs.width * scaleX, 9 10 height: attrs.height * scaleY, 10 fill: ' grey',11 fill: '#4B4B4B', 11 12 stroke: 'black', 12 13 strokeWidth: 1, … … 18 19 } 19 20 } 21 22 RenderedWall.prototype.className = "RenderedWall"; 23 _registerNode(RenderedWall); -
imaps-frontend/src/scripts/shapes/Entrance.js
rd565449 r0c6b92a 1 import Konva from "konva"; 2 import MapShape from "./MapShape"; 3 import { _registerNode } from "konva/lib/Global"; 4 export default class Entrance extends MapShape { 5 constructor(mousePos, blockSize, layer, rotation, snap,id,scaleX = 1, scaleY = 1) { 6 super( 7 { 8 x: mousePos.x, 9 y: mousePos.y, 10 width: blockSize * scaleX, 11 height: blockSize * 2 * scaleY, 12 fill: "#0051ff", 13 stroke: "grey", 14 strokeWidth: 1, 15 opacity: 0.7, 16 name: "mapObj", 17 draggable: true, 18 rotation: rotation, 19 zIndex: 1, 20 }, 21 layer, 22 blockSize, 23 snap 24 ); 25 this.type = "Entrance"; 26 this.modalEventName = "openEntranceModalEvent"; 1 import {_registerNode} from "konva/lib/Global"; 2 import MapNode from "../base/MapNode.js"; 3 import {node} from "prop-types"; 27 4 28 this.id = id; 5 export default class Entrance extends MapNode { 29 6 30 this._info = { 31 name: `Entrance ${id}`, 32 connectedRoom: "", 33 description: "", 34 isMainEntrance: false, 35 selectedPin: "", 36 selectedPins: [], 37 }; 7 constructor(attrs, id) { 38 8 39 this.initText(); 40 } 9 if (!attrs.fromLoad) { 10 attrs.height *= 2; 11 } 12 super( 13 { 14 x: attrs.position.x, 15 y: attrs.position.y, 16 width: attrs.width, 17 height: attrs.height, 18 fill: "rgb(126,238,167)", 19 stroke: "#252627", 20 strokeWidth: 1, 21 opacity: 0.9, 22 name: "mapObj", 23 draggable: true, 24 rotation: attrs.rotation, 25 zIndex: 1, 26 }, 27 attrs.layer, 28 attrs.blockSize, 29 attrs.snap 30 ); 31 this.type = "Entrance"; 32 this.eventName = "openEntranceModalEvent"; 33 this.floorNum = attrs.floorNum 41 34 42 loadInfo(attrs) { 43 this.info.name = attrs.obj_name; 44 this.info.connectedRoom = attrs.connected_room; 45 this.info.description = attrs.description; 46 this.info.isMainEntrance = attrs.is_main_entrance; 47 this.info.selectedPins = attrs.connected_pins; 48 } 35 this.id = id; 49 36 50 saveShapeDetails() { 51 this.setAttr("connected_pins", this.info.selectedPins); 52 this.setAttr("obj_name", this.info.name); 53 this.setAttr("description", this.info.description); 54 this.setAttr("is_main_entrance", this.info.isMainEntrance); 55 this.setAttr("connected_room", this.info.connectedRoom); 56 } 37 this._info = { 38 name: `Entrance${id} [${this.floorNum}F]`, 39 connectedRoom: "", 40 description: "", 41 isMainEntrance: false, 42 selectedPin: "", 43 selectedPins: [], 44 }; 45 46 this.initText(); 47 this.moveToTop(); 48 } 49 50 loadInfo(attrs) { 51 this.info.name = attrs.obj_name; 52 this.info.connectedRoom = attrs.connected_room; 53 this.info.description = attrs.description; 54 this.info.isMainEntrance = attrs.is_main_entrance; 55 this.info.selectedPins = attrs.connected_pins; 56 this.floorNum = attrs.floor_num; 57 } 58 59 saveShapeDetails() { 60 console.info("fnum entrance",this.attrs.floorNum) 61 62 this.setAttr("connected_pins", this.info.selectedPins); 63 this.setAttr("obj_name", this.info.name); 64 this.setAttr("description", this.info.description); 65 this.setAttr("is_main_entrance", this.info.isMainEntrance); 66 this.setAttr("connected_room", this.info.connectedRoom); 67 this.setAttr("floor_num",this.floorNum); 68 } 69 70 connect(node, draw = true) { 71 if(this.floorNum !== node.floorNum) return; 72 73 super.connect(node) 74 } 75 76 setInfo(infoObj) { 77 console.log("SA VIKNA SETINFO") 78 this.info = infoObj; 79 if(this.info.connectedRoom == null || this.info.connectedRoom === "" ){ 80 this.strokeWidth(2); 81 this.stroke("#a10114") 82 }else{ 83 this.strokeWidth(1) 84 this.stroke("black") 85 } 86 } 57 87 } 58 88 -
imaps-frontend/src/scripts/shapes/InfoPin.js
rd565449 r0c6b92a 1 import Konva from "konva"; 2 import MapShape from "./MapShape"; 3 import Factory from "../util/Factory"; 1 4 2 import { _registerNode } from "konva/lib/Global"; 5 export default class InfoPin extends MapShape { 6 constructor(mousePos, blockSize, layer, snappable,id) { 3 import MapNode from "../base/MapNode.js"; 4 import {node} from "prop-types"; 5 import draw from "../../pages/Draw/Draw.jsx"; 6 export default class InfoPin extends MapNode { 7 constructor(attrs,id) { 8 attrs.snap = false; 7 9 super( 8 10 { 9 x: mousePos.x,10 y: mousePos.y,11 radiusX: blockSize * 0.5,12 radiusY: blockSize * 0.7,13 tailHeight: blockSize * 1.2,14 fill: "# d70113",11 x: attrs.position.x, 12 y: attrs.position.y, 13 radiusX: attrs.blockSize * 0.5, 14 radiusY: attrs.blockSize * 0.7, 15 tailHeight: attrs.blockSize * 1.2, 16 fill: "#f60000", 15 17 stroke: "#1b1b1b", 16 strokeWidth: 0.2,18 strokeWidth: 1, 17 19 draggable: true, 18 20 name: "mapObj", 19 21 }, 20 layer,21 blockSize,22 snappable22 attrs.layer, 23 attrs.blockSize, 24 attrs.snap 23 25 ); 24 26 25 27 this.id = id; 28 this.eventName = "openPinModalEvent"; 29 this.floorNum = attrs.floorNum; 26 30 27 this.modalEventName = "openPinModalEvent";28 31 this.type = "InfoPin"; 29 32 this._info = { 30 name: `Pin ${id}`,33 name: `Pin${id} [${this.floorNum}F]`, 31 34 selectedPins: [], 32 35 description: "", … … 34 37 35 38 this.on("mouseover", () => { 36 this.fill(" yellow");39 this.fill("#FFD700"); 37 40 }); 38 41 this.on("mouseout", () => { 39 this.fill(" red");42 this.fill("#f60000"); 40 43 }); 44 41 45 42 46 this.initText(); 43 47 } 44 48 _sceneFunc(context, shape) { 45 const { radiusX, radiusY, tailHeight } = this.attrs; 49 const { radiusX, radiusY, tailHeight } = this.attrs; // attrs od konva 46 50 47 51 context.beginPath(); … … 59 63 } 60 64 65 61 66 loadInfo(attrs) { 62 67 this.info.name = attrs.obj_name; 63 68 this.info.selectedPins = attrs.connected_pins; 64 69 this.info.description = attrs.description; 70 this.floorNum = attrs.floor_num 65 71 } 66 72 … … 69 75 this.setAttr("connected_pins", this.info.selectedPins); 70 76 this.setAttr("description", this.info.description); 77 this.setAttr("floor_num",this.floorNum) 71 78 console.log(this.info, "vnatre vo info"); 79 } 80 81 connect(node, draw = true) { 82 if(this.floorNum !== node.floorNum) return; 83 super.connect(node) 72 84 } 73 85 } -
imaps-frontend/src/scripts/shapes/Room.js
rd565449 r0c6b92a 1 1 import Konva from "konva"; 2 import MapShape from ". /MapShape";2 import MapShape from "../base/MapShape.js"; 3 3 import { _registerNode } from "konva/lib/Global"; 4 4 export default class Room extends MapShape { 5 constructor(mousePos, blockSize, layer, rotation, snap, id, scaleX = 1, scaleY = 1){ 5 constructor(attrs,id){ 6 7 if(!attrs.fromLoad){ 8 attrs.width *= 12; 9 attrs.height *= 8; 10 } 11 12 console.log(attrs.position,"hehe") 6 13 super( 7 14 { 8 x: mousePos.x,9 y: mousePos.y,10 width: blockSize * 8 *scaleX,11 height: blockSize * 4 *scaleY,12 fill: " #DDE0F8",15 x: attrs.position.x, 16 y: attrs.position.y, 17 width: attrs.width * attrs.scaleX, 18 height: attrs.height * attrs.scaleY, 19 fill: "rgb(86,168,253)", 13 20 stroke: "grey", 14 21 strokeWidth: 1, 15 22 name: "mapObj", 16 rotation: rotation,23 rotation: attrs.rotation, 17 24 draggable: true, 18 25 }, 19 layer,20 blockSize,21 snap26 attrs.layer, 27 attrs.blockSize, 28 attrs.snap 22 29 ); 23 30 31 this.floorNum = attrs.floorNum; 32 24 33 this._info = { 25 name: `Room ${id}`,34 name: `Room${id} [${this.floorNum}F]`, 26 35 type: "", 27 36 description: "", … … 29 38 30 39 this.type = "Room"; 31 this. modalEventName = "openRoomModalEvent";40 this.eventName = "openRoomModalEvent"; 32 41 this.id = id; 33 42 … … 39 48 this.info.type = attrs.room_type; 40 49 this.info.description = attrs.description; 50 this.floorNum = attrs.floor_num; 41 51 } 42 52 … … 45 55 this.setAttr("room_type", this.info.type); 46 56 this.setAttr("description", this.info.description); 57 this.setAttr("floor_num",this.floorNum); 47 58 } 48 59 } -
imaps-frontend/src/scripts/shapes/Stairs.js
rd565449 r0c6b92a 1 1 import Konva from "konva"; 2 import { MapShape } from "./MapShape"; 2 import MapNode from "../base/MapNode.js"; 3 import {_registerNode} from "konva/lib/Global.js"; 4 import Room from "./Room.js"; 5 export default class Stairs extends MapNode{ 6 constructor(attrs,id) { 3 7 8 if(!attrs.fromLoad){ 9 attrs.width *= 4; 10 } 11 12 super({ 13 x: attrs.position.x, 14 y: attrs.position.y, 15 width: attrs.width * attrs.scaleX, 16 height: attrs.height * attrs.scaleY, 17 fill: "rgb(225,213,124)", 18 stroke: "rgb(16,15,15)", 19 strokeWidth: 1, 20 name: "mapObj", 21 rotation: attrs.rotation, 22 draggable: true 23 }, 24 attrs.layer, 25 attrs.blockSize, 26 attrs.snap 27 ); 28 29 this.floorNum = attrs.floorNum; 30 31 this.type = "Stairs" 32 this._info = { 33 name: `Stairs${id} [${this.floorNum}F]`, 34 description: "", 35 selectedPins: [] 36 }; 37 38 this.id = id; 39 this.eventName = "openStairsModalEvent"; 40 this.initText(); 41 } 42 43 44 _sceneFunc(context, shape) { 45 const { width, height} = this.attrs; 46 47 let steps = 5; 48 context.beginPath() 49 for(let i = 0; i < steps; i++){ 50 context.rect((-this.blockSize) * i,(this.blockSize * 0.6) * i,width * 0.86,height/2) 51 context.fillStrokeShape(shape); 52 } 53 context.closePath() 54 } 55 56 loadInfo(attrs) { 57 this.info.name = attrs.obj_name; 58 this.info.description = attrs.description; 59 this.info.selectedPins = attrs.connected_pins; 60 this.floorNum = attrs.floor_num; 61 } 62 63 saveShapeDetails() { 64 this.setAttr("connected_pins", this.info.selectedPins); 65 this.setAttr("obj_name", this.info.name); 66 this.setAttr("description", this.info.description); 67 this.setAttr("floor_num",this.floorNum) 68 } 69 connect(node,draw = true) { 70 let canDraw = this.floorNum === node.floorNum; 71 super.connect(node,canDraw); 72 } 73 74 } 75 76 Stairs.prototype.className = "Stairs"; 77 _registerNode(Stairs); 4 78 //TODO -
imaps-frontend/src/scripts/shapes/Wall.js
rd565449 r0c6b92a 1 1 import Konva from "konva"; 2 import MapShape from ". /MapShape";2 import MapShape from "../base/MapShape.js"; 3 3 import { _registerNode } from 'konva/lib/Global'; 4 4 export default class Wall extends MapShape { 5 constructor(mousePos, blockSize, layer, rotation,snap, draggable = true,scaleX = 1, scaleY = 1){ 5 constructor(attrs){ 6 if(!attrs.fromLoad){ 7 attrs.height *= 8; 8 } 9 10 6 11 super( 7 12 { 8 x: mousePos.x,9 y: mousePos.y,10 width: blockSize *scaleX,11 height: blockSize * 8 *scaleY,12 fill: "# DDE0F8",13 x: attrs.position.x, 14 y: attrs.position.y, 15 width: attrs.width * attrs.scaleX, 16 height: attrs.height * attrs.scaleY, 17 fill: "#d3d3d3", 13 18 stroke: "grey", 14 19 strokeWidth: 1, 15 20 name: "mapObj", 16 draggable: draggable,17 rotation: rotation,21 draggable: true, 22 rotation: attrs.rotation, 18 23 zIndex: 0, 19 24 }, 20 layer,21 blockSize,22 snap,25 attrs.layer, 26 attrs.blockSize, 27 attrs.snap, 23 28 ); 24 25 29 this.type = "Wall"; 30 31 this.floorNum = attrs.floorNum; 26 32 } 27 } 33 34 loadInfo(attrs) { 35 this.floorNum = attrs.floor_num; 36 } 37 38 saveShapeDetails() { 39 this.setAttr("floor_num",this.floorNum) 40 } 41 } 28 42 29 43 Wall.prototype.className = 'Wall' -
imaps-frontend/src/scripts/util/Factory.js
rd565449 r0c6b92a 6 6 import RenderedEntrance from "../rendered_shapes/RenderedEntrance"; 7 7 import RenderedWall from "../rendered_shapes/RenderedWall.js"; 8 import Stairs from "../shapes/Stairs.js"; 9 import RenderedStairs from "../rendered_shapes/RenderedStairs.js"; 10 import {updateShapeCount, getShapeCount} from "./ShapeCount.js"; 8 11 export default class Factory { 12 // BUG KO KE NAPRES REFRESH SA RESETVAT COUNTS! 9 13 10 static infoPinCount = 0; 11 static wallCount = 0; 12 static entranceCount = 0; 13 static roomCount = 0; 14 static createShape(shapeType,attrs) { 15 console.log(attrs,"attrs in factory") 16 console.log("position in factory: " + attrs.position.x) 14 17 15 static createShape(shapeType, position, blockSize, layer, rotation,scaleX = 1, scaleY = 1, increment = false) { 18 let scaleX = (attrs.scaleX ? parseFloat(attrs.scaleX) : 1); 19 let scaleY = (attrs.scaleY ? parseFloat(attrs.scaleY) : 1); 20 21 attrs.scaleX = scaleX; 22 attrs.scaleY = scaleY; 23 16 24 switch (shapeType) { 17 25 case "Entrance": 18 if( increment) this.entranceCount++;19 return new Entrance( position, blockSize, layer, rotation,true,this.entranceCount,scaleX,scaleY);26 if(attrs.increment) updateShapeCount("entrance") 27 return new Entrance(attrs,getShapeCount("entrance")); 20 28 case "Room": 21 if(increment) this.roomCount++; 22 return new Room(position, blockSize, layer, rotation,true, this.roomCount,scaleX,scaleY); 23 case "Wall": 24 return new Wall(position, blockSize, layer, rotation,true,scaleX,scaleY); 25 case "InfoPin": 26 if(increment) this.infoPinCount++; 27 return new InfoPin(position, blockSize, layer, false,this.infoPinCount); 29 if(attrs.increment) updateShapeCount("room"); 30 return new Room(attrs,getShapeCount("room")); 31 case "Wall": 32 return new Wall(attrs); 33 case "InfoPin": 34 if(attrs.increment) updateShapeCount("infoPin") 35 return new InfoPin(attrs,getShapeCount("infoPin")); 36 case "Stairs": 37 if(attrs.increment) updateShapeCount("stairs") 38 return new Stairs(attrs,getShapeCount("stairs")) 28 39 default: 29 40 throw new Error("Invalid shape type: " + shapeType); … … 41 52 case "Wall": 42 53 return new RenderedWall(attrs,scaleX,scaleY); 54 case "Stairs": 55 return new RenderedStairs(attrs,scaleX,scaleY) 43 56 default: 44 57 throw new Error("Invalid shape type." + shapeType); -
imaps-frontend/src/scripts/util/zoomStage.js
rd565449 r0c6b92a 1 export const zoomStage = (e,stage ) => {2 if ( !e.evt.shiftKey) return;1 export const zoomStage = (e,stage,shift=false) => { 2 if (shift && !e.evt.shiftKey) return; 3 3 4 4 e.evt.preventDefault();
Note:
See TracChangeset
for help on using the changeset viewer.