All of jfsiii awesome edits are now in place.

This commit is contained in:
Lokesh Dhakar
2012-04-22 00:48:46 -04:00
parent fb1bba5df2
commit 0123a7bff0
3 changed files with 186 additions and 230 deletions

View File

@@ -35,7 +35,6 @@
</div> <!--! end of #container --> </div> <!--! end of #container -->
<script>window.jQuery || document.write('<script src="js/libs/jquery-1.6.2.min.js"><\/script>')</script> <script>window.jQuery || document.write('<script src="js/libs/jquery-1.6.2.min.js"><\/script>')</script>
<script src="js/libs/jquery.imagesloaded.js"></script>
<script src="js/libs/jquery.lettering.js"></script> <script src="js/libs/jquery.lettering.js"></script>
<script src="js/libs/mustache.js"></script> <script src="js/libs/mustache.js"></script>
@@ -65,69 +64,6 @@
{{/images}} {{/images}}
</script> </script>
<script> <script src="index.js"></script>
$(document).ready(function(){
// Use mustache.js templating to create layout
var imageArray = { images: [
{"file": "3.jpg"},
{"file": "4.jpg"},
{"file": "5.jpg"},
{"file": "logo1.png"},
{"file": "icon1.png", "colorCount": "4", "class": "fbIcon"}
]};
var html = Mustache.to_html($('#template').html(), imageArray);
$('#main').append(html);
// Use lettering.js to give letter by letter styling control for the h1 title
$("h1").lettering();
// Once images are loaded, loop through each one, getting dominant color
// and palette and displaying them.
$('img').imagesLoaded(function(){
$('img').each(function(index){
var imageSection = $(this).closest('.imageSection'),
swatchEl;
// Dominant Color
var dominantColor = getDominantColor(this);
swatchEl = $('<div>', {
'class': 'swatch'
}).css('background-color','rgba('+dominantColor.r+','+dominantColor.g+ ','+dominantColor.b+', 1)');
imageSection.find('.dominantColor .swatches').append(swatchEl);
// Palette
var colorCount = $(this).attr('data-colorcount')? $(this).data('colorcount'): 10;
var medianPalette = createPalette(this, colorCount);
var medianCutPalette = imageSection.find('.medianCutPalette .swatches');
$.each(medianPalette, function(index, value){
swatchEl = $('<div>', {
'class': 'swatch'
}).css('background-color','rgba('+value[0]+','+value[1]+ ','+value[2]+', 1)');
medianCutPalette.append(swatchEl);
});
});
});
});
</script>
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript"></script>
<script type="text/javascript">
_uacct = "UA-2196019-1";
urchinTracker();
</script>
</body> </body>
</html> </html>

45
index.js Normal file
View File

@@ -0,0 +1,45 @@
$(document).ready(function () {
// Use mustache.js templating to create layout
var imageArray = { images: [
{"file": "3.jpg"},
{"file": "4.jpg"},
{"file": "5.jpg"},
{"file": "logo1.png"},
{"file": "icon1.png", "colorCount": "4", "class": "fbIcon"}
]};
var html = Mustache.to_html($('#template').html(), imageArray);
$('#main').append(html);
// Use lettering.js to give letter by letter styling control for the h1 title
$("h1").lettering();
// For each image:
// Once image is loaded, get dominant color and palette and display them.
$('img').bind('load', function (event) {
var image = event.target;
var $image = $(image);
var imageSection = $image.closest('.imageSection');
var appendColors = function (colors, root) {
$.each(colors, function (index, value) {
var swatchEl = $('<div>', {'class': 'swatch'})
.css('background-color', 'rgba('+ value +', 1)');
root.append(swatchEl);
});
};
// Dominant Color
var dominantColor = getDominantColor(image);
var dominantSwatch = imageSection.find('.dominantColor .swatches');
appendColors([dominantColor], dominantSwatch);
// Palette
var colorCount = $image.attr('data-colorcount') ? $image.data('colorcount') : 10;
var medianPalette = createPalette(image, colorCount);
var medianCutPalette = imageSection.find('.medianCutPalette .swatches');
appendColors(medianPalette, medianCutPalette);
});
});

View File

