Image Map?

by Sam Fereday

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/svg.js/2.4.0/svg.min.js"></script>
<div id="container"></div>
<div id="drawing"></div>
<img src="http://media.istockphoto.com/photos/piece-of-cheese-isolated-picture-id500454774?k=6&m=500454774&s=170667a&w=0&h=N0lcQ_dJRXfjvTmUsnGQyGmLRo4Si4jK35k8X113Nj4=" id="img" />

<button id="do">
  Make Grid
</button>
<button id="do-hide" class="hide">
  Hide Grid
</button>

CSS

html,
body {
  padding: 0;
  margin: 0;
}

div {
  box-sizing: border-box;
}

#drawing {
  position: absolute;
  left: 0;
  top: 0;
}

img {
  width: 100%;
  height: auto;
}

#container {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 99;
}

.row {
  width: 100%;
  clear: both;
  float: left;
}

.cell {
  width: 1px;
  height: 1px;
  float: left;
  background: rgba(33, 33, 33, 0.6);
}

.cell.active {
  background: #00EE00;
}

.cell:hover {
  background: #fff;
}

.hide {
  display: none;
}

JavaScript

// https://svgdotjs.github.io/
// w, h, scale (how big you want the cells to be in pixels)
// 217 is image width, so it should draw a new grid item cell at 6 pixels data-wise.
let cont = document.getElementById("container");
let img = document.getElementById("img");

let cellw = 6;
let cellh = 6;
let coords = [];

let Divvy = function(x, y, cw, ch, polygon) {
  this.x = x;
  this.y = y;
  this.el = document.createElement('div');
  this.el.style.width = cw + 'px';
  this.el.style.height = ch + 'px';
  this.el.className = 'cell';
  this.toggled = 1;
  let self = this;
  this.el.addEventListener('click', function(el) {
    self.toggled *= -1;
    self.el.className = self.toggled > 0 ? 'cell' : 'active cell';
    coords.push([x * cw, y * ch]);
    polygon.plot(coords);
  });
  return this.el;
}

// ...
document.getElementById("do").addEventListener('click', function() {

  var draw = SVG('drawing').size(img.clientWidth, img.clientHeight);
  var polygon = draw.polygon('0,0').fill('#fff').stroke({
    width: 3
  });

  polygon.on('mouseover', function() {
    let colour = '#f06';
    this.fill({
      color: colour
    });
  });

  polygon.on('mouseout', function() {
    let colour = '#fff';
    this.fill({
      color: colour
    });
  });

  // Number of cells it'd need to scale the image width and height
  let imgw = Math.floor(img.clientWidth / cellw);
  let imgh = Math.floor(img.clientHeight / cellh);

  for (var i = 0; i < imgh; i++) {

    let row = document.createElement('div');
    row.className = 'row';

    for (var j = 0; j < imgw; j++) {

      row.appendChild(new Divvy(j, i, cellw, cellh, polygon));

    }

    cont.appendChild(row);

  }

  this.className = 'hide';
  document.getElementById("do-hide").className = '';

});

let toggledGrid = 1;
document.getElementById("do-hide").addEventListener('click', function() {

  toggledGrid *= -1;
  cont.className = toggledGrid > 0 ? '' : 'hide';
  this.innerHTML = toggledGrid > 0 ? 'Hide Grid' : 'Show Grid';

});