window.DrawingBoard = typeof DrawingBoard !== "undefined" ? DrawingBoard : {}; DrawingBoard.Utils = {}; /*! * Tim (lite) * github.com/premasagar/tim *//* A tiny, secure JavaScript micro-templating script. */ DrawingBoard.Utils.tpl = (function(){ "use strict"; var start = "{{", end = "}}", path = "[a-z0-9_][\\.a-z0-9_]*", // e.g. config.person.name pattern = new RegExp(start + "\\s*("+ path +")\\s*" + end, "gi"), undef; return function(template, data){ // Merge data into the template string return template.replace(pattern, function(tag, token){ var path = token.split("."), len = path.length, lookup = data, i = 0; for (; i < len; i++){ lookup = lookup[path[i]]; // Property not found if (lookup === undef){ throw "tim: '" + path[i] + "' not found in " + tag; } // Return the required value if (i === len - 1){ return lookup; } } }); }; }()); /** * https://github.com/jeromeetienne/microevent.js * MicroEvent - to make any js object an event emitter (server or browser) * * - pure javascript - server compatible, browser compatible * - dont rely on the browser doms * - super simple - you get it immediatly, no mistery, no magic involved * * - create a MicroEventDebug with goodies to debug * - make it safer to use */ DrawingBoard.Utils.MicroEvent = function(){}; DrawingBoard.Utils.MicroEvent.prototype = { bind : function(event, fct){ this._events = this._events || {}; this._events[event] = this._events[event] || []; this._events[event].push(fct); }, unbind : function(event, fct){ this._events = this._events || {}; if( event in this._events === false ) return; this._events[event].splice(this._events[event].indexOf(fct), 1); }, trigger : function(event /* , args... */){ this._events = this._events || {}; if( event in this._events === false ) return; for(var i = 0; i < this._events[event].length; i++){ this._events[event][i].apply(this, Array.prototype.slice.call(arguments, 1)); } } }; //I know. DrawingBoard.Utils._boxBorderSize = function($el, withPadding, withMargin, direction) { withPadding = !!withPadding || true; withMargin = !!withMargin || false; var width = 0, props; if (direction == "width") { props = ['border-left-width', 'border-right-width']; if (withPadding) props.push('padding-left', 'padding-right'); if (withMargin) props.push('margin-left', 'margin-right'); } else { props = ['border-top-width', 'border-bottom-width']; if (withPadding) props.push('padding-top', 'padding-bottom'); if (withMargin) props.push('margin-top', 'margin-bottom'); } for (var i = props.length - 1; i >= 0; i--) width += parseInt($el.css(props[i]).replace('px', ''), 10); return width; }; DrawingBoard.Utils.boxBorderWidth = function($el, withPadding, withMargin) { return DrawingBoard.Utils._boxBorderSize($el, withPadding, withMargin, 'width'); }; DrawingBoard.Utils.boxBorderHeight = function($el, withPadding, withMargin) { return DrawingBoard.Utils._boxBorderSize($el, withPadding, withMargin, 'height'); }; DrawingBoard.Utils.isColor = function(string) { if (!string || !string.length) return false; return (/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i).test(string) || $.inArray(string.substring(0, 3), ['rgb', 'hsl']) !== -1; }; /** * Packs an RGB color into a single integer. */ DrawingBoard.Utils.RGBToInt = function(r, g, b) { var c = 0; c |= (r & 255) << 16; c |= (g & 255) << 8; c |= (b & 255); return c; }; /** * Returns informations on the pixel located at (x,y). */ DrawingBoard.Utils.pixelAt = function(image, x, y) { var i = (y * image.width + x) * 4; var c = DrawingBoard.Utils.RGBToInt( image.data[i], image.data[i + 1], image.data[i + 2] ); return [ i, // INDEX x, // X y, // Y c // COLOR ]; }; /** * Compares two colors with the given tolerance (between 0 and 255). */ DrawingBoard.Utils.compareColors = function(a, b, tolerance) { if (tolerance === 0) { return (a === b); } var ra = (a >> 16) & 255, rb = (b >> 16) & 255, ga = (a >> 8) & 255, gb = (b >> 8) & 255, ba = a & 255, bb = b & 255; return (Math.abs(ra - rb) <= tolerance) && (Math.abs(ga - gb) <= tolerance) && (Math.abs(ba - bb) <= tolerance); }; (function() { var lastTime = 0; var vendors = ['ms', 'moz', 'webkit', 'o']; for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame']; } }());