@@ -3,7 +3,7 @@
* by Lokesh Dhakar - http://www.lokeshdhakar.com * by Lokesh Dhakar - http://www.lokeshdhakar.com
* *
* Licensed under the Creative Commons Attribution 2.5 License - http://creativecommons.org/licenses/by/2.5/ * Licensed under the Creative Commons Attribution 2.5 License - http://creativecommons.org/licenses/by/2.5/
* *
* The median cut palette function uses quantize.js which is written by Nick Rabinowitz * The median cut palette function uses quantize.js which is written by Nick Rabinowitz
* and licensed under the MIT license. Big props to Nick as this is where the magic happens. * and licensed under the MIT license. Big props to Nick as this is where the magic happens.
* *
@@ -16,49 +16,49 @@
* createAreaBasedPalette() * createAreaBasedPalette()
* *
* Requires jquery and quantize.js. * Requires jquery and quantize.js.
*/ */
/* /*
CanvasImage Class CanvasImage Class
Class that wraps the html image element and canvas. Class that wraps the html image element and canvas.
It also simplifies some of the canvas context manipulation It also simplifies some of the canvas context manipulation
with a set of helper functions. with a set of helper functions.
*/ */
var CanvasImage = function(image){ var CanvasImage = function (image) {
// If jquery object is passed in, get html element // If jquery object is passed in, get html element
this.imgEl = (image.jquery)? image[0]: image; this.imgEl = (image.jquery) ? image[0] : image;
this.canvas = document.createElement('canvas'), this.canvas = document.createElement('canvas');
this.context = this.canvas.getContext('2d'); this.context = this.canvas.getContext('2d');
document.body.appendChild(this.canvas); document.body.appendChild(this.canvas);
this.width = this.canvas.width = $(this.imgEl).width(), this.width = this.canvas.width = $(this.imgEl).width();
this.height = this.canvas.height = $(this.imgEl).height(); this.height = this.canvas.height = $(this.imgEl).height();
this.context.drawImage(this.imgEl, 0, 0); this.context.drawImage(this.imgEl, 0, 0);
} };
CanvasImage.prototype.clear = function() { CanvasImage.prototype.clear = function () {
this.context.clearRect(0, 0, this.width, this.height); this.context.clearRect(0, 0, this.width, this.height);
} };
CanvasImage.prototype.update = function(imageData) { CanvasImage.prototype.update = function (imageData) {
this.context.putImageData(imageData, 0, 0); this.context.putImageData(imageData, 0, 0);
} };
CanvasImage.prototype.getPixelCount = function() { CanvasImage.prototype.getPixelCount = function () {
return this.width * this.height; return this.width * this.height;
} };
CanvasImage.prototype.getImageData = function() { CanvasImage.prototype.getImageData = function () {
return this.context.getImageData(0, 0, this.width, this.height); return this.context.getImageData(0, 0, this.width, this.height);
} };
CanvasImage.prototype.removeCanvas = function() { CanvasImage.prototype.removeCanvas = function () {
$(this.canvas).remove(); $(this.canvas).remove();
} };
/* /*
@@ -67,41 +67,16 @@ CanvasImage.prototype.removeCanvas = function() {
* *
* Use the median cut algorithm provided by quantize.js to cluster similar * Use the median cut algorithm provided by quantize.js to cluster similar
* colors and return the base color from the largest cluster. * colors and return the base color from the largest cluster.
*/ */
function getDominantColor(sourceImage){ function getDominantColor(sourceImage) {
var palette = []; var palette = createPalette(sourceImage, 5);
var dominant = palette[0];
// Create custom CanvasImage object return dominant;
var image = new CanvasImage(sourceImage),
imageData = image.getImageData(),
pixels = imageData.data,
pixelCount = image.getPixelCount();
// Store the RGB values in an array format suitable for quantize function
var pixelArray = [];
for (var i = 0; i < pixelCount; i++) {
// If pixel is mostly opaque and not white
if(pixels[i*4+3] >= 125){
if(!(pixels[i*4] > 250 && pixels[i*4+1] > 250 && pixels[i*4+2] > 250)){
pixelArray.push( [pixels[i*4], pixels[i*4+1], pixels[i*4+2]]);
}
}
};
// Send array to quantize function which clusters values
// using median cut algorithm
var cmap = MMCQ.quantize(pixelArray, 5);
var newPalette = cmap.palette();
// Clean up
image.removeCanvas();
return {r: newPalette[0][0], g: newPalette[0][1], b: newPalette[0][2]};
} }
/* /*
* createPalette(sourceImage, colorCount) * createPalette(sourceImage, colorCount)
* returns array[ {r: num, g: num, b: num}, {r: num, g: num, b: num}, ...] * returns array[ {r: num, g: num, b: num}, {r: num, g: num, b: num}, ...]
@@ -110,37 +85,41 @@ function getDominantColor(sourceImage){
* colors. * colors.
* *
* BUGGY: Function does not always return the requested amount of colors. It can be +/- 2. * BUGGY: Function does not always return the requested amount of colors. It can be +/- 2.
*/ */
function createPalette(sourceImage, colorCount){ function createPalette(sourceImage, colorCount) {
var palette = []; // Create custom CanvasImage object
var image = new CanvasImage(sourceImage),
imageData = image.getImageData(),
pixels = imageData.data,
pixelCount = image.getPixelCount();
// Create custom CanvasImage object // Store the RGB values in an array format suitable for quantize function
var image = new CanvasImage(sourceImage), var pixelArray = [];
imageData = image.getImageData(), for (var i = 0, offset, r, g, b, a; i < pixelCount; i++) {
pixels = imageData.data, offset = i * 4;
pixelCount = image.getPixelCount(); r = pixels[offset + 0];
g = pixels[offset + 1];
// Store the RGB values in an array format suitable for quantize function b = pixels[offset + 2];
var pixelArray = []; a = pixels[offset + 3];
for (var i = 0; i < pixelCount; i++) { // If pixel is mostly opaque and not white
// If pixel is mostly opaque and not white if (a >= 125) {
if(pixels[i*4+3] >= 125){ if (!(r > 250 && g > 250 && b > 250)) {
if(!(pixels[i*4] > 250 && pixels[i*4+1] > 250 && pixels[i*4+2] > 250)){ pixelArray.push([r, g, b]);
pixelArray.push( [pixels[i*4], pixels[i*4+1], pixels[i*4+2]]); }
} }
} }
};
// Send array to quantize function which clusters values // Send array to quantize function which clusters values
// using median cut algorithm // using median cut algorithm
var cmap = MMCQ.quantize(pixelArray, colorCount);
var newPalette = cmap.palette();
// Clean up var cmap = MMCQ.quantize(pixelArray, colorCount);
image.removeCanvas(); var palette = cmap.palette();
return newPalette; // Clean up
image.removeCanvas();
return palette;
} }
@@ -151,40 +130,40 @@ function createPalette(sourceImage, colorCount){
* Add up all pixels RGB values and return average. * Add up all pixels RGB values and return average.
* Tends to return muddy gray/brown color. Most likely, you'll be better * Tends to return muddy gray/brown color. Most likely, you'll be better
* off using getDominantColor() instead. * off using getDominantColor() instead.
*/ */
function getAverageRGB(sourceImage) { function getAverageRGB(sourceImage) {
// Config // Config
var sampleSize = 10; var sampleSize = 10;
// Create custom CanvasImage object
var image = new CanvasImage(sourceImage),
imageData = image.getImageData(),
pixels = imageData.data,
pixelCount = image.getPixelCount();
// Reset vars // Create custom CanvasImage object
var i = 0, var image = new CanvasImage(sourceImage),
count = 0, imageData = image.getImageData(),
rgb = {r:0,g:0,b:0}; pixels = imageData.data,
pixelCount = image.getPixelCount();
// Loop through every # pixels. (# is set in Config above via the blockSize var) // Reset vars
// Add all the red values together, repeat for blue and green. var i = 0,
// Last step, divide by the number of pixels checked to get average. count = 0,
rgb = {r:0, g:0, b:0};
// Loop through every # pixels. (# is set in Config above via the blockSize var)
// Add all the red values together, repeat for blue and green.
// Last step, divide by the number of pixels checked to get average.
while ( (i += sampleSize * 4) < pixelCount ) { while ( (i += sampleSize * 4) < pixelCount ) {
// if pixel is mostly opaque // if pixel is mostly opaque
if(pixels[i+3] > 125){ if (pixels[i+3] > 125) {
++count; ++count;
rgb.r += pixels[i]; rgb.r += pixels[i];
rgb.g += pixels[i+1]; rgb.g += pixels[i+1];
rgb.b += pixels[i+2]; rgb.b += pixels[i+2];
} }
} }
rgb.r = Math.floor(rgb.r/count); rgb.r = ~~(rgb.r/count);
rgb.g = Math.floor(rgb.g/count); rgb.g = ~~(rgb.g/count);
rgb.b = Math.floor(rgb.b/count); rgb.b = ~~(rgb.b/count);
return rgb; return rgb;
} }
@@ -194,59 +173,55 @@ function getAverageRGB(sourceImage) {
* *
* Break the image into sections. Loops through pixel RGBS in the section and average color. * Break the image into sections. Loops through pixel RGBS in the section and average color.
* Tends to return muddy gray/brown color. You're most likely better off using createPalette(). * Tends to return muddy gray/brown color. You're most likely better off using createPalette().
* *
* BUGGY: Function does not always return the requested amount of colors. It can be +/- 2. * BUGGY: Function does not always return the requested amount of colors. It can be +/- 2.
* *
*/ */
function createAreaBasedPalette(sourceImage, colorCount){ function createAreaBasedPalette(sourceImage, colorCount) {
var palette = []; var palette = [];
// Create custom CanvasImage object // Create custom CanvasImage object
var image = new CanvasImage(sourceImage), var image = new CanvasImage(sourceImage),
imageData = image.getImageData(), imageData = image.getImageData(),
pixels = imageData.data, pixels = imageData.data,
pixelCount = image.getPixelCount(); pixelCount = image.getPixelCount();
// How big a pixel area does each palette color get
var rowCount = colCount = Math.round(Math.sqrt(colorCount)),
colWidth = Math.round(image.width / colCount),
rowHeight = Math.round(image.height / rowCount);
var count = offset = rowOffset = vertOffset = horizOffset = 0,
rgb = {r:0,g:0,b:0};
// Loop through pixels section by section.
// At the end of each section, push the average rgb color to palette array.
for(var i=0; i<rowCount; i++){
vertOffset = i * rowHeight * image.width * 4;
for(var j=0; j<colCount; j++){
horizOffset = j * colWidth * 4;
for( var k = 0; k < rowHeight; k++){
rowOffset = k * image.width * 4;
for( var l = 0; l < colWidth; l++){
offset = vertOffset + horizOffset + rowOffset + (l * 4);
rgb.r += pixels[offset];
rgb.g += pixels[offset+1];
rgb.b += pixels[offset+2];
count++;
}
}
rgb.r = Math.floor(rgb.r/count);
rgb.g = Math.floor(rgb.g/count);
rgb.b = Math.floor(rgb.b/count);
palette.push(rgb);
// reset before next section // How big a pixel area does each palette color get
rgb = {r:0,g:0,b:0}; var rowCount = Math.round(Math.sqrt(colorCount)),
count = 0; colCount = rowCount,
} colWidth = Math.round(image.width / colCount),
} rowHeight = Math.round(image.height / rowCount);
return palette; // Loop through pixels section by section.
} // At the end of each section, push the average rgb color to palette array.
for (var i = 0, vertOffset; i<rowCount; i++) {
vertOffset = i * rowHeight * image.width * 4;
for (var j = 0, horizOffset, rgb, count; j<colCount; j++) {
horizOffset = j * colWidth * 4;
rgb = {r:0, g:0, b:0};
count = 0;
for (var k = 0, rowOffset; k < rowHeight; k++) {
rowOffset = k * image.width * 4;
for (var l = 0, offset; l < colWidth; l++) {
offset = vertOffset + horizOffset + rowOffset + (l * 4);
rgb.r += pixels[offset];
rgb.g += pixels[offset+1];
rgb.b += pixels[offset+2];
count++;
}
}
rgb.r = ~~(rgb.r/count);
rgb.g = ~~(rgb.g/count);
rgb.b = ~~(rgb.b/count);
palette.push(rgb);
}
}
return palette;
}