40k Map - Draggable Canvas

Interactive map idea with a draggable canvas and some locations as examples

by Michelle-Louise Janion

HTML

<div id="map">
  <div class="map-canvas"></div>
</div>

CSS

* {
  /* to remove the top and left whitespace */
  margin: 0;
  padding: 0;
}

html,
body {
  /* just to be sure these are full screen*/
  width: 100%;
  height: 100%;
}

canvas {
  /* To remove the scrollbars */
  display: block;
}

#map {
  position: relative;
  overflow: hidden;
}

.map-canvas {
  position: absolute;
  background: black url(http://jambonium.co.uk/40kmap/images/map_background.png) no-repeat;
  background-size: 100% 100%;
  width: 2904px;
  height: 1687px;
}

#map .ui-draggable-dragging {
  cursor: -moz-grabbing;
  cursor: -webkit-grabbing;
  cursor: grabbing;
}

.map-marker {
  width: 0px;
  height: 0px;
  -moz-border-radius: 2px;
  border-radius: 3px;
  overflow: visible;
  color: #fff;
  font-size: 85%;
}

.imperial {
  background-color: blue;
  border: 3px solid blue;
}

.chaos {
  background-color: red;
  border: 3px solid red;
}

.tau {
  background-color: yellow;
  border: 3px solid yellow;
}

.ork {
  background-color: green;
  border: 3px solid green;
}

.eldar {
  background-color: turquoise;
  border: 3px solid turquoise;
}

.darkeldar {
  background-color: maroon;
  border: 3px solid maroon;
}

.exodite {
  background-color: cyan;
  border: 3px solid cyan;
}

.necron {
  background-color: grey;
  border: 3px solid grey;
}

.webway {
  background-color: pink;
  border: 3px solid pink;
}

.dead {
  background-color: brown;
  border: 3px solid brown;
}

.death {
  background-color: black;
  border: 3px solid black;
}

.other {
  background-color: magenta;
  border: 3px solid magenta;
}

.unknown {
  background-color: white;
  border: 3px solid white;
}

.feature {
  font-size: 115%;
  font-style: italic;
}

.area {
  font-size: 155%;
  font-weight: bold;
  font-style: italic;
}

.segmentum {
  font-size: 250%;
  font-weight: bold;
}

.map-marker p {
  position: absolute;
  top: -10px;
  left: 10px;
  width: 350px;
}

.map-marker p span {
  font-style: italic;
}

JavaScript

// Pre-select elements
var map = $("#map"),
  canvas = map.find(".map-canvas");

// Sets canvas to be 100% width and 100% height
map.css("width", window.innerWidth);
map.css("height", window.innerHeight);

// Calculate canvas constraints
var maxLeft = map.width() - canvas.width(),
  maxTop = map.height() - canvas.height();

// Make canvas draggable
canvas.draggable({
  drag: function(e, ui) {
    // Check if canvas is within constraints
    if (ui.position.left > 0) {
      ui.position.left = 0;
    } else if (ui.position.left < maxLeft) {
      ui.position.left = maxLeft;
    }
    if (ui.position.top > 0) {
      ui.position.top = 0;
    } else if (ui.position.top < maxTop) {
      ui.position.top = maxTop;
    }
  }
});



// Jagga
$("<div></div>")
  .addClass("map-marker")
  .addClass("ork")
  .appendTo(canvas)
  .offset(function() {
    return {
      left: 1463,
      top: 784
    };
  })
  
  .append("<p>Jagga</p>");

// Shaa-dom
$("<div></div>")
  .addClass("map-marker")
  .addClass("webway")
  .appendTo(canvas)
  .offset(function() {
    return {
      left: 643,
      top: 785
    };
  })
  
  .append("<p>Shaa-dom</p>");

// Telias
$("<div></div>")
  .addClass("map-marker")
  .addClass("unknown")
  .appendTo(canvas)
  .offset(function() {
    return {
      left: 145,
      top: 40
    };
  })
  
  .append("<p>Telias</p>");

// Deluge
$("<div></div>")
  .addClass("map-marker")
  .addClass("death")
  .appendTo(canvas)
  .offset(function() {
    return {
      left: 54,
      top: 104
    };
  })
  
  .append("<p>Deluge</p>");

// XD-777
$("<div></div>")
  .addClass("map-marker")
  .addClass("other")
  .appendTo(canvas)
  .offset(function() {
    return {
      left: 150,
      top: 90
    };
  })
  
  .append("<p>XD-777</p>");

// Orbiana
$("<div></div>")
  .addClass("map-marker")
  .addClass("imperial")
  .appendTo(canvas)
  .offset(function() {
    return {
      left: 200,
      top: 22
    };
  })
  
  .append("<p>Orbiana</p>");

//...