JSFiddle - React, Tailwind, and code Playground
by Muhammad Nugroho
HTML
<head>
<title>Real Life Color Picker — Shiny Demos</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, height=device-height">
<link rel="stylesheet" href="styles/style.css">
<link rel="stylesheet" href="/styles/panel.css">
</head>
<body>
<div id="supcontainer">
<h1>Real Life Color Picker</h1>
<div id="container">
<div id="video_container">
<video id="video"></video>
</div>
<div id="footer">
<canvas id="mycanvas" width="300" height="425"></canvas>
</div>
<div id="doit" class="button">Create Palette</div> <div id="reset" class="button">Reset</div>
<div id="colors">
<ul id="colorlist"></ul>
</div>
</div>
</div>
<!-- Credit: Built upon work by Lokesh Dhakar (http://www.lokeshdhakar.com) at http://www.lokeshdhakar.com/2011/11/03/color-thief/. -->
<script src="/scripts/modernizr.js"></script>
<script src="/scripts/panel.js"></script>
<script src="scripts/options.js"></script>
<script src="scripts/script.js"></script>
<script src="scripts/quantize.js"></script>
CSS
@font-face {
font-family: 'chunk';
src: url('fonts/Chunkfive.eot');
src: local('☺'), url('../fonts/Chunkfive.woff') format('woff'), url('../fonts/Chunkfive.ttf') format('truetype'), url('../fonts/Chunkfive.svg') format('svg');
font-weight: normal;
font-style: normal;
/* ChunkFive font: http://www.fontsquirrel.com/fonts/ChunkFive
Licensed under SIL Open Font License Version 1.1 http://www.fontsquirrel.com/license/ChunkFive */
}
body{
background-color: #ede1cb;
color: #555;
font-family: "lucida grande", tahoma, verdana, arial, sans-serif;
}
@-o-viewport {
width: device-width;
height: device-height;
}
#supcontainer{
margin: 0 auto;
padding: 10px;
width: 600px;
text-align: center;
border: 1px solid #333;
background-color: #faf7f2;
border-radius: 3px;
}
h1{
font-family: "chunk", "lucida grande", arial, sans-serif;
font-size: 2.5em;
margin: 0;
}
a{
color: #555;
}
#mycanvas{
display: none;
}
#primesquare{
width: 50px;
height: 50px;
outline: 1px solid #fff;
display: inline-block;
}
video{
width: 510px;
box-shadow: 0px 3px 5px #444;
}
.othercolors{
width: 25px;
height: 25px;
outline: 1px solid #fff;
display: inline-block;
margin-top: 10px;
}
.hide{
display: none;
}
#colors {
margin-top: 5px;
text-align: left;
}
#colorlist li{
list-style: none;
font-size: 1.4em;
border-bottom: 1px dotted #333;
}
.button{
display:inline-block;
outline: none;
cursor: pointer;
text-align: center;
text-decoration: none;
padding: .5em 2em .55em;
border-radius: 5px;
box-shadow: 0 1px 2px rgba(0,0,0,.2);
font-size: 0.8em;
margin-top: 5px;
color: #fef4e9;
border: solid 1px #da7c0c;
background: #f78d1d;
background: -webkit-gradient(top, #faa51a, #f47a20);
background: -moz-linear-gradient(top, #faa51a, #f47a20);
background: -ms-linear-gradient(top, #faa51a, #f47a20);
background: -o-linear-gradient(top, #faa51a, #f47a20);
}
footer{
margin-top: 20px;
font-family: 'chunk';
}
/*...
JavaScript
if (!pv) {
var pv = {
map: function(array, f) {
var o = {};
return f
? array.map(function(d, i) { o.index = i; return f.call(o, d); })
: array.slice();
},
naturalOrder: function(a, b) {
return (a < b) ? -1 : ((a > b) ? 1 : 0);
},
sum: function(array, f) {
var o = {};
return array.reduce(f
? function(p, d, i) { o.index = i; return p + f.call(o, d); }
: function(p, d) { return p + d; }, 0);
},
max: function(array, f) {
return Math.max.apply(null, f ? pv.map(array, f) : array);
}
}
}
/**
* Basic Javascript port of the MMCQ (modified median cut quantization)
* algorithm from the Leptonica library (http://www.leptonica.com/).
* Returns a color map you can use to map original pixels to the reduced
* palette. Still a work in progress.
*
* @author Nick Rabinowitz
* @example
// array of pixels as [R,G,B] arrays
var myPixels = [[190,197,190], [202,204,200], [207,214,210], [211,214,211], [205,207,207]
// etc
];
var maxColors = 4;
var cmap = MMCQ.quantize(myPixels, maxColors);
var newPalette = cmap.palette();
var newPixels = myPixels.map(function(p) {
return cmap.map(p);
});
*/
var MMCQ = (function() {
// private constants
var sigbits = 5,
rshift = 8 - sigbits,
maxIterations = 1000,
fractByPopulations = 0.75;
// get reduced-space color index for a pixel
function getColorIndex(r, g, b) {
return (r << (2 * sigbits)) + (g << sigbits) + b;
}
// Simple priority queue
function PQueue(comparator) {
var contents = [],
sorted = false;
function sort() {
contents.sort(comparator);
sorted = true;
}
return {
push: function(o) {
contents.push(o);
sorted...