summaryrefslogtreecommitdiff
path: root/public
diff options
context:
space:
mode:
Diffstat (limited to 'public')
-rw-r--r--public/dye.html83
-rw-r--r--public/js/mp/dye.js30
-rw-r--r--public/js/mp/resource.js35
-rw-r--r--public/playground.html13
4 files changed, 149 insertions, 12 deletions
diff --git a/public/dye.html b/public/dye.html
new file mode 100644
index 0000000..f7ca177
--- /dev/null
+++ b/public/dye.html
@@ -0,0 +1,83 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Dyer</title>
+ <style type="text/css">
+ .viewport {
+ border:solid 1px #000000;
+ display: inline-block;
+ height: 400px;
+ overflow: scroll;
+ width: 600px;
+ }
+ </style>
+ <script src="js/mp/dye.js"></script>
+ <script src="js/mp/resource.js"></script>
+ </head>
+ <body>
+ <div class="viewport" dropzone="link" ondrop="dyeDrop(event);" ondragover="event.preventDefault();">
+ <canvas id="dyeCanvas"></canvas>
+ </div>
+ <div class="viewport" dropzone="link" ondrop="referenceDrop(event);" ondragover="event.preventDefault();"></div>
+
+ <div style="display: none" >
+ <canvas id="rawCanvas"></canvas>
+ </div>
+
+ <div><input type="text" id="dyeStringInput" size="100"/><button onclick="applyDye(event);">Apply</button></div>
+
+ <script>
+ var dyeCanvas = document.getElementById("dyeCanvas"),
+ dyeStringInput = document.getElementById("dyeStringInput");
+
+ var loadedImage = null;
+
+ function applyDye(event) {
+ if (loadedImage == null) {
+ return;
+ }
+
+ var ctx = dyeCanvas.getContext("2d");
+ ctx.clearRect(0, 0, dyeCanvas.width, dyeCanvas.height);
+ var clone = mp.resource.copyImageData(ctx, loadedImage);
+ mp.dye.dyeImage(clone.data, mp.dye.parseDyeString(dyeStringInput.value));
+ ctx.putImageData(clone, 0, 0);
+ }
+
+ function dyeDrop(event) {
+ event.stopPropagation();
+ event.preventDefault();
+ var file = event.dataTransfer.files[0],
+ reader = new FileReader();
+ reader.onload = function (event) {
+ mp.resource.loadImage(event.target.result, function(err, imageData) {
+ if (!err) {
+ loadedImage = imageData;
+ dyeCanvas.width = loadedImage.width;
+ dyeCanvas.height = loadedImage.height;
+ applyDye(null);
+ }
+ });
+ };
+ reader.readAsDataURL(file);
+
+ return false;
+ }
+
+ function referenceDrop(event) {
+ event.stopPropagation();
+ event.preventDefault();
+ var file = event.dataTransfer.files[0],
+ reader = new FileReader();
+ reader.onload = function (event) {
+ var img = new Image();
+ img.src = event.target.result;
+ referenceViewport.innerHTML = '';
+ referenceViewport.appendChild(img);
+ };
+ reader.readAsDataURL(file);
+ return false;
+ }
+ </script>
+ </body>
+</html>
diff --git a/public/js/mp/dye.js b/public/js/mp/dye.js
index 7cf8da5..e7af938 100644
--- a/public/js/mp/dye.js
+++ b/public/js/mp/dye.js
@@ -5,7 +5,12 @@ var mp = function(mp) {
parseDyeString: parseDyeString,
dyeImage: dyeImage
};
+
var channel = [null, "R", "G", "Y", "B", "M", "C", "W"];
+
+ /*
+ * Return the channel and intensity for the given RGB(A) array.
+ */
function getChannel(color) {
var r = color[0], g = color[1], b = color[2],
max = Math.max(r, g, b);
@@ -28,12 +33,35 @@ var mp = function(mp) {
return { channel: channel[idx], intensity: max };
}
+
/*
* Return a dye specification from a dye string.
*/
function parseDyeString(dyeString) {
- /* TODO */
+ var channelStrings = dyeString.split("|");
+ var dyeData = {};
+
+ for (var i = 0; i < channelStrings.length; i++) {
+ var channelStr = channelStrings[i];
+ if (channelStr[1] != ":" || channelStr[2] != "#") {
+ // TODO error
+ }
+
+ var channel = channelStr[0];
+ var parts = channelStr.substring(3).split(",");
+
+ var list = [];
+
+ for (var j = 0; j < parts.length; j++) {
+ list.push(mp.resource.parseColor(parts[j]));
+ }
+
+ dyeData[channel] = list;
+ }
+
+ return dyeData;
}
+
/*
* Dye the internal image data based on the specification provided by dyeData.
* The specification can be generated from a dyeString by parseDyeString.
diff --git a/public/js/mp/resource.js b/public/js/mp/resource.js
index f348a89..406222a 100644
--- a/public/js/mp/resource.js
+++ b/public/js/mp/resource.js
@@ -1,7 +1,9 @@
"use strict";
var mp = function(mp) {
mp.resource = {
- loadImage: loadImage
+ loadImage: loadImage,
+ copyImageData: copyImageData,
+ parseColor: parseColor
};
/*
@@ -32,5 +34,36 @@ var mp = function(mp) {
};
image.src = url;
}
+
+ function copyImageData(ctx, src) {
+ var dst = ctx.createImageData(src.width, src.height);
+ dst.data.set(src.data);
+ return dst;
+ }
+
+ /*
+ * Parses the given color string into an array of parts
+ */
+ function parseColor(colorString) {
+ if (colorString[0] == "#") {
+ colorString = colorString.substring(1);
+ }
+
+ if (colorString.length == 3) {
+ var r = colorString[0] + colorString[0];
+ var g = colorString[1] + colorString[1];
+ var b = colorString[2] + colorString[2];
+ return [parseInt(r, 16), parseInt(g, 16), parseInt(b, 16)]
+ }
+
+ if (colorString.length == 6) {
+ return [parseInt(colorString.substring(0,2), 16), parseInt(colorString.substring(2,4), 16), parseInt(colorString.substring(4,6), 16)]
+ }
+
+ // TODO others?
+
+ return null;
+ }
+
return mp;
}(mp || {});
diff --git a/public/playground.html b/public/playground.html
index 3099b83..10ac6c2 100644
--- a/public/playground.html
+++ b/public/playground.html
@@ -11,16 +11,9 @@
<script src="js/mp/dye.js"></script>
<script src="js/mp/resource.js"></script>
<script>
-var dyeData = {
- "R": [
- [0xed, 0xe5, 0xb2],
- [0xff, 0xf7, 0xbf]
- ],
- "G": [
- [0xcc, 0xcc, 0xcc],
- [0xff, 0xff, 0xff]
- ]
-};
+var dyeString = "R:#ede5b2,fff7bf|G:#cccccc,ffffff";
+var dyeData = mp.dye.parseDyeString(dyeString);
+
mp.resource.loadImage("bigcake.png", function(err, imageData) {
var oContext = document.getElementById("original").getContext("2d");
var dContext = document.getElementById("dyed").getContext("2d");