JSFiddle - React, Tailwind, and code Playground
HTML
<script src="http://www.play-crafts.com/blog/wp-includes/js/quantize.js"></script>
<script src="http://www.play-crafts.com/blog/wp-includes/js/colorutils.js"></script>
<canvas id="UIframe" width=700 height=500>
Your browser does not support this application. Please update your browser or try a different browser.
</canvas>
<div id="paletteCircles">
<div id="circle0" class="circle"></div>
<div id="circle1" class="circle"></div>
<div id="circle2" class="circle"></div>
<div id="circle3" class="circle"></div>
<div id="circle4" class="circle"></div>
<div id="circle5" class="circle"></div>
<div id="circle6" class="circle"></div>
<div id="circle7" class="circle"></div>
</div>
<div id="paletteFrame" style="width:740px; height:105px">
<div id="palette1" class="palette"></div>
<div id="buffer1" class="buffer"></div>
<div id="palette2" class="palette"></div>
<div id="buffer2" class="buffer"></div>
<div id="palette3" class="palette"></div>
<div id="buffer3" class="buffer"></div>
<div id="palette4" class="palette"></div>
<div id="buffer4" class="buffer"></div>
<div id="palette5" class="palette"></div>
<div id="buffer5" class="buffer"></div>
<div id="palette6" class="palette"></div>
<div id="buffer6" class="buffer"></div>
<div id="palette7" class="palette"></div>
<div id="buffer7" class="buffer"></div>
<div id="palette8" class="palette"></div>
<div id="buffer8" class="buffer"></div>
<div id="paletteUI" class="button lime newcolor"><strong>+</strong></div>
<div style="clear:both"></div>
</div>
<input id="imageUploadBrowse" type="file" accept="image/jpeg, image/jpg, image/png" style="position:absolute; top:-1000px;"/>
<div id="loadImage" class="button lime" style="position:absolute; top:300px; left:300px;">Load Image</div>
<div id="shareImage" class="button orange">Share</div>
<div id="saveImage" class="button orange">Save</div>
<canvas id="combinedFrame" width=700 height=600...
CSS
@charset "UTF-8";
/* CSS Document */
body,td,th {
color: #333;
}
body {
background-color: #efefef;
}
p {
font: 14px/100% Arial, Helvetica, sans-serif;
}
.palette {
width: 112px;
height: 100px;
float: left;
}
.buffer {
width: 5px;
height: 100px;
float: left;
}
.newcolor {
color: #ffffff !important;
font-style: oblique;
padding: 5px !important;
}
.circle {
-webkit-border-radius: 50%;
-moz-border-radius: 50%;
border-radius: 50%;
width: 10px;
height: 10px;
border: 3px solid white;
-moz-box-shadow: 0 0 5px 5px rgba(0,0,0,.4);
-webkit-box-shadow: 0 0 5px 5px rgba(0,0,0,.4);
box-shadow: 0 0 1px rgba(0,0,0,.4);
position: absolute;
}
.button {
display: inline-block;
outline: none;
cursor: pointer;
text-align: center;
text-decoration: none;
font: 14px/100% Arial, Helvetica, sans-serif;
padding: .5em 2em .55em;
text-shadow: 0 1px 1px rgba(0,0,0,.1);
-webkit-border-radius: .5em;
-moz-border-radius: .5em;
border-radius: .5em;
-webkit-box-shadow: 0 1px 2px rgba(0,0,0,.2);
-moz-box-shadow: 0 1px 2px rgba(0,0,0,.2);
box-shadow: 0 1px 2px rgba(0,0,0,.2);
}
.gallery {
width: 500px;
border: 1px solid #000;
margin: 10px 5px 0 0;
}
.button:hover {
text-decoration: none;
}
.button:active {
position: relative;
top: 1px;
}
.lime {
color: #003300;
border: solid 1px #99af0c;
background: #9ed900;
background: -webkit-gradient(linear, left top, left bottom, from(#beff10), to(#9ed900));
background: -moz-linear-gradient(top, #beff10, #9ed900);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#beff10', endColorstr='#9ed900');
}
.lime:hover {
background: #b2f500;
background: -webkit-gradient(linear, left top, left bottom, from(#d0ff52), to(#aaea00));
background: -moz-linear-gradient(top, #d0ff52, #aaea00);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr:'#d0ff52', endColorstr='#aaea00');
}
.lime:active {
color:...
JavaScript
// Palette Builder v2.0
// Copyright 2012-2013 Play Crafts, Inc.
$(document).ready(startApp);
var palette = [];
var paletteDiv = [];
var bufferDiv = [];
var circleDiv = [];
var paletteCircles = [];
var newColorIcon;
var circleIndex = -1;
var circledx, circledy;
var ctx, imgScale;
var img, uiFrame;
var stroke = 3;
var defaultPaletteSize = 6;
var paletteSize;
var maxPaletteSize = 8;
var imgData;
var totalOffset = {x: 0, y: 0};
var redrawTimer;
var newIconShown = false;
var combineFrame, combinectx, paletteImage;
var newWindow;
var initialHeight;
var initialWidth;
var i;
var paletteSpacing = 5;
// Let us know when the user wants to load an image
function startApp() {
$("#loadImage").on("click", buttonClicked);
document.getElementById('imageUploadBrowse').addEventListener('change', loadImage, false);
var shareButton = $("#shareImage");
shareButton.on("click", shareImage);
shareButton.hide();
var saveButton = $("#saveImage");
saveButton.on("click", saveImage);
saveButton.hide();
newColorIcon = $("#paletteUI");
newColorIcon.on ("click", addColor);
newColorIcon.hide();
uiFrame = document.getElementById('UIframe');
initialHeight = uiFrame.height;
initialWidth = uiFrame.width;
ctx = uiFrame.getContext('2d');
// load all the palette divs into the array
for (i=0; i<maxPaletteSize; i++)
{
circleDiv[i] = document.getElementById('circle' + i);
circleDiv[i].style.display = 'none';
$("#circle"+i).draggable({
drag: function(event, ui) {
// find current x,y of div
var circleX = ui.position.left;
var circleY = ui.position.top;
// figure out what color pixel the circle is over
var pixelNum = Math.round(circleY * img.width + circleX) * 4;
var color = "rgba(" + imgData.data[pixelNum] + "," + imgData.data[pixelNum+1] + "," + imgData.data[pixelNum+2] + ")";
//...