/* * # Semantic - Colorize * http://github.com/semantic-org/semantic-ui/ * * * Copyright 2014 Contributor * Released under the MIT license * http://opensource.org/licenses/MIT * */ ;(function ( $, window, document, undefined ) { $.fn.colorize = function(parameters) { var settings = $.extend(true, {}, $.fn.colorize.settings, parameters), // hoist arguments moduleArguments = arguments || false ; $(this) .each(function(instanceIndex) { var $module = $(this), mainCanvas = $('')[0], imageCanvas = $('')[0], overlayCanvas = $('')[0], backgroundImage = new Image(), // defs mainContext, imageContext, overlayContext, image, imageName, width, height, // shortucts colors = settings.colors, paths = settings.paths, namespace = settings.namespace, error = settings.error, // boilerplate instance = $module.data('module-' + namespace), module ; module = { checkPreconditions: function() { module.debug('Checking pre-conditions'); if( !$.isPlainObject(colors) || $.isEmptyObject(colors) ) { module.error(error.undefinedColors); return false; } return true; }, async: function(callback) { if(settings.async) { setTimeout(callback, 0); } else { callback(); } }, getMetadata: function() { module.debug('Grabbing metadata'); image = $module.data('image') || settings.image || undefined; imageName = $module.data('name') || settings.name || instanceIndex; width = settings.width || $module.width(); height = settings.height || $module.height(); if(width === 0 || height === 0) { module.error(error.undefinedSize); } }, initialize: function() { module.debug('Initializing with colors', colors); if( module.checkPreconditions() ) { module.async(function() { module.getMetadata(); module.canvas.create(); module.draw.image(function() { module.draw.colors(); module.canvas.merge(); }); $module .data('module-' + namespace, module) ; }); } }, redraw: function() { module.debug('Redrawing image'); module.async(function() { module.canvas.clear(); module.draw.colors(); module.canvas.merge(); }); }, change: { color: function(colorName, color) { module.debug('Changing color', colorName); if(colors[colorName] === undefined) { module.error(error.missingColor); return false; } colors[colorName] = color; module.redraw(); } }, canvas: { create: function() { module.debug('Creating canvases'); mainCanvas.width = width; mainCanvas.height = height; imageCanvas.width = width; imageCanvas.height = height; overlayCanvas.width = width; overlayCanvas.height = height; mainContext = mainCanvas.getContext('2d'); imageContext = imageCanvas.getContext('2d'); overlayContext = overlayCanvas.getContext('2d'); $module .append( mainCanvas ) ; mainContext = $module.children('canvas')[0].getContext('2d'); }, clear: function(context) { module.debug('Clearing canvas'); overlayContext.fillStyle = '#FFFFFF'; overlayContext.fillRect(0, 0, width, height); }, merge: function() { if( !$.isFunction(mainContext.blendOnto) ) { module.error(error.missingPlugin); return; } mainContext.putImageData( imageContext.getImageData(0, 0, width, height), 0, 0); overlayContext.blendOnto(mainContext, 'multiply'); } }, draw: { image: function(callback) { module.debug('Drawing image'); callback = callback || function(){}; if(image) { backgroundImage.src = image; backgroundImage.onload = function() { imageContext.drawImage(backgroundImage, 0, 0); callback(); }; } else { module.error(error.noImage); callback(); } }, colors: function() { module.debug('Drawing color overlays', colors); $.each(colors, function(colorName, color) { settings.onDraw(overlayContext, imageName, colorName, color); }); } }, debug: function(message, variableName) { if(settings.debug) { if(variableName !== undefined) { console.info(settings.name + ': ' + message, variableName); } else { console.info(settings.name + ': ' + message); } } }, error: function(errorMessage) { console.warn(settings.name + ': ' + errorMessage); }, invoke: function(methodName, context, methodArguments) { var method ; methodArguments = methodArguments || Array.prototype.slice.call( arguments, 2 ); if(typeof methodName == 'string' && instance !== undefined) { methodName = methodName.split('.'); $.each(methodName, function(index, name) { if( $.isPlainObject( instance[name] ) ) { instance = instance[name]; return true; } else if( $.isFunction( instance[name] ) ) { method = instance[name]; return true; } module.error(settings.error.method); return false; }); } return ( $.isFunction( method ) ) ? method.apply(context, methodArguments) : false ; } }; if(instance !== undefined && moduleArguments) { // simpler than invoke realizing to invoke itself (and losing scope due prototype.call() if(moduleArguments[0] == 'invoke') { moduleArguments = Array.prototype.slice.call( moduleArguments, 1 ); } return module.invoke(moduleArguments[0], this, Array.prototype.slice.call( moduleArguments, 1 ) ); } // initializing module.initialize(); }) ; return this; }; $.fn.colorize.settings = { name : 'Image Colorizer', debug : true, namespace : 'colorize', onDraw : function(overlayContext, imageName, colorName, color) {}, // whether to block execution while updating canvas async : true, // object containing names and default values of color regions colors : {}, metadata: { image : 'image', name : 'name' }, error: { noImage : 'No tracing image specified', undefinedColors : 'No default colors specified.', missingColor : 'Attempted to change color that does not exist', missingPlugin : 'Blend onto plug-in must be included', undefinedHeight : 'The width or height of image canvas could not be automatically determined. Please specify a height.' } }; })( jQuery, window , document );