PasswordCards/resources/js/jquery.tinycolorpicker.js

303 lines
8.7 KiB
JavaScript

;(function(factory) {
if(typeof define === 'function' && define.amd) {
define(['jquery'], factory);
}
else if(typeof exports === 'object') {
module.exports = factory(require("jquery"));
}
else {
factory(jQuery);
}
}
(function($) {
var pluginName = "tinycolorpicker"
, defaults = {
colors : ["#ffffff", "#A7194B","#FE2712","#FB9902","#FABC02","#FEFE33","#D0EA2B","#66B032","#0391CE","#0247FE","#3D01A5","#8601AF"]
, backgroundUrl : null
}
;
function Plugin($container, options) {
/**
* The options of the colorpicker extended with the defaults.
*
* @property options
* @type Object
*/
this.options = $.extend({}, defaults, options);
/**
* @property _defaults
* @type Object
* @private
* @default defaults
*/
this._defaults = defaults;
/**
* @property _name
* @type String
* @private
* @final
* @default 'tinycolorpicker'
*/
this._name = pluginName;
var self = this
, $track = $container.find(".track")
, $color = $container.find(".color")
, $canvas = null
, $colorInput = $container.find(".colorInput")
, $dropdown = $container.find(".dropdown")
, $dropdownItem = $dropdown.find("li").remove()
, context = null
, mouseIsDown = false
, hasCanvas = !!document.createElement("canvas").getContext
, touchEvents = "ontouchstart" in document.documentElement
;
/**
* The current active color in hex.
*
* @property colorHex
* @type String
* @default ""
*/
this.colorHex = "";
/**
* The current active color in rgb.
*
* @property colorRGB
* @type String
* @default ""
*/
this.colorRGB = "";
/**
* @method _initialize
* @private
*/
function _initialize() {
if(hasCanvas) {
$canvas = $("<canvas></canvas>");
$track.append($canvas);
context = $canvas[0].getContext( "2d" );
_setImage();
}
else {
$.each(self.options.colors, function(index, color) {
var $clone = $dropdownItem.clone();
$clone.css("backgroundColor", color);
$clone.attr("data-color", color);
$dropdown.append($clone);
});
}
_setEvents();
return self;
}
/**
* @method _setImage
* @private
*/
function _setImage() {
var colorPicker = new Image()
, backgroundUrl = $track.css("background-image").replace(/"/g, "").replace(/url\(|\)$/ig, "")
;
$track.css("background-image", "none");
$(colorPicker).load(function() {
$canvas.attr("width", this.width);
$canvas.attr("height", this.height);
context.drawImage(colorPicker, 0, 0, this.width, this.height);
});
colorPicker.src = self.options.backgroundUrl || backgroundUrl;
}
/**
* @method _setEvents
* @private
*/
function _setEvents() {
var eventType = touchEvents ? "touchstart" : "mousedown";
if(hasCanvas) {
$color.bind(eventType, function(event) {
event.preventDefault();
event.stopPropagation();
$track.toggle();
$(document).bind("mousedown.colorpicker", function(event) {
$(document).unbind(".colorpicker");
$track.hide();
});
});
if(!touchEvents) {
$canvas.mousedown(function(event) {
mouseIsDown = true;
_getColorCanvas(event);
$(document).bind("mouseup.colorpicker", function(event) {
mouseIsDown = false;
$(document).unbind(".colorpicker");
$track.hide();
return false;
});
return false;
});
$canvas.mousemove(_getColorCanvas);
}
else {
$canvas.bind("touchstart", function(event) {
mouseIsDown = true;
_getColorCanvas(event.originalEvent.touches[0]);
return false;
});
$canvas.bind("touchmove", function(event) {
_getColorCanvas(event.originalEvent.touches[0]);
return false;
});
$canvas.bind("touchend", function(event) {
mouseIsDown = false;
$track.hide();
return false;
});
}
}
else {
$color.bind("mousedown", function(event) {
event.preventDefault();
event.stopPropagation();
$dropdown.toggle();
});
$dropdown.delegate("li", "mousedown", function(event) {
event.preventDefault();
event.stopImmediatePropagation();
var color = $(this).attr("data-color");
self.setColor(color);
$dropdown.hide();
});
}
}
/**
* @method _getColorCanvas
* @private
*/
function _getColorCanvas(event) {
if(mouseIsDown) {
var $target = $(event.target)
, offset = $target.offset()
, colorData = context.getImageData(event.pageX - offset.left, event.pageY - offset.top, 1, 1).data
;
self.setColor("rgb(" + colorData[0] + "," + colorData[1] + "," + colorData[2] + ")");
/**
* The change event will trigger when a new color is set.
*
* @event change
*/
$container.trigger("change", [self.colorHex, self.colorRGB]);
}
}
/**
* Set the color to a given hex or rgb color.
*
* @method setColor
* @chainable
*/
this.setColor = function(color) {
if(color.indexOf("#") >= 0) {
self.colorHex = color;
self.colorRGB = self.hexToRgb(self.colorHex);
}
else {
self.colorRGB = color;
self.colorHex = self.rgbToHex(self.colorRGB);
}
$color.find(".colorInner").css("backgroundColor", self.colorHex);
$colorInput.val(self.colorHex);
};
/**
* Convert hex to rgb
*
* @method hexToRgb
* @chainable
*/
this.hexToRgb = function(hex) {
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return "rgb(" + parseInt(result[1], 16) + "," + parseInt(result[2], 16) + "," + parseInt(result[3], 16) + ")";
};
/**
* Convert rgb to hex
*
* @method rgbToHex
* @chainable
*/
this.rgbToHex = function(rgb) {
var result = rgb.match(/\d+/g);
function hex(x) {
var digits = new Array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F");
return isNaN(x) ? "00" : digits[(x - x % 16 ) / 16] + digits[x % 16];
}
return "#" + hex(result[0]) + hex(result[1]) + hex(result[2]);
};
return _initialize();
}
/**
* @class tinycolorpicker
* @constructor
* @param {Object} options
@param {Array} [options.colors=[]] fallback colors for old browsers (ie8-).
@param {String} [options.backgroundUrl=''] It will look for a css image on the track div. If not found it will look if there's a url in this property.
*/
$.fn[pluginName] = function(options) {
return this.each(function() {
if(!$.data(this, "plugin_" + pluginName)) {
$.data(this, "plugin_" + pluginName, new Plugin($(this), options));
}
});
};
}));