From 0123a7bff0e69f087e9c6227d2af2c790cc21ebd Mon Sep 17 00:00:00 2001 From: Lokesh Dhakar Date: Sun, 22 Apr 2012 00:48:46 -0400 Subject: [PATCH] All of jfsiii awesome edits are now in place. --- index.html | 68 +---------- index.js | 45 +++++++ js/color-thief.js | 303 +++++++++++++++++++++------------------------- 3 files changed, 186 insertions(+), 230 deletions(-) create mode 100644 index.js diff --git a/index.html b/index.html index b57820a..820a32e 100755 --- a/index.html +++ b/index.html @@ -35,7 +35,6 @@ - @@ -65,69 +64,6 @@ {{/images}} - - - - - + - + \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..014c6d7 --- /dev/null +++ b/index.js @@ -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 = $('
', {'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); + }); +}); \ No newline at end of file diff --git a/js/color-thief.js b/js/color-thief.js index 63c6b21..08ef3c0 100644 --- a/js/color-thief.js +++ b/js/color-thief.js @@ -3,7 +3,7 @@ * by Lokesh Dhakar - http://www.lokeshdhakar.com * * 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 * and licensed under the MIT license. Big props to Nick as this is where the magic happens. * @@ -16,49 +16,49 @@ * createAreaBasedPalette() * * Requires jquery and quantize.js. -*/ + */ /* - CanvasImage Class - Class that wraps the html image element and canvas. - It also simplifies some of the canvas context manipulation - with a set of helper functions. + CanvasImage Class + Class that wraps the html image element and canvas. + It also simplifies some of the canvas context manipulation + with a set of helper functions. */ -var CanvasImage = function(image){ - // If jquery object is passed in, get html element - this.imgEl = (image.jquery)? image[0]: image; +var CanvasImage = function (image) { + // If jquery object is passed in, get html element + this.imgEl = (image.jquery) ? image[0] : image; - this.canvas = document.createElement('canvas'), + this.canvas = document.createElement('canvas'); 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.height = this.canvas.height = $(this.imgEl).height(); + this.width = this.canvas.width = $(this.imgEl).width(); + 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() { - this.context.clearRect(0, 0, this.width, this.height); -} +CanvasImage.prototype.clear = function () { + this.context.clearRect(0, 0, this.width, this.height); +}; -CanvasImage.prototype.update = function(imageData) { - this.context.putImageData(imageData, 0, 0); -} +CanvasImage.prototype.update = function (imageData) { + this.context.putImageData(imageData, 0, 0); +}; -CanvasImage.prototype.getPixelCount = function() { - return this.width * this.height; -} +CanvasImage.prototype.getPixelCount = function () { + return this.width * this.height; +}; -CanvasImage.prototype.getImageData = function() { - return this.context.getImageData(0, 0, this.width, this.height); -} +CanvasImage.prototype.getImageData = function () { + return this.context.getImageData(0, 0, this.width, this.height); +}; -CanvasImage.prototype.removeCanvas = function() { - $(this.canvas).remove(); -} +CanvasImage.prototype.removeCanvas = function () { + $(this.canvas).remove(); +}; /* @@ -67,41 +67,16 @@ CanvasImage.prototype.removeCanvas = function() { * * Use the median cut algorithm provided by quantize.js to cluster similar * 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 - 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]}; + return dominant; } - /* * createPalette(sourceImage, colorCount) * returns array[ {r: num, g: num, b: num}, {r: num, g: num, b: num}, ...] @@ -110,37 +85,41 @@ function getDominantColor(sourceImage){ * colors. * * 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 - 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]]); - } - } - }; + // Store the RGB values in an array format suitable for quantize function + var pixelArray = []; + for (var i = 0, offset, r, g, b, a; i < pixelCount; i++) { + offset = i * 4; + r = pixels[offset + 0]; + g = pixels[offset + 1]; + b = pixels[offset + 2]; + a = pixels[offset + 3]; + // If pixel is mostly opaque and not white + if (a >= 125) { + if (!(r > 250 && g > 250 && b > 250)) { + pixelArray.push([r, g, b]); + } + } + } - // Send array to quantize function which clusters values - // using median cut algorithm - var cmap = MMCQ.quantize(pixelArray, colorCount); - var newPalette = cmap.palette(); + // Send array to quantize function which clusters values + // using median cut algorithm - // Clean up - image.removeCanvas(); + var cmap = MMCQ.quantize(pixelArray, colorCount); + 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. * Tends to return muddy gray/brown color. Most likely, you'll be better * off using getDominantColor() instead. -*/ + */ function getAverageRGB(sourceImage) { - // Config - var sampleSize = 10; - - // Create custom CanvasImage object - var image = new CanvasImage(sourceImage), - imageData = image.getImageData(), - pixels = imageData.data, - pixelCount = image.getPixelCount(); + // Config + var sampleSize = 10; - // Reset vars - var i = 0, - count = 0, - rgb = {r:0,g:0,b:0}; + // Create custom CanvasImage object + var image = new CanvasImage(sourceImage), + imageData = image.getImageData(), + pixels = imageData.data, + pixelCount = image.getPixelCount(); - // 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. + // Reset vars + var i = 0, + 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 ) { - // if pixel is mostly opaque - if(pixels[i+3] > 125){ - ++count; - rgb.r += pixels[i]; - rgb.g += pixels[i+1]; - rgb.b += pixels[i+2]; - } + // if pixel is mostly opaque + if (pixels[i+3] > 125) { + ++count; + rgb.r += pixels[i]; + rgb.g += pixels[i+1]; + rgb.b += pixels[i+2]; + } } - rgb.r = Math.floor(rgb.r/count); - rgb.g = Math.floor(rgb.g/count); - rgb.b = Math.floor(rgb.b/count); + rgb.r = ~~(rgb.r/count); + rgb.g = ~~(rgb.g/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. * 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. - * -*/ -function createAreaBasedPalette(sourceImage, colorCount){ + * + */ +function createAreaBasedPalette(sourceImage, colorCount) { - var palette = []; + var palette = []; - // Create custom CanvasImage object - var image = new CanvasImage(sourceImage), - imageData = image.getImageData(), - pixels = imageData.data, - 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}; + // Create custom CanvasImage object + var image = new CanvasImage(sourceImage), + imageData = image.getImageData(), + pixels = imageData.data, + pixelCount = image.getPixelCount(); - // 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