123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707 |
- var ctx;
- var canvas;
- var lastX=0;
- var lastY=0;
- var dragStart = null;
- var dragged = false;
- var scaleFactor = 1.1;
- var roomSize = {width: 64, height: 64};
- var spacing = 32;
- var rooms = [
- {"id":0,"x":16,"y":16,"name":"temple"},
- {"id":1,"x":16,"y":112,"name":"street"},
- {"id":2,"x":112,"y":112,"name":"street"},
- {"id":3,"x":208,"y":112,"name":"street"},
- {"id":4,"x":208,"y":208,"name":"guild"},
- {"id":5,"x":304,"y":112,"name":"street"},
- {"id":6,"x":400,"y":112,"name":"street"},
- {"id":7,"x":208,"y":16,"name":"shop"},
- {"id":8,"x":112,"y":208,"name":"street"},
- {"id":9,"x":112,"y":304,"name":"old well"},
- {"id":10,"x":208,"y":304,"name":"bank"},
- {"id":11,"x":112,"y":400,"name":"post office"},
- {"id":12,"x":16,"y":304,"name":"street"},
- {"id":13,"x":16,"y":400,"name":"street"},
- {"id":14,"x":16,"y":496,"name":"street"},
- {"id":15,"x":16,"y":592,"name":"street"},
- {"id":16,"x":16,"y":688,"name":"south gate"},
- {"id":17,"x":-80,"y":304,"name":"street"},
- {"id":18,"x":-176,"y":304,"name":"street"},
- {"id":19,"x":-176,"y":400,"name":"cemetary"},
- {"id":21,"x":-176,"y":112,"name":"street"},
- {"id":23,"x":-368,"y":112,"name":"street"},
- {"id":24,"x":-464,"y":112,"name":"west gate"},
- {"id":25,"x":-368,"y":16,"name":"street"},
- {"id":26,"x":-272,"y":-80,"name":"street"},
- {"id":27,"x":-368,"y":-80,"name":"mikes"},
- {"id":28,"x":-176,"y":16,"name":"merchantrow"},
- {"id":29,"x":-80,"y":16,"name":"smithy"},
- {"id":30,"x":-80,"y":-80,"name":"forge"},
- {"id":31,"x":-176,"y":-80,"name":"armourer"},
- {"id":32,"x":-80,"y":112,"name":"street"},
- {"id":33,"x":-272,"y":112,"name":"street"},
- ];
- var loadedRooms = JSON.parse(localStorage.getItem("map-rooms"));
- if(loadedRooms != null) {
- rooms = loadedRooms;
- }
- var links = [
- {"start":0,"end":1,"exit":"s","enter":"n"},
- {"start":1,"end":2,"exit":"e","enter":"w"},
- {"start":3,"end":2,"exit":"w","enter":"e"},
- {"start":4,"end":3,"exit":"n","enter":"s"},
- {"start":3,"end":5,"exit":"e","enter":"w"},
- {"start":5,"end":6,"exit":"e","enter":"w"},
- {"start":3,"end":7,"exit":"n","enter":"s"},
- {"start":2,"end":8,"exit":"s","enter":"n"},
- {"start":8,"end":9,"exit":"s","enter":"n"},
- {"start":9,"end":10,"exit":"e","enter":"w"},
- {"start":9,"end":11,"exit":"s","enter":"n"},
- {"start":9,"end":12,"exit":"w","enter":"e"},
- {"start":12,"end":13,"exit":"s","enter":"n"},
- {"start":13,"end":14,"exit":"s","enter":"n"},
- {"start":14,"end":15,"exit":"s","enter":"n"},
- {"start":15,"end":16,"exit":"s","enter":"n"},
- {"start":12,"end":17,"exit":"w","enter":"e"},
- {"start":17,"end":18,"exit":"w","enter":"e"},
- {"start":18,"end":19,"exit":"s","enter":"n"},
- {"start":23,"end":24,"exit":"w","enter":"e"},
- {"start":23,"end":25,"exit":"n","enter":"s"},
- {"start":25,"end":26,"exit":"ne","enter":"sw"},
- {"start":25,"end":27,"exit":"n","enter":"s"},
- {"start":26,"end":28,"exit":"se","enter":"nw"},
- {"start":28,"end":29,"exit":"e","enter":"w"},
- {"start":29,"end":30,"exit":"n","enter":"s"},
- {"start":30,"end":31,"exit":"w","enter":"e"},
- {"start":31,"end":28,"exit":"s","enter":"n"},
- {"start":28,"end":21,"exit":"s","enter":"n"},
- {"start":21,"end":32,"exit":"e","enter":"w"},
- {"start":32,"end":29,"exit":"n","enter":"s"},
- {"start":32,"end":1,"exit":"e","enter":"w"},
- {"start":23,"end":33,"exit":"e","enter":"w"},
- {"start":33,"end":21,"exit":"e","enter":"w"},
- ];
- var loadedLinks = JSON.parse(localStorage.getItem("map-links"));
- if(loadedLinks != null) {
- links = loadedLinks;
- }
- var activeRoom = rooms[0];
- var movingRoom = false;
- var roomToMove = null;
- var moveLink = false;
- var linkToMove = null;
- function resizeCanvas() {
- // look up the size the canvas is being displayed
- const width = canvas.clientWidth;
- const height = canvas.clientHeight;
- // If its resolution does not match change it
- if (canvas.width !== width || canvas.height !== height) {
- canvas.width = width;
- canvas.height = height;
- return true;
- }
- return false;
- }
- function clearMap() {
- var p1 = ctx.transformedPoint(0,0);
- var p2 = ctx.transformedPoint(canvas.width,canvas.height);
- ctx.clearRect(p1.x,p1.y,p2.x-p1.x,p2.y-p1.y);
- ctx.save();
- ctx.setTransform(1,0,0,1,0,0);
- ctx.clearRect(0,0,canvas.width,canvas.height);
- ctx.restore();
- }
- function drawRoom(room) {
- if(room.id == activeRoom.id) {
- ctx.fillStyle = "#FFFFFF";
- } else {
- ctx.fillStyle = "#DDDDDD";
- }
- ctx.strokeStyle = "#000000";
- ctx.fillRect(room.x,room.y,roomSize.width,roomSize.height);
- ctx.strokeRect(room.x,room.y,roomSize.width,roomSize.height);
- ctx.fillStyle = "#000000";
- ctx.fillText(room.name, room.x + 5, room.y + 11);
- }
- function getRoomExit(room, direction) {
- var exit = {x:0, y:0};
- var exitOffset = {x:0, y:0};
- switch(direction) {
- case "n":
- exitOffset.x = roomSize.width / 2;
- exitOffset.y = 0;
- break;
- case "s":
- exitOffset.x = roomSize.width / 2;
- exitOffset.y = roomSize.height;
- break;
- case "e":
- exitOffset.x = roomSize.width;
- exitOffset.y = roomSize.height / 2;
- break;
- case "w":
- exitOffset.x = 0;
- exitOffset.y = roomSize.height / 2;
- break;
- case "nw":
- exitOffset.x = 0;
- exitOffset.y = 0;
- break;
- case "ne":
- exitOffset.x = roomSize.width;
- exitOffset.y = 0;
- break;
- case "sw":
- exitOffset.x = 0;
- exitOffset.y = roomSize.height;
- break;
- case "se":
- exitOffset.x = roomSize.width;
- exitOffset.y = roomSize.height;
- break;
- }
- exit.x = exitOffset.x + room.x;
- exit.y = exitOffset.y + room.y;
- return exit;
- }
- function getWiggle(start, end, exit, enter) {
- var wiggle = {start: {x: 0, y: 0}, end: {x:0, y:0}};
- switch(exit) {
- case "n":
- wiggle.start.x = -16;
- wiggle.start.y = -16;
- break;
- case "s":
- wiggle.start.x = -16;
- wiggle.start.y = 16;
- break;
- case "e":
- wiggle.start.x = 16;
- wiggle.start.y = -16;
- break;
- case "w":
- wiggle.start.x = -16;
- wiggle.start.y = -16;
- break;
- case "ne":
- wiggle.start.x = 0;
- wiggle.start.y = -16;
- break;
- case "nw":
- wiggle.start.x = 0;
- wiggle.start.y = -16;
- break;
- case "se":
- wiggle.start.x = 16;
- wiggle.start.y = 0;
- break;
- case "sw":
- wiggle.start.x = -16;
- wiggle.start.y = 0;
- break;
- }
- switch(enter) {
- case "n":
- wiggle.end.x = 16;
- wiggle.end.y = -16;
- break;
- case "s":
- wiggle.end.x = 16;
- wiggle.end.y = 16;
- break;
- case "e":
- wiggle.end.x = 16;
- wiggle.end.y = 16;
- break;
- case "w":
- wiggle.end.x = -16;
- wiggle.end.y = 16;
- break;
- case "ne":
- wiggle.end.x = 16;
- wiggle.end.y = 0;
- break;
- case "se":
- wiggle.end.x = 0;
- wiggle.end.y = 16;
- break;
- case "nw":
- wiggle.end.x = -16;
- wiggle.end.y = 0;
- break;
- case "sw":
- wiggle.end.x = 0;
- wiggle.end.y = 16;
- break;
- }
- return wiggle;
- }
- function getRoomById(roomId) {
- for(var roomIndex in rooms) {
- var room = rooms[roomIndex];
- if(room.id == roomId) {
- return room;
- }
- }
- }
- function drawLink(link, rooms) {
- var startRoom = getRoomById(link.start);
- var endRoom = getRoomById(link.end);
- if(startRoom == null || endRoom == null) {
- //TODO: delete link
- return;
- }
- var start = getRoomExit(startRoom, link.exit);
- var end = getRoomExit(endRoom, link.enter);
- var wiggle = getWiggle(start, end, link.exit, link.enter);
- ctx.beginPath();
- ctx.moveTo(start.x,start.y);
- ctx.bezierCurveTo(start.x+wiggle.start.x,start.y+wiggle.start.y,end.x+wiggle.end.x,end.y+wiggle.end.y,end.x,end.y);
- ctx.stroke();
- }
- function drawLinkToPoint(link, point) {
- var startRoom = getRoomById(link.start);
- var endRoom = getRoomById(link.end);
- if(startRoom == null || endRoom == null) {
- //TODO: delete link
- return;
- }
- var start = getRoomExit(startRoom, link.exit);
- var end = getRoomExit(endRoom, link.enter);
- var wiggle = getWiggle(start, end, link.exit, link.enter);
- ctx.beginPath();
- ctx.moveTo(start.x,start.y);
- ctx.bezierCurveTo(start.x+wiggle.start.x,start.y+wiggle.start.y,end.x+wiggle.end.x,end.y+wiggle.end.y,end.x,end.y);
- ctx.stroke();
- }
- function getOppositeDir(dir) {
- switch(dir) {
- case "n": return "s";
- case "s": return "n";
- case "e": return "w";
- case "w": return "e";
- case "ne": return "sw";
- case "nw": return "se";
- case "se": return "nw";
- case "sw": return "ne";
- case "u": return "d";
- case "d": return "u";
- }
- }
- function drawMap() {
- clearMap();
- rooms.map(room => drawRoom(room));
- links.map(link => drawLink(link, rooms));
- if(moveLink) {
- drawLink(linkToMove, rooms);
- }
- }
- function handleMouseDown(evt) {
- if(movingRoom) {
- movingRoom = false;
- localStorage.setItem("map-rooms", JSON.stringify(rooms));
- return;
- }
- if(moveLink && activeRoom.id != linkToMove.start) {
- moveLink = false;
- links.push(linkToMove);
- localStorage.setItem("map-links", JSON.stringify(links));
- return;
- }
- document.body.style.mozUserSelect = 'none';
- document.body.style.webkitUserSelect = 'none';
- document.body.style.userSelect = 'none';
- lastX = evt.offsetX || (evt.pageX - canvas.offsetLeft);
- lastY = evt.offsetY || (evt.pageY - canvas.offsetTop);
- dragStart = ctx.transformedPoint(lastX,lastY);
- dragged = false;
- }
- function checkRoomHover(room, mouseTransform) {
- if(mouseTransform.x >= room.x && mouseTransform.x <= room.x + roomSize.width &&
- mouseTransform.y >= room.y && mouseTransform.y <= room.y + roomSize.height)
- {
- setContextToRoom(room);
- drawMap();
- }
- }
- function handleMouseMove(evt) {
- if(movingRoom) {
- newX = evt.offsetX || (evt.pageX - canvas.offsetLeft);
- newY = evt.offsetY || (evt.pageY - canvas.offsetTop);
- var pt = ctx.transformedPoint(newX - (roomSize.width / 2),newY - (roomSize.height / 2));
- roomToMove.x = pt.x;
- roomToMove.y = pt.y;
- drawMap();
- return;
- }
- if(moveLink) {
- linkToMove.end = activeRoom.id;
- }
- setContextToWorld();
- var mouseTransform = ctx.transformedPoint(event.clientX, event.clientY);
- rooms.map(room => checkRoomHover(room, mouseTransform));
- lastX = evt.offsetX || (evt.pageX - canvas.offsetLeft);
- lastY = evt.offsetY || (evt.pageY - canvas.offsetTop);
-
- if (dragStart){
- dragged = true;
- var pt = ctx.transformedPoint(lastX,lastY);
- ctx.translate(pt.x-dragStart.x,pt.y-dragStart.y);
- drawMap();
- }
- hideContextMenu();
- }
- function handleMouseUp(evt) {
- dragStart = null;
- dragged = false;
- }
- function zoomMap(clicks){
- var pt = ctx.transformedPoint(lastX,lastY);
- ctx.translate(pt.x,pt.y);
- var factor = Math.pow(scaleFactor,clicks);
- ctx.scale(factor,factor);
- ctx.translate(-pt.x,-pt.y);
- drawMap();
- }
- function handleScroll(evt){
- var delta = evt.wheelDelta ? evt.wheelDelta/40 : evt.detail ? -evt.detail : 0;
- if (delta) {
- zoomMap(delta);
- }
- return evt.preventDefault() && false;
- };
- function showContextMenu(x, y) {
- var menu = document.getElementsByClassName("context-menu-container")[0];
- menu.style.display="block";
- menu.style.top = y-15 + "px";
- menu.style.left = x-15 + "px";
- }
- function hideContextMenu() {
- var menu = document.getElementsByClassName("context-menu-container")[0];
- menu.style.display="none";
- }
- function setContextToWorld() {
- document.getElementById("world-menu").style.display= "block";
- document.getElementById("room-menu").style.display= "none";
- }
- function setContextToRoom(room) {
- activeRoom = room;
- document.getElementById("world-menu").style.display= "none";
- var roomMenu = document.getElementById("room-menu");
- roomMenu.style.display= "block";
- roomMenu.getElementsByClassName("title")[0].innerHTML = room.name;
- }
- function handleContextMenu(event) {
- event.preventDefault();
- showContextMenu(event.clientX, event.clientY);
- dragStart = null;
- dragged = false;
- }
- function handleResize(event) {
- var canvas = document.getElementById("mapper");
- var ctx = canvas.getContext("2d");
- ctx.setTransform(1,0,0,1,0,0);
- resizeCanvas();
- drawMap();
- }
- function setActiveRoom(input) {
- for(var linkId in links) {
- var link = links[linkId];
- if(activeRoom.id == link.start && input == link.exit) {
- activeRoom = getRoomById(link.end);
- return true;
- }
- if(activeRoom.id == link.end && input == link.enter) {
- activeRoom = getRoomById(link.start);
- return true;
- }
- }
- return false;
- }
- function getNewRoomIndex() {
- var newIndex = 0;
- for(var roomId in rooms) {
- if(rooms[roomId].id > newIndex) {
- newIndex = rooms[roomId].id;
- }
- }
- return newIndex + 1;
- }
- function setOrCreateActiveRoom(input) {
- if(setActiveRoom(input)) {
- return;
- }
- var newRoom = {id: getNewRoomIndex(), x: activeRoom.x, y: activeRoom.y, name:"newroom"};
- if(input.indexOf("n") != -1) {
- newRoom.y = activeRoom.y - (spacing + roomSize.height);
- }
- if(input.indexOf("s") != -1) {
- newRoom.y = activeRoom.y + (spacing + roomSize.height);
- }
- if(input.indexOf("w") != -1) {
- newRoom.x = activeRoom.x - (spacing + roomSize.width);
- }
- if(input.indexOf("e") != -1) {
- newRoom.x = activeRoom.x + (spacing + roomSize.width);
- }
- rooms.push(newRoom);
- links.push({start:activeRoom.id, end:newRoom.id, exit:input, enter:getOppositeDir(input)})
- activeRoom = newRoom;
- localStorage.setItem("map-rooms", JSON.stringify(rooms));
- localStorage.setItem("map-links", JSON.stringify(links));
- }
- function keyboardListener(event) {
- var key = event.keyCode;
- switch(key) {
- case 78:
- inputBuffer = "n";
- break;
- case 83:
- inputBuffer = "s";
- break;
- case 69:
- inputBuffer += "e";
- break;
- case 87:
- inputBuffer += "w";
- break;
- case 38:
- setActiveRoom("n");
- inputBuffer = "";
- break;
- case 40:
- setActiveRoom("s");
- inputBuffer = "";
- break;
- case 39:
- setActiveRoom("e");
- inputBuffer = "";
- break;
- case 37:
- setActiveRoom("w");
- inputBuffer = "";
- break;
- case 13:
- if(inputBuffer != "") {
- setOrCreateActiveRoom(inputBuffer);
- }
- inputBuffer = "";
- break;
- default:
- inputBuffer = "";
- console.warn("Unhandled keypress: ", key);
- break;
- }
-
- drawMap();
- }
- function showModal(modalId) {
- var modal = document.getElementById(modalId);
- modal.parentNode.style.display = "block";
- modal.style.display = "block";
- }
- function closeModal(modalId) {
- var modal = document.getElementById(modalId);
- modal.parentNode.style.display = "none";
- modal.style.display = "none";
- }
- window.addEventListener("resize", handleResize, false);
- document.addEventListener("DOMContentLoaded", function(event) {
- document.getElementById("reset-view").addEventListener('click', function(event) {
- var canvas = document.getElementById("mapper");
- var ctx = canvas.getContext("2d");
- ctx.setTransform(1,0,0,1,0,0);
- lastX=canvas.width/2;
- lastY=canvas.height/2;
- hideContextMenu();
- resizeCanvas();
- drawMap();
- });
- document.getElementById("delete-room").addEventListener('click', function(event) {
- var roomToDelete = rooms.indexOf(activeRoom);
- rooms.splice(roomToDelete, 1);
- for(var linkId = links.length - 1; linkId >= 0; linkId--) {
- var link = links[linkId];
- if(activeRoom.id == link.start || activeRoom.id == link.end) {
- links.splice(linkId, 1);
- }
- }
- localStorage.setItem("map-rooms", JSON.stringify(rooms));
- localStorage.setItem("map-links", JSON.stringify(links));
- hideContextMenu();
- drawMap();
- });
- document.getElementById("rename-room").addEventListener('click', function(event) {
- var newName = prompt("Please enter the new room name:", activeRoom.name);
- activeRoom.name = newName;
- localStorage.setItem("map-rooms", JSON.stringify(rooms));
- localStorage.setItem("map-links", JSON.stringify(links));
- hideContextMenu();
- drawMap();
- });
- document.getElementById("move-room").addEventListener('click', function(event) {
- movingRoom = true;
- roomToMove = activeRoom;
- hideContextMenu();
- drawMap();
- });
- var modalCloseButtons = document.getElementsByClassName("modal-close");
- for(var i = 0; i < modalCloseButtons.length; i++) {
- modalCloseButtons[i].addEventListener("click", function(event) {
- this.parentNode.style.display = "none";
- this.parentNode.parentNode.style.display = "none";
- });
- }
- document.getElementById("manage-links").addEventListener('click', function(event) {
- var modal = document.getElementById("link-editor-modal");
- modal.style.display = "block";
- modal.parentNode.style.display = "block";
- hideContextMenu();
- });
- document.getElementById("add-link").addEventListener('click', function(event) {
- var linkSourceId = activeRoom.id;
- moveLink = true;
- var exitDir = prompt("Please enter the exit direction (n, s, e, w):");
- var oppositeDir = getOppositeDir(exitDir);
- linkToMove = {start:linkSourceId, end:null, exit:exitDir, enter:oppositeDir};
- hideContextMenu();
- });
- document.getElementById("export-map").addEventListener('click', function(event) {
- showModal("export-modal");
- var exportData = {"rooms": rooms, "links": links, "version": 1};
- var exportText = JSON.stringify(exportData);
- var exportField = document.getElementById("export-text");
- exportField.value = btoa(exportText);
-
- hideContextMenu();
- });
- document.getElementById("import-map").addEventListener('click', function(event) {
- showModal("import-modal");
- document.getElementById("import-text").value = "";
- hideContextMenu();
- });
- document.getElementById("load-import-data").addEventListener("click", function(event) {
- var newData = document.getElementById("import-text").value;
- var potentialLoad = null;
- try {
- potentialLoad = JSON.parse(atob(newData));
- } catch (exception) {
- console.error("Invalid import data", exception);
- }
- if(potentialLoad != null) {
- rooms = potentialLoad.rooms;
- links = potentialLoad.links;
- localStorage.setItem("map-rooms", JSON.stringify(rooms));
- localStorage.setItem("map-links", JSON.stringify(links));
- drawMap();
- closeModal("import-modal");
- }
- });
- canvas = document.getElementById("mapper");
- canvas.addEventListener('mousedown',handleMouseDown,false);
- canvas.addEventListener('mousemove',handleMouseMove,false);
- canvas.addEventListener('mouseup',handleMouseUp, false);
- canvas.addEventListener('DOMMouseScroll',handleScroll,false);
- canvas.addEventListener('mousewheel',handleScroll,false);
- canvas.addEventListener('contextmenu', handleContextMenu, false);
-
- ctx = canvas.getContext('2d');
- attachTransforms(ctx);
- lastX=canvas.width/2;
- lastY=canvas.height/2;
- resizeCanvas();
- drawMap();
- });
- var inputBuffer = "";
- window.addEventListener("keydown", keyboardListener);
|