Browse Source

Super rough, initial version

master
commit
054ea6ef5f
17 changed files with 258 additions and 0 deletions
  1. +3
    -0
      .gitignore
  2. +13
    -0
      package.json
  3. +29
    -0
      public/css/main.css
  4. BIN
      public/img/default-map.png
  5. BIN
      public/img/eraser-big.png
  6. BIN
      public/img/eraser.png
  7. BIN
      public/img/pencil-big.png
  8. BIN
      public/img/pencil.png
  9. BIN
      public/img/rectangle-big.png
  10. BIN
      public/img/rectangle.png
  11. BIN
      public/img/transparency-big.png
  12. BIN
      public/img/transparency.png
  13. +32
    -0
      public/index.html
  14. +45
    -0
      src/Toolbox.js
  15. +71
    -0
      src/map-discoverer.js
  16. +44
    -0
      src/tools/PencilTool.js
  17. +21
    -0
      src/tools/RectangleTool.js

+ 3
- 0
.gitignore View File

@@ -0,0 +1,3 @@
node_modules/
npm-debug.log
public/js/

+ 13
- 0
package.json View File

@@ -0,0 +1,13 @@
{
"name": "map-discoverer",
"version": "0.0.1",
"description": "A small web application to 'discover' maps",
"author": "Esteban Manchado Velázquez <emanchado@demiurgo.org>",
"scripts": {
"watch": "babel -w --modules ignore -o public/js/map-discoverer.js src"
},
"devDependencies": {
"babel": "^5.8.23"
},
"license": "MIT"
}

+ 29
- 0
public/css/main.css View File

@@ -0,0 +1,29 @@
body {
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
}

fieldset {
display: inline-block;
}

#map-loader {
float: right;
}

#map-container {
margin-top: 2ex;
}

#orig-map {
position: relative;
top: 0;
left: 0;
}

#overlay {
position: absolute;
top: 0;
left: 0;

opacity: 0.7;
}

BIN
public/img/default-map.png View File

Before After
Width: 599  |  Height: 470  |  Size: 178KB

BIN
public/img/eraser-big.png View File

Before After
Width: 64  |  Height: 64  |  Size: 728B

BIN
public/img/eraser.png View File

Before After
Width: 20  |  Height: 20  |  Size: 399B

BIN
public/img/pencil-big.png View File

Before After
Width: 64  |  Height: 64  |  Size: 807B

BIN
public/img/pencil.png View File

Before After
Width: 20  |  Height: 20  |  Size: 367B

BIN
public/img/rectangle-big.png View File

Before After
Width: 64  |  Height: 64  |  Size: 270B

BIN
public/img/rectangle.png View File

Before After
Width: 20  |  Height: 20  |  Size: 225B

BIN
public/img/transparency-big.png View File

Before After
Width: 64  |  Height: 64  |  Size: 1.1KB

BIN
public/img/transparency.png View File

Before After
Width: 20  |  Height: 20  |  Size: 460B

+ 32
- 0
public/index.html View File

@@ -0,0 +1,32 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Map discoverer</title>
<link rel="stylesheet" href="css/main.css" type="text/css" media="screen" />
</head>

<body>
<div id="top-header">
<div id="map-loader">
New map: <input type="file" id="new-map-file" />
</div>

<div id="tools">
<button id="toggle-transparency-btn"><img src="img/transparency.png" alt="" /> Toggle transparency</button>
<button id="show-hide-btn" data-mode="uncover"><img src="img/eraser.png" alt="" /> <span id="show-hide-btn-text">Uncover Mode</span></button>
</div>
</div>

<div id="map-container" style="position: relative; left: 0; top: 0;">
<img src="img/default-map.png" id="orig-map" alt="Original Map" />
<canvas id="overlay">
You need a browser which understands &lt;canvas&gt;
</canvas>
</div>

<div>Icons made by <a href="http://www.freepik.com" title="Freepik">Freepik</a> from <a href="http://www.flaticon.com" title="Flaticon">www.flaticon.com</a> is licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0">CC BY 3.0</a></div>

<script type="text/javascript" src="js/map-discoverer.js"></script>
</body>
</html>

+ 45
- 0
src/Toolbox.js View File

@@ -0,0 +1,45 @@
export class Toolbox {
constructor(canvas, toolList) {
this.canvas = canvas;
if (!toolList.length) {
throw new Error("Need at least one tool!");
}
this.tools = [];
for (let toolClass of toolList) {
let tool = new toolClass(this.canvas);
this.createToolButton(tool);
this.tools.push(tool);
}
this.currentTool = this.tools[0];

this.canvas.addEventListener("mousedown", evt => {
this.currentTool.onStart(evt);
}, false);
this.canvas.addEventListener("mouseup", evt => {
this.currentTool.onStop(evt);
}, false);
this.canvas.addEventListener("mousemove", evt => {
this.currentTool.onMove(evt);
}, false);
}

createToolButton(tool) {
let toolClass = tool.constructor,
toolsDiv = document.getElementById("tools"),
buttonDomEl = document.createElement("button"),
toolIconEl = document.createElement("img"),
self = this;

buttonDomEl.id = toolClass.name.toLowerCase() + "-btn";
toolIconEl.src = "img/" + toolClass.img;
toolIconEl.alt = "";

buttonDomEl.appendChild(toolIconEl);
buttonDomEl.appendChild(document.createTextNode(" " + toolClass.title));
buttonDomEl.addEventListener("click", function () {
self.currentTool = tool;
}, false);

toolsDiv.appendChild(buttonDomEl);
}
}

+ 71
- 0
src/map-discoverer.js View File

@@ -0,0 +1,71 @@
// In stopTool a snapshot of the current canvas would be taken, for
// undo purposes. Add undo option.

// Add UI hints, like the size of the current rectangle. Change the
// cursor shape.

// Add size of pencil.

import PencilTool from "tool/PencilTool";
import RectangleTool from "tool/RectangleTool";
import Toolbox from "Toolbox";

function loadImage(imgEl, canvasEl, imageUrl) {
imgEl.style.visibility = "hidden";
imgEl.src = imageUrl;

canvasEl.height = imgEl.height;
canvasEl.width = imgEl.width;
let ctx = canvasEl.getContext('2d');
ctx.fillRect(0, 0, canvasEl.width, canvasEl.height);
ctx.globalCompositeOperation = "destination-out";
let showHideBtn = document.getElementById("show-hide-btn"),
showHideBtnText = document.getElementById("show-hide-btn-text");
showHideBtnText.textContent = 'Uncover Mode';
showHideBtn.dataset.mode = 'uncover';
let overlay = document.getElementById("overlay");
overlay.style.opacity = "";

imgEl.style.visibility = "";
}

window.addEventListener("load", function(/*e*/) {
let mapImg = document.getElementById("orig-map"),
canvas = document.getElementById("overlay"),
ctx = canvas.getContext('2d'),
toolbox = new Toolbox(canvas, [PencilTool, RectangleTool]);

loadImage(mapImg, canvas, "img/default-map.png");
document.getElementById("new-map-file").addEventListener("change", evt => {
let file = evt.target.files[0];
let reader = new FileReader();
reader.onload = evt => {
loadImage(mapImg, canvas, evt.target.result);
};
reader.readAsDataURL(file);
}, false);

let toggleBtn = document.getElementById("toggle-transparency-btn"),
overlay = document.getElementById("overlay");
toggleBtn.addEventListener("click", function(/*e*/) {
if (overlay.style.opacity) {
overlay.style.opacity = "";
} else {
overlay.style.opacity = "1";
}
});

let showHideBtn = document.getElementById("show-hide-btn"),
showHideBtnText = document.getElementById("show-hide-btn-text");
showHideBtn.addEventListener("click", function(/*e*/) {
if (showHideBtn.dataset.mode === 'uncover') {
showHideBtnText.textContent = 'Cover Mode';
showHideBtn.dataset.mode = 'cover';
ctx.globalCompositeOperation = "source-over";
} else {
showHideBtnText.textContent = 'Uncover Mode';
showHideBtn.dataset.mode = 'uncover';
ctx.globalCompositeOperation = "destination-out";
}
});
}, false);

+ 44
- 0
src/tools/PencilTool.js View File

@@ -0,0 +1,44 @@
export class PencilTool {
constructor(canvas) {
this.ctx = canvas.getContext('2d');
this.started = false;
}

onStart({offsetX, offsetY}) {
this.started = true;

this.ctx.fillStyle = "rgba(0,0,0,1)";
this.ctx.beginPath();
this.ctx.arc(offsetX,
offsetY,
20,
(Math.PI/180)*0,
(Math.PI/180)*360,
false);
this.ctx.fill();
this.ctx.closePath();
}

onMove({offsetX, offsetY}) {
if (!this.started) {
return;
}

this.ctx.fillStyle = "rgba(0,0,0,1)";
this.ctx.beginPath();
this.ctx.arc(offsetX,
offsetY,
20,
(Math.PI/180)*0,
(Math.PI/180)*360,
false);
this.ctx.fill();
this.ctx.closePath();
}

onStop(/*evt*/) {
this.started = false;
}
}
PencilTool.title = "Pencil Tool";
PencilTool.img = "pencil.png";

+ 21
- 0
src/tools/RectangleTool.js View File

@@ -0,0 +1,21 @@
export class RectangleTool {
constructor(canvas) {
this.ctx = canvas.getContext('2d');
}

onStart({offsetX, offsetY}) {
[this.initialX, this.initialY] = [offsetX, offsetY];
}

onMove(/*evt*/) {}

onStop({offsetX, offsetY}) {
this.ctx.beginPath();
this.ctx.rect(this.initialX, this.initialY,
offsetX - this.initialX, offsetY - this.initialY);
this.ctx.fill();
this.ctx.stroke();
}
}
RectangleTool.title = "Rectangle Tool";
RectangleTool.img = "rectangle.png";

Loading…
Cancel
Save