Commit 4a97d640 authored by bijh's avatar bijh

初始化spectrum项目

parents
{
"name": "spectrum",
"version": "1.8.0",
"main": ["./spectrum.css", "./spectrum.js"],
"docs": "http://bgrins.github.com/spectrum",
"homepage": "http://bgrins.github.com/spectrum",
"demo": "http://jsfiddle.net/bgrins/ctkY3/",
"dependencies": {
"jquery": ">=1.7.2"
},
"ignore": [
".gitignore",
".travis.yml",
"build/",
"docs/",
"example/",
"Gruntfile.js",
"LICENSE",
"README.md",
"test/"
]
}
// Spectrum Colorpicker
// Arabic (ar) localization
// https://github.com/bgrins/spectrum
(function ( $ ) {
var localization = $.spectrum.localization["ar"] = {
cancelText: "إلغاء",
chooseText: "إختار",
clearText: "إرجاع الألوان على ما كانت",
noColorSelectedText: "لم تختار أي لون",
togglePaletteMoreText: "أكثر",
togglePaletteLessText: "أقل"
};
$.extend($.fn.spectrum.defaults, localization);
})( jQuery );
// Spectrum Colorpicker
// German (de) localization
// https://github.com/bgrins/spectrum
(function ( $ ) {
var localization = $.spectrum.localization["de"] = {
cancelText: "Abbrechen",
chooseText: "Wählen",
clearText: "Farbauswahl zurücksetzen",
noColorSelectedText: "Keine Farbe ausgewählt",
togglePaletteMoreText: "Mehr",
togglePaletteLessText: "Weniger"
};
$.extend($.fn.spectrum.defaults, localization);
})( jQuery );
// Spectrum Colorpicker
// Danish (dk) localization
// https://github.com/bgrins/spectrum
(function ( $ ) {
var localization = $.spectrum.localization["dk"] = {
cancelText: "annuller",
chooseText: "Vælg"
};
$.extend($.fn.spectrum.defaults, localization);
})( jQuery );
// Spectrum Colorpicker
// Spanish (es) localization
// https://github.com/bgrins/spectrum
(function ( $ ) {
var localization = $.spectrum.localization["es"] = {
cancelText: "Cancelar",
chooseText: "Elegir",
clearText: "Borrar color seleccionado",
noColorSelectedText: "Ningún color seleccionado",
togglePaletteMoreText: "Más",
togglePaletteLessText: "Menos"
};
$.extend($.fn.spectrum.defaults, localization);
})( jQuery );
// Spectrum Colorpicker
// Persian (fa) localization
// https://github.com/bgrins/spectrum
(function ( $ ) {
var localization = $.spectrum.localization["fa"] = {
cancelText: "لغو",
chooseText: "انتخاب"
};
$.extend($.fn.spectrum.defaults, localization);
})( jQuery );
// Spectrum Colorpicker
// Finnish (fi) localization
// https://github.com/bgrins/spectrum
(function ( $ ) {
var localization = $.spectrum.localization["fi"] = {
cancelText: "Kumoa",
chooseText: "Valitse"
};
$.extend($.fn.spectrum.defaults, localization);
})( jQuery );
// Spectrum Colorpicker
// French (fr) localization
// https://github.com/bgrins/spectrum
(function ( $ ) {
var localization = $.spectrum.localization["fr"] = {
cancelText: "Annuler",
chooseText: "Valider",
clearText: "Effacer couleur sélectionnée",
noColorSelectedText: "Aucune couleur sélectionnée",
togglePaletteMoreText: "Plus",
togglePaletteLessText: "Moins"
};
$.extend($.fn.spectrum.defaults, localization);
})( jQuery );
// Spectrum Colorpicker
// Greek (gr) localization
// https://github.com/bgrins/spectrum
(function ( $ ) {
var localization = $.spectrum.localization["gr"] = {
cancelText: "Ακύρωση",
chooseText: "Επιλογή",
clearText: "Καθαρισμός επιλεγμένου χρώματος",
noColorSelectedText: "Δεν έχει επιλεχθεί κάποιο χρώμα",
togglePaletteMoreText: "Περισσότερα",
togglePaletteLessText: "Λιγότερα"
};
$.extend($.gr.spectrum.defaults, localization);
})( jQuery );
// Spectrum Colorpicker
// Hebrew (he) localization
// https://github.com/bgrins/spectrum
(function ( $ ) {
var localization = $.spectrum.localization["he"] = {
cancelText: "בטל בחירה",
chooseText: "בחר צבע",
clearText: "אפס בחירה",
noColorSelectedText: "לא נבחר צבע",
togglePaletteMoreText: "עוד צבעים",
togglePaletteLessText: "פחות צבעים"
};
$.extend($.fn.spectrum.defaults, localization);
})( jQuery );
// Spectrum Colorpicker
// Croatian (hr) localization
// https://github.com/bgrins/spectrum
(function ( $ ) {
var localization = $.spectrum.localization["hr"] = {
cancelText: "Odustani",
chooseText: "Odaberi",
clearText: "Poništi odabir",
noColorSelectedText: "Niti jedna boja nije odabrana",
togglePaletteMoreText: "Više",
togglePaletteLessText: "Manje"
};
$.extend($.fn.spectrum.defaults, localization);
})( jQuery );
// Spectrum Colorpicker
// Indonesia/Bahasa Indonesia (id) localization
// https://github.com/bgrins/spectrum
(function ( $ ) {
var localization = $.spectrum.localization["id"] = {
cancelText: "Batal",
chooseText: "Pilih",
clearText: "Hapus Pilihan Warna",
noColorSelectedText: "Warna Tidak Dipilih",
togglePaletteMoreText: "tambah",
togglePaletteLessText: "kurangi"
};
$.extend($.fn.spectrum.defaults, localization);
})( jQuery );
// Spectrum Colorpicker
// Italian (it) localization
// https://github.com/bgrins/spectrum
(function ( $ ) {
var localization = $.spectrum.localization["it"] = {
cancelText: "annulla",
chooseText: "scegli",
clearText: "Annulla selezione colore",
noColorSelectedText: "Nessun colore selezionato"
};
$.extend($.fn.spectrum.defaults, localization);
})( jQuery );
// Spectrum Colorpicker
// Japanese (ja) localization
// https://github.com/bgrins/spectrum
(function ( $ ) {
var localization = $.spectrum.localization["ja"] = {
cancelText: "中止",
chooseText: "選択"
};
$.extend($.fn.spectrum.defaults, localization);
})( jQuery );
// Spectrum Colorpicker
// Lithuanian (lt) localization
// https://github.com/liesislukas
(function ( $ ) {
var localization = $.spectrum.localization["lt"] = {
cancelText: "Atšaukti",
chooseText: "Pasirinkti",
clearText: "Išvalyti pasirinkimą",
noColorSelectedText: "Spalva nepasirinkta",
togglePaletteMoreText: "Daugiau",
togglePaletteLessText: "Mažiau"
};
$.extend($.fn.spectrum.defaults, localization);
})( jQuery );
// Spectrum Colorpicker
// Dutch (nl-nl) localization
// https://github.com/bgrins/spectrum
(function ( $ ) {
var localization = $.spectrum.localization["nl-nl"] = {
cancelText: "Annuleer",
chooseText: "Kies",
clearText: "Wis kleur selectie",
togglePaletteMoreText: 'Meer',
togglePaletteLessText: 'Minder'
};
$.extend($.fn.spectrum.defaults, localization);
})( jQuery );
// Spectrum Colorpicker
// Polish (pl) localization
// https://github.com/bgrins/spectrum
(function ( $ ) {
var localization = $.spectrum.localization["pl"] = {
cancelText: "Anuluj",
chooseText: "Wybierz",
clearText: "Usuń wybór koloru",
noColorSelectedText: "Nie wybrano koloru",
togglePaletteMoreText: "Więcej",
togglePaletteLessText: "Mniej"
};
$.extend($.fn.spectrum.defaults, localization);
})( jQuery );
// Spectrum Colorpicker
// Brazilian (pt-br) localization
// https://github.com/bgrins/spectrum
(function ( $ ) {
var localization = $.spectrum.localization["pt-br"] = {
cancelText: "Cancelar",
chooseText: "Escolher",
clearText: "Limpar cor selecionada",
noColorSelectedText: "Nenhuma cor selecionada",
togglePaletteMoreText: "Mais",
togglePaletteLessText: "Menos"
};
$.extend($.fn.spectrum.defaults, localization);
})( jQuery );
// Spectrum Colorpicker
// Russian (ru) localization
// https://github.com/bgrins/spectrum
(function ( $ ) {
var localization = $.spectrum.localization["ru"] = {
cancelText: "Отмена",
chooseText: "Выбрать",
clearText: "Сбросить",
noColorSelectedText: "Цвет не выбран",
togglePaletteMoreText: "Ещё",
togglePaletteLessText: "Скрыть"
};
$.extend($.fn.spectrum.defaults, localization);
})( jQuery );
// Spectrum Colorpicker
// Swedish (sv) localization
// https://github.com/bgrins/spectrum
(function ( $ ) {
var localization = $.spectrum.localization["sv"] = {
cancelText: "Avbryt",
chooseText: "Välj"
};
$.extend($.fn.spectrum.defaults, localization);
})( jQuery );
// Spectrum Colorpicker
// Turkish (tr) localization
// https://github.com/bgrins/spectrum
(function ( $ ) {
var localization = $.spectrum.localization["tr"] = {
cancelText: "iptal",
chooseText: "tamam"
};
$.extend($.fn.spectrum.defaults, localization);
})( jQuery );
// Spectrum Colorpicker
// Simplified Chinese (zh-cn) localization
// https://github.com/bgrins/spectrum
(function ( $ ) {
var localization = $.spectrum.localization["zh-cn"] = {
cancelText: "取消",
chooseText: "选择",
clearText: "清除",
togglePaletteMoreText: "更多选项",
togglePaletteLessText: "隐藏",
noColorSelectedText: "尚未选择任何颜色"
};
$.extend($.fn.spectrum.defaults, localization);
})( jQuery );
// Spectrum Colorpicker
// Traditional Chinese (zh-tw) localization
// https://github.com/bgrins/spectrum
(function ( $ ) {
var localization = $.spectrum.localization["zh-tw"] = {
cancelText: "取消",
chooseText: "選擇",
clearText: "清除",
togglePaletteMoreText: "更多選項",
togglePaletteLessText: "隱藏",
noColorSelectedText: "尚未選擇任何顏色"
};
$.extend($.fn.spectrum.defaults, localization);
})( jQuery );
<!doctype html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Spectrum - The No Hassle jQuery Colorpicker</title>
<meta name="description" content="Spectrum is a JavaScript colorpicker plugin using the jQuery framework. It is highly customizable, but can also be used as a simple input type=color polyfill">
<meta name="author" content="Brian Grinstead and Spectrum contributors">
<link rel="stylesheet" type="text/css" href="spectrum.css">
<link rel="stylesheet" type="text/css" href="docs/bootstrap.css">
<link rel="stylesheet" type="text/css" href="docs/docs.css">
<script type="text/javascript" src="docs/jquery-1.9.1.js"></script>
<script type="text/javascript" src="spectrum.js"></script>
<script type='text/javascript' src='docs/toc.js'></script>
<script type='text/javascript' src='docs/docs.js'></script>
</head>
<body>
<div id='header'>
<h1><a href='http://bgrins.github.com/spectrum'>Spectrum</a></h1> <h2><em>The No Hassle jQuery Colorpicker</em></h2>
<div id='links'>
<a href='http://github.com/bgrins/spectrum/zipball/1.8.0' class="btn btn-primary">Download Zip</a>
View the <a href='http://github.com/bgrins/spectrum'>Source code</a>.
Spectrum is a project by <a href='http://twitter.com/bgrins'>@bgrins</a>.
</div>
<br style='clear:both;' />
</div>
<div id='toc'></div>
<div id='toc-slider'></div>
<div id='docs'>
<div id='docs-content'>
<div id='switch-current'>
<input type='text' name='color1' id='pick1' value='#ddddff' />
<div id='switch-current-hsv' class='switch-current-output'></div>
<div id='switch-current-rgb' class='switch-current-output'></div>
<div id='switch-current-hex' class='switch-current-output'></div>
</div>
<div style='text-align:center;'>
<input id="full" />
</div>
<pre class='prettyprint hide' id='code-heading'>
&lt;input type='color' value='#f594d0' /&gt;
<input type='color' class='basic' value='#f594d0' />
</pre>
<h2 id="why">Why A Colorpicker?</h2>
<p><em>I wasn't satisfied with the solutions available for colorpicking</em>.
Many of them included a ton of images, were hard to skin or customize, or were very large plugins.
Here are the goals I had when making a new one:
</p>
<h3 id="why-footprint" class='point'>Small Footprint</h3>
<div class='note'>see a working <a href='http://jsfiddle.net/bgrins/ctkY3/'>jsFiddle example</a></div>
<p>Just include the needed CSS and JavaScript files, and you are ready to go! </p>
<pre class='prettyprint' id='code-subheading'>
&lt;script src='<a href='http://bgrins.github.com/spectrum/spectrum.js' target="_blank">spectrum.js</a>'&gt;&lt;/script&gt;
&lt;link rel='stylesheet' href='<a href='http://bgrins.github.com/spectrum/spectrum.css' target="_blank">spectrum.css</a>' /&gt;
</pre>
<p><strong>We don't need no stinkin' images!</strong></p>
<p>Nobody wants to add a bunch of code into their project. Spectrum is contained in two files, and both are careful not to mess with your existing code.</p>
<h3 id="why-polyfill" class='point'>Polyfill</h3>
<p>I wanted an option for the most basic use case, a polyfill for the <a href='http://dev.w3.org/html5/markup/input.color.html'>input[type=color]</a> HTML5 control.
This mode needs to work without JavaScript enabled - and fallback to an input[type=text] like other HTML5 inputs.
</p>
<p>If you don't want this behavior to happen, but still want to use spectrum elsewhere on the page, you can set <code>$.fn.spectrum.load = false;</code> right after loading the script file.</p>
<h3 id="why-customizable" class='point'>Customizable</h3>
<p>Just because you don't <em>have</em> to change anything to get it to work, doesn't mean you <em>can't</em>!
It is easy to skin and customize the plugin with CSS, and there are a wide range of modes and options to explore.
</p>
<h3 id="why-mobile" class='point'>Mobile Support</h3>
<p>Along with desktop browser support, I wanted a mobile colorpicker that was touch friendly, worked in iOS and Android, and used standards
that maximize future mobile support.
</p>
<h3 id="why-devtools" class='point'>Devtools</h3>
<p>
Believe it or not, <strong>this colorpicker lives inside of Chrome, Firefox, and Safari devtools</strong> to make picking colors easier for web developers and designers.
</p>
<p>
When I started the project, I wrote about <a href="http://www.briangrinstead.com/blog/chrome-developer-tools-colorpicker-concept">developer tools concept colorpicker implementation</a>. After that, I was <a href="http://groups.google.com/group/google-chrome-developer-tools/browse_thread/thread/4dd1e853b8051727/4549a6f0788885d4">contacted on the devtools mailing list</a> and got some initial feedback about the possibility of integrating it with devtools. Then I pulled the jQuery dependency out of a branch and I submitted a patch to the WebKit project.
</p>
<p>
From there, I opened a <a href="https://bugs.webkit.org/show_bug.cgi?id=71262">bug</a> to start working on it Web Inspector. 50+ comments and 10 patches later, the case <a href="http://www.webkit.org/blog/1804/last-week-in-webkit-calculated-css-values-and-the-translate-attribute/">landed in WebKit</a>. Here is the <a href='https://bugzilla.mozilla.org/show_bug.cgi?id=911702'>Firefox bug</a> where it was added.
</p>
<h2 id="modes">Modes</h2>
<h3 id="modes-custom" class='point'>Custom</h3>
<p>If you want to get more into the functionality, just create a normal input and initialize it as a normal jQuery plugin.
<strong>You can set a lot of options</strong> when initializing the colorpicker.
See the 'Options' section below.
</p>
<pre class='prettyprint'>
&lt;input type='text' id="custom" /&gt;
</pre>
<pre class='prettyprint'>
&lt;script&gt;
$("#custom").spectrum({
color: "#f00"
});
&lt;/script&gt;
</pre>
<div class='example'>
<input type='text' id='custom' />
</div>
<h3 id="modes-flat" class='point'>Flat</h3>
<p><strong>Flat</strong>
This means that it will always show up at full size,
and be positioned as an inline-block element.
Look to the left for a full sized flat picker.
</p>
<pre class='prettyprint'>
&lt;input type='text' id="flat" /&gt;
&lt;br/&gt;
&lt;input type='text' id="flat" /&gt;
</pre>
<pre class='prettyprint'>
$("#flat").spectrum({
flat: true,
showInput: true
});
$("#flatClearable").spectrum({
flat: true,
showInput: true,
allowEmpty:true
});
</pre>
<div class='example'>
<input type='text' id='flat' value="limegreen" />
<br/>
<input type='text' id='flatClearable' value="limegreen" />
</div>
<h3 id="modes-input" class='point'>input[type=color]</h3>
<p>
If you just want to provide a polyfill for the native color input,
the easiest way is to create an input with the type of color.
Once a user's browser supports a native color control, it will opt to use their native control instead.
</p>
<p><strong>Unlike the other modes, your value must be a 6 character hex value starting with a '#'.</strong> Why? Because the spec <a href='http://dev.w3.org/html5/markup/input.color.html#input.color.attrs.value'>says so</a>, that's why.
</p>
<pre class='prettyprint' id='code-subheading'>
&lt;input type='color' name='color' /&gt;
&lt;input type='color' name='color2' value='#3355cc' /&gt;
</pre>
<div class='example'>
<form method="get">
<input type='color' name='color' />
<input type='color' name='color2' value='#3355cc' />
<input type='color' name='color3' value='#000000' />
<input type="submit" />
</form>
</div>
<p><strong>That's it!</strong>
The field will degrade to a text input if the user does not have JavaScript enabled,
so that they will still be able to manually enter a color. You don't need to add a single line of code.
</p>
<!--
<div class="alert">
Heads up! Make sure you do not have a <code>maxlength</code> property set on your input. It has been known to break IE10.
</div>
-->
<h2 id="options">Options</h2>
<pre class='prettyprint'>
$("#picker").spectrum({
color: <strong>tinycolor</strong>,
flat: bool,
showInput: bool,
showInitial: bool,
allowEmpty: bool,
showAlpha: bool,
disabled: bool,
localStorageKey: string,
showPalette: bool,
showPaletteOnly: bool,
togglePaletteOnly: bool,
showSelectionPalette: bool,
clickoutFiresChange: bool,
cancelText: string,
chooseText: string,
togglePaletteMoreText: string,
togglePaletteLessText: string,
containerClassName: string,
replacerClassName: string,
preferredFormat: string,
maxSelectionSize: int,
palette: [[string]],
selectionPalette: [string]
});
</pre>
<div class="alert alert-info">
Tip: options can be specified in an options object in the <code>spectrum</code> initializer, like <code>$(element).spectrum({showAlpha: true })</code> or on the element's markup, like <code>&lt;input data-show-alpha="true" /&gt;</code>.
</div>
<h3 id="options-color">Color</h3>
<div class='option-content'>
<div class='description'>
<p>
The initial color will be set with the <code>color</code> option.
If you don't pass in a color, Spectrum will use the <code>value</code> attribute on the input.
</p>
<p>
The color parsing is based on the <a href='https://github.com/bgrins/TinyColor'>TinyColor</a> plugin.
This should parse any color string you throw at it.</p>
</p>
</div>
<pre class='prettyprint'>
&lt;input type='text' class='basic' value='red' /&gt;
&lt;input type='text' class='basic' value='#0f0' /&gt;
&lt;input type='text' class='basic' value='blue' /&gt;
&lt;br /&gt;
&lt;input type='text' class='override' /&gt;
&lt;br /&gt;
&lt;input type='text' class='startEmpty' value='' /&gt;
</pre>
<pre class='prettyprint'>
&lt;script&gt;
$(".basic").spectrum();
$(".override").spectrum({
color: "yellow"
});
(".startEmpty").spectrum({
allowEmpty: true
});
&lt;/script&gt;
</pre>
<div class='example'>
<input type='text' class='basic' value='red' />
<input type='text' class='basic' value='green' />
<input type='text' class='basic' value='blue' />
<br />
<input type='text' class='override' />
<br/>
<input type='text' class='startEmpty' value='' />
</div>
</div>
<h3 id="options-showInput">Show Input</h3>
<div class='option-content'>
<div class='description'>
<p>You can add an input to allow free form typing. The color parsing is very permissive in the allowed strings. See <a href='https://github.com/bgrins/TinyColor'>TinyColor</a> for more details.
</div>
<pre class='prettyprint'>
$("#showInput").spectrum({
showInput: true
});
$("#showInputWithClear").spectrum({
showInput: true,
allowEmpty:true
});
</pre>
<div class='example'>
<input type='text' name='showInput' id='showInput' />
<br/>
<input type='text' name='showInputWithClear' id='showInputWithClear' value='' />
</div>
</div>
<h3 id="options-showAlpha">Show Alpha</h3>
<div class='option-content'>
<div class='description'>
<p>You can allow alpha transparency selection. Check out these examples: </p>
</div>
<pre class='prettyprint'>
$("#showAlpha").spectrum({
showAlpha: true
});
</pre>
<div class='example'>
<input type='text' name='showAlpha' id='showAlpha' />
</div>
<div class='example'>
<input type='text' name='showAlphaWithInput' id='showAlphaWithInput' />
</div>
</div>
<h3 id="options-disabled">Disabled</h3>
<div class='option-content'>
<div class='description'>
<p>Spectrum can be automatically disabled if you pass in the <code>disabled</code> flag. Additionally, if the input that you initialize spectrum on is disabled, this will be the default value. Note: you <strong>cannot</strong> enable spectrum if the input is disabled (see below).</p>
</div>
<pre class='prettyprint'>
$("#disabled").spectrum({
disabled: true
});
$("input:disabled").spectrum({
});
</pre>
<div class='example'>
<input type='text' name='disabled' id='disabled' value='lightblue' />
<input type='text' disabled value='lightblue' />
<button id='toggle-disabled' class='btn'>Toggle Disabled</button>
</div>
</div>
<h3 id="options-showPalette">Show Palette</h3>
<div class='option-content'>
<div class='description'>
<p>Spectrum can show a palette below the colorpicker to make it convenient for users to choose from frequently or recently used colors. When the colorpicker is closed, the current color will be added to the palette if it isn't there already. Check it out here: </p>
</div>
<pre class='prettyprint'>
$("#showPalette").spectrum({
showPalette: true,
palette: [
['black', 'white', 'blanchedalmond'],
['rgb(255, 128, 0);', 'hsv 100 70 50', 'lightyellow']
]
});
</pre>
<div class='example'>
<input type='text' name='showPalette' id='showPalette' value='lightblue' />
</div>
</div>
<h3 id="options-showPaletteOnly">Show Palette Only</h3>
<div class='option-content'>
<div class='note'>see a working <a href='http://jsfiddle.net/bgrins/S45tW/'>jsFiddle example</a></div>
<div class='description'>
<p>If you'd like, spectrum can show the palettes you specify, and nothing else.</p>
</div>
<pre class='prettyprint'>
$("#showPaletteOnly").spectrum({
showPaletteOnly: true,
showPalette:true,
color: 'blanchedalmond',
palette: [
['black', 'white', 'blanchedalmond',
'rgb(255, 128, 0);', 'hsv 100 70 50'],
['red', 'yellow', 'green', 'blue', 'violet']
]
});
</pre>
<div class='example'>
<span class='label label-result'>
Result
</span>
<input type='text' name='showPaletteOnly' id='showPaletteOnly' />
</div>
</div>
<h3 id="options-togglePaletteOnly">Toggle Palette Only</h3>
<div class='option-content'>
<div class='description'>
<p>Spectrum can show a button to toggle the colorpicker next to the palette. This way, the user can choose from a limited number of colors in the palette, but still be able to pick a color that's not in the palette.<br />
The default value for <code>togglePaletteOnly</code> is FALSE. Set it to TRUE to enable the Toggle button.<br /><br />
You can also change the text on the Toggle Button with the options <code>togglePaletteMoreText</code> (default is "more") and <code>togglePaletteLessText</code> (default is "less").</p>
</div>
<pre class='prettyprint'>
$("#togglePaletteOnly").spectrum({
showPaletteOnly: true,
togglePaletteOnly: true,
togglePaletteMoreText: 'more',
togglePaletteLessText: 'less',
color: 'blanchedalmond',
palette: [
["#000","#444","#666","#999","#ccc","#eee","#f3f3f3","#fff"],
["#f00","#f90","#ff0","#0f0","#0ff","#00f","#90f","#f0f"],
["#f4cccc","#fce5cd","#fff2cc","#d9ead3","#d0e0e3","#cfe2f3","#d9d2e9","#ead1dc"],
["#ea9999","#f9cb9c","#ffe599","#b6d7a8","#a2c4c9","#9fc5e8","#b4a7d6","#d5a6bd"],
["#e06666","#f6b26b","#ffd966","#93c47d","#76a5af","#6fa8dc","#8e7cc3","#c27ba0"],
["#c00","#e69138","#f1c232","#6aa84f","#45818e","#3d85c6","#674ea7","#a64d79"],
["#900","#b45f06","#bf9000","#38761d","#134f5c","#0b5394","#351c75","#741b47"],
["#600","#783f04","#7f6000","#274e13","#0c343d","#073763","#20124d","#4c1130"]
]
});
</pre>
<div class='example'>
<span class='label label-result'>
Result
</span>
<input type='text' name='togglePaletteOnly' id='togglePaletteOnly' />
</div>
</div>
<h3 id="options-showSelectionPalette">Show Selection Palette</h3>
<div class='option-content'>
<div class='description'>
<p>Spectrum can keep track of what has been selected by the user with the <code>showSelectionPalette</code> option.</p>
<p>If the <code>localStorageKey</code> option is defined, the selection will be saved in the browser's localStorage object</p>
</div>
<pre class='prettyprint'>
$("#showSelectionPalette").spectrum({
showPalette: true,
showSelectionPalette: true, // true by default
palette: [ ]
});
$("#showSelectionPaletteStorage").spectrum({
showPalette: true,
showSelectionPalette: true,
palette: [ ],
localStorageKey: "spectrum.homepage", // Any Spectrum with the same string will share selection
});
</pre>
<div class='example'>
<span class='label label-info'>This colorpicker will store what you pick:</span><br /><br />
<input type='text' name='showSelectionPalette' id='showSelectionPalette' value='lightblue' /><br /><br />
<span class='label label-info'>Try switching between the two colorpickers or reloading your page, the chosen colors are always available:</span><br /><br />
<input type='text' name='showSelectionPaletteStorage' id='showSelectionPaletteStorage' value='lightblue' />
<input type='text' name='showSelectionPaletteStorage2' id='showSelectionPaletteStorage2' value='pink' />
</div>
</div>
<h3 id="options-selectionPalette">Selection Palette</h3>
<div class='option-content'>
<div class='description'>
<p>The default values inside of the selection palette. Make sure that <a href="#options-showSelectionPalette">showSelectionPalette</a> and <a href="#options-showPalette">showPalette</a> are both enabled.</p>
<p>If a <code>localStorageKey</code> is defined, then this value will be overwritten by it.</p>
</div>
<pre class='prettyprint'>
$("#selectionPalette").spectrum({
showPalette: true,
palette: [ ],
showSelectionPalette: true, // true by default
selectionPalette: ["red", "green", "blue"]
});
</pre>
<div class='example'>
<span class='label label-info'>This colorpicker has default values in the selection palette:</span><br /><br />
<input type='text' name='selectionPalette' id='selectionPalette' value='orange' />
</div>
</div>
<h3 id="options-maxSelectionSize">Max Selection Size</h3>
<div class='option-content'>
<div class='description'>
<p>This is how many elements are allowed in the <a href="#options-selectionPalette">selectionPallete</a> at once.</p>
<p>Elements will be removed from the palette in first in - first out order if this limit is reached.</p>
</div>
<pre class='prettyprint'>
$("#maxSelectionSize").spectrum({
showPalette: true,
palette: [ ],
showSelectionPalette: true, // true by default
selectionPalette: ["red", "green", "blue"],
maxSelectionSize: 2
});
</pre>
<div class='example'>
<span class='label label-info'>This colorpicker starts removing selection palette colors older than 2:</span><br /><br />
<input type='text' name='maxSelectionSize' id='maxSelectionSize' value='red' />
</div>
</div>
<h3 id="options-hideAfterPaletteSelect">Hide After Palette Select</h3>
<div class='option-content'>
<div class='description'>
<p>You can have the colorpicker automatically hide after a palette color is selected.</p>
</div>
<pre class='prettyprint'>
$("#hideAfterPaletteSelect").spectrum({
showPaletteOnly: true,
showPalette:true,
hideAfterPaletteSelect:true,
color: 'blanchedalmond',
palette: [
['black', 'white', 'blanchedalmond',
'rgb(255, 128, 0);', 'hsv 100 70 50'],
['red', 'yellow', 'green', 'blue', 'violet']
]
});
</pre>
<div class='example'>
<span class='label label-result'>
Result
</span>
<input type='text' name='hideAfterPaletteSelect' id='hideAfterPaletteSelect' />
</div>
</div>
<h3 id="options-clickoutFiresChange">Clickout Fires Change</h3>
<div class='option-content'>
<div class='description'>
<p>
When clicking outside of the colorpicker, you can force it to fire a <code>change</code> event rather than having it revert the change. This is <code>true</code> by default.
</p>
</div>
<pre class='prettyprint'>
$("#clickoutFiresChange").spectrum({
clickoutFiresChange: true
});
$("#clickoutDoesntChange").spectrum({
clickoutFiresChange: false
});
</pre>
<div class='example'>
<input type='text' name='clickoutFiresChange' id='clickoutFiresChange' value='goldenrod' />
<input type='text' name='clickoutDoesntFireChange' id='clickoutDoesntFireChange' value='goldenrod' />
</div>
</div>
<h3 id="options-showInitial">Show Initial</h3>
<div class='option-content'>
<div class='description'>
<p>
Spectrum can show the color that was initially set when opening.
This provides an easy way to click back to what was set when opened.
</p>
</div>
<pre class='prettyprint'>
$("#showInitial").spectrum({
showInitial: true
});
</pre>
<div class='example'>
<input type='text' name='showInitial' id='showInitial' value='goldenrod' />
</div>
</div>
<h3 id="options-showInputAndInitial">Show Input and Initial</h3>
<div class='option-content'>
<div class='description'>
<p>If you specify both the <code>showInput</code> and <code>showInitial</code> options, the CSS keeps things in order by wrapping the buttons to the bottom row, and shrinking the input. <em>Note: this is all customizable via CSS.</em></p>
</div>
<pre class='prettyprint'>
$("#showInputAndInitial").spectrum({
showInitial: true,
showInput: true
});
</pre>
<div class='example'>
<input type='text' name='showInputAndInitial' id='showInputAndInitial' value='goldenrod' />
</div>
</div>
<h3>Show Input, Initial, and Clear</h3>
<div class='option-content'>
<div class='description'>
<p>If you specify both the <code>showInput</code>, <code>showInitial</code>, and <code>allowEmpty</code> options, the CSS keeps things in order by wrapping the buttons to the bottom row, and shrinking the input. <em>Note: this is all customizable via CSS.</em></p>
</div>
<pre class='prettyprint'>
$("#showInputInitialClear").spectrum({
allowEmpty:true,
showInitial: true,
showInput: true
});
</pre>
<div class='example'>
<input type='text' name='showInputInitialClear' id='showInputInitialClear' value='' />
</div>
</div>
<h3 id="options-buttonText">Button Text</h3>
<div class='option-content'>
<div class='description'>
<p>You can set the button's text using <code>cancelText</code> and <code>chooseText</code> properties.</p>
</div>
<pre class='prettyprint'>
$("#buttonText").spectrum({
allowEmpty:true,
chooseText: "Alright",
cancelText: "No way"
});
</pre>
<div class='example'>
<input type='text' name='buttonText' id='buttonText' value='orangered' />
</div>
</div>
<h3 id="options-showButtons">Show Buttons</h3>
<div class='option-content'>
<div class='description'>
<p>
You can show or hide the buttons using the <code>showButtons</code> property.
If there are no buttons, the behavior will be to fire the `change` event (and update the original input) when the picker is closed.
</p>
</div>
<pre class='prettyprint'>
$("#hideButtons").spectrum({
showButtons: false
});
</pre>
<div class='example'>
<input type='text' name='hideButtons' id='hideButtons' value='orangered' />
</div>
</div>
<h3 id="options-containerClassName">Container Class Name</h3>
<div class='option-content'>
<div class='description'>
<p>
You can add an additional class name to the just the container element using the <code>containerClassName</code> property.
</p>
</div>
<pre class='prettyprint'>
$("#containerClassName").spectrum({
containerClassName: 'awesome'
});
</pre>
<pre class='prettyprint'>
.awesome {
background: purple;
}
</pre>
<style type='text/css'>
.awesome {
background: purple;
}
</style>
<div class='example'>
<input type='text' name='containerClassName' id='containerClassName' value='orangered' />
</div>
</div>
<h3 id="options-replacerClassName">Replacer Class Name</h3>
<div class='option-content'>
<div class='description'>
<p>
You can add an additional class name to just the replacer element using the <code>replacerClassName</code> property.
</p>
</div>
<pre class='prettyprint'>
$("#replacerClassName").spectrum({
replacerClassName: 'awesome'
});
</pre>
<pre class='prettyprint'>
.awesome {
background: purple;
}
</pre>
<style type='text/css'>
.awesome {
background: purple;
}
</style>
<div class='example'>
<input type='text' name='replacerClassName' id='replacerClassName' value='orangered' />
</div>
</div>
<h3 id="options-preferredFormat">Preferred Format</h3>
<div class='option-content'>
<div class='description'>
<p>You can set the format that is displayed in the text box.</p>
<p>This will also change the format that is displayed in the titles from the palette swatches.</p>
</div>
<pre class='prettyprint'>
$("#preferredHex").spectrum({
preferredFormat: "hex",
showInput: true,
showPalette: true,
palette: [["red", "rgba(0, 255, 0, .5)", "rgb(0, 0, 255)"]]
});
$("#preferredHex3").spectrum({
preferredFormat: "hex3",
showInput: true,
showPalette: true,
palette: [["red", "rgba(0, 255, 0, .5)", "rgb(0, 0, 255)"]]
});
$("#preferredHsl").spectrum({
preferredFormat: "hsl",
showInput: true,
showPalette: true,
palette: [["red", "rgba(0, 255, 0, .5)", "rgb(0, 0, 255)"]]
});
$("#preferredRgb").spectrum({
preferredFormat: "rgb",
showInput: true,
showPalette: true,
palette: [["red", "rgba(0, 255, 0, .5)", "rgb(0, 0, 255)"]]
});
$("#preferredName").spectrum({
preferredFormat: "name",
showInput: true,
showPalette: true,
palette: [["red", "rgba(0, 255, 0, .5)", "rgb(0, 0, 255)"]]
});
$("#preferredNone").spectrum({
showInput: true,
showPalette: true,
palette: [["red", "rgba(0, 255, 0, .5)", "rgb(0, 0, 255)"]]
});
</pre>
<div class='example'>
<div class='alert alert-info'>Hex</div>
<input type='text' name='preferredHex' id='preferredHex' value='orangered' />
<div class='alert alert-info'>Hex (3 Characters If Possible)</div>
<input type='text' name='preferredHex3' id='preferredHex3' value='orangered' />
<div class='alert alert-info'>Hsl</div>
<input type='text' name='preferredHsl' id='preferredHsl' value='orangered' />
<div class='alert alert-info'>Rgb</div>
<input type='text' name='preferredRgb' id='preferredRgb' value='orangered' />
<div class='alert alert-info'>Name (Falls back to hex)</div>
<input type='text' name='preferredName' id='preferredName' value='orangered' />
<div class='alert alert-info'>None (Depends on input - try changing formats with the text box)</div>
<input type='text' name='preferredNone' id='preferredNone' value='orangered' />
</div>
</div>
<h3 id="options-appendTo">appendTo</h3>
<div class='option-content'>
<div class='description'>
<p>You can choose which element the colorpicker container is appended to (default is <code>"body"</code>). This can be any valid object taken into the jQuery <a href="https://api.jquery.com/appendTo/">appendTo</a> function.</p>
<p>Changing this can help resolve issues with opening the colorpicker in a modal dialog or fixed position container, for instance.</p>
</div>
</div>
<h2 id="events">Events</h2>
<pre class='prettyprint'>
// Events can be bound in the intialization process as options:
$("#picker").spectrum({
move: function(tinycolor) { },
show: function(tinycolor) { },
hide: function(tinycolor) { },
beforeShow: function(tinycolor) { },
});
// Alternatively, they can be added as an event listener:
$("#picker").on('move.spectrum', function(e, tinycolor) { });
$("#picker").on('show.spectrum', function(e, tinycolor) { });
$("#picker").on('hide.spectrum', function(e, tinycolor) { });
$("#picker").on('beforeShow.spectrum', function(e, tinycolor) { });
</pre>
<h3 id="events-change">change</h3>
<div class='option-content'>
<div class='description'>
<p>Called as the original input changes. Only happens when the input is closed or the 'Choose' button is clicked.</p>
</div>
<pre class='prettyprint'>
change: function(color) {
color.toHexString(); // #ff0000
}
</pre>
<div class='example'>
<input type='text' value='blanchedalmond' name='changeOnMoveNo' id='changeOnMoveNo' />
<em id='changeOnMoveNoLabel' class='em-label'></em>
</div>
</div>
<h3 id="events-move">move</h3>
<div class='option-content'>
<div class='description'>
<p>Called as the user moves around within the colorpicker</p>
</div>
<pre class='prettyprint'>
move: function(color) {
color.toHexString(); // #ff0000
}
</pre>
<div class='example'>
<input type='text' value='blanchedalmond' name='changeOnMove' id='changeOnMove' />
<em id='changeOnMoveLabel' class='em-label'></em>
</div>
</div>
<h3 id="events-hide">hide</h3>
<div class='option-content'>
<div class='description'>
<p>
Called after the colorpicker is hidden.
This happens when clicking outside of the picker while it is open.
Note, when any colorpicker on the page is shown it will hide any that are already open.
This event is ignored on a flat colorpicker.
</p>
</div>
<pre class='prettyprint'>
hide: function(color) {
color.toHexString(); // #ff0000
}
</pre>
<div class='example'>
<input type='text' value='blanchedalmond' name='eventhide' id='eventhide' />
<em id='eventhideLabel' class='em-label'></em>
</div>
</div>
<h3 id="events-show">show</h3>
<div class='option-content'>
<div class='description'>
<p>
Called after the colorpicker is opened.
This is ignored on a flat colorpicker.
Note, when any colorpicker on the page is shown it will hide any that are already open.
</p>
</div>
<pre class='prettyprint'>
show: function(color) {
color.toHexString(); // #ff0000
}
</pre>
<div class='example'>
<input type='text' value='blanchedalmond' name='eventshow' id='eventshow' />
<em id='eventshowLabel' class='em-label'></em>
</div>
</div>
<h3 id="events-beforeShow">beforeShow</h3>
<div class='option-content'>
<div class='description'>
<p>
You can prevent the colorpicker from showing up if you return false in the beforeShow event.
This event is ignored on a flat colorpicker.
</p>
</div>
<pre class='prettyprint'>
beforeShow: function(color) {
return false; // Will never show up
}
</pre>
<div class='example'>
<input type='text' value='blanchedalmond' name='beforeShow' id='beforeShow' />
</div>
</div>
<h3 id="events-dragstart">dragstart</h3>
<div class='option-content'>
<div class='description'>
<p>
Called at the beginning of a drag event on either
hue slider, alpha slider, or main color picker areas
</p>
</div>
<pre class='prettyprint'>
$(element).on("dragstart.spectrum"): function(e, color) {
color.toHexString(); // #ff0000
}
</pre>
<div class='example'>
<input type='text' value='blanchedalmond' name='eventdragstart' id='eventdragstart' />
<em id='eventdragstartLabel' class='em-label'></em>
</div>
</div>
<h3 id="events-dragstop">dragstop</h3>
<div class='option-content'>
<div class='description'>
<p>
Called at the end of a drag event on either
hue slider, alpha slider, or main color picker areas
</p>
</div>
<pre class='prettyprint'>
$(element).on("dragstop.spectrum"): function(e, color) {
color.toHexString(); // #ff0000
}
</pre>
<div class='example'>
<input type='text' value='blanchedalmond' name='eventdragstop' id='eventdragstop' />
<em id='eventdragstopLabel' class='em-label'></em>
</div>
</div>
<h2 id="methods">Methods</h2>
<pre class='prettyprint'>
$("#picker").spectrum("show");
$("#picker").spectrum("hide");
$("#picker").spectrum("toggle");
$("#picker").spectrum("get");
$("#picker").spectrum("set", colorString);
$("#picker").spectrum("container");
$("#picker").spectrum("reflow");
$("#picker").spectrum("destroy");
$("#picker").spectrum("enable");
$("#picker").spectrum("disable");
$("#picker").spectrum("option", optionName);
$("#picker").spectrum("option", optionName, newOptionValue);
</pre>
<h3 id="methods-show">show</h3>
<div class='option-content'>
<div class='description'>
<p>
Shows the colorpicker.
</p>
</div>
</div>
<h3 id="methods-hide">hide</h3>
<div class='option-content'>
<div class='description'>
<p>
Hides the colorpicker.
</p>
</div>
</div>
<h3 id="methods-toggle">toggle</h3>
<div class='option-content'>
<div class='description'>
<p>
Toggles the colorpicker.
</p>
<p class="warning">
<b>Warning:</b> If you are calling toggle from a click handler, make sure you <code>return false</code> to prevent the colorpicker from immediately hiding after it is toggled.
</p>
</div>
<pre class='prettyprint'>
$("#btn-toggle").click(function() {
$("#toggle").spectrum("toggle");
return false;
});
</pre>
<div class='example'>
<input type='text' value='blanchedalmond' name='toggle' id='toggle' />
<button id='btn-toggle'>Toggle</button>
</div>
</div>
<h3 id="methods-get">get</h3>
<div class='option-content'>
<div class='description'>
<p>
Gets the current value from the colorpicker.
</p>
</div>
</div>
<h3 id="methods-set">set</h3>
<div class='option-content'>
<div class='description'>
<p>
Setting the colorpicker programmatically will update the original input.
</p>
<p>
Note: this will <strong>not</strong> fire the <code>change</code> event,
to prevent infinite loops from calling <code>set</code> from within <code>change</code>.
</p>
</div>
<pre class='prettyprint'>
&lt;input type='text' value='blanchedalmond' name='triggerSet' id='triggerSet' /&gt;
&lt;input type='text' placeholder='Enter A Color' id='enterAColor' /&gt;
&lt;button id='btnEnterAColor'&gt;Trigger Set&lt;/button&gt;
&lt;script&gt;
$("#triggerSet").spectrum();
// Show the original input to demonstrate the value changing when calling `set`
$("#triggerSet").show();
$("#btnEnterAColor").click(function() {
$("#triggerSet").spectrum("set", $("#enterAColor").val());
});
&lt;/script&gt;
</pre>
<div class='example'>
<input type='text' value='blanchedalmond' name='triggerSet' id='triggerSet' /><br /><br />
<input type='text' placeholder='Enter A Color' id='enterAColor' /><button id='btnEnterAColor'>Trigger Set</button>
</div>
</div>
<h3 id="methods-container">container</h3>
<div class='option-content'>
<div class='description'>
<p>
Retrieves the container element of the colorpicker, in case you want to manaully position it or do other things.
</p>
</div>
</div>
<h3 id="methods-reflow">reflow</h3>
<div class='option-content'>
<div class='description'>
<p>
Resets the positioning of the container element. This could be used was hidden when initialized, or if the colorpicker is inside of a moving area.
</p>
</div>
</div>
<h3 id="methods-destroy">destroy</h3>
<div class='option-content'>
<div class='description'>
<p>
Removes the colorpicker functionality and restores the element to its original state.
</p>
</div>
</div>
<h3 id="methods-enable">enable</h3>
<div class='option-content'>
<div class='description'>
<p>
Allows selection of the colorpicker component. If it is already enabled, this method does nothing.
</p>
<p>
Additionally, this will cause the original (now hidden) input to be set as disabled.
</p>
</div>
</div>
<h3 id="methods-disable">disable</h3>
<div class='option-content'>
<div class='description'>
<p>
Disables selection of the colorpicker component. Adds the <code>sp-disabled</code> class onto the replacer element. If it is already disabled, this method does nothing.
</p>
<p>
Additionally, this will remove the <code>disabled</code> property on the original (now hidden).
</p>
</div>
</div>
<h3 id="methods-option">option</h3>
<div class='option-content'>
<div class='description'>
<p>
Calling <code>option</code> with an option name will return the current value of that option. So, for example:
</p>
<pre class='prettyprint'>
$("input").spectrum({
showInput: true
});
$("input").spectrum("option", "showInput"); // true
</pre>
<p>
Calling <code>option</code> with an option name and an option value will set the option to the new value.
</p>
<pre class='prettyprint'>
$("input").spectrum({
showInput: true
});
$("input").spectrum("option", "showInput", false);
$("input").spectrum("option", "showInput"); // false
</pre>
</div>
</div>
<h2 id="skinning">Skinning</h2>
<p>Since it is all built with HTML/CSS, you can skin it easily. There are two parts to the <a href='https://github.com/bgrins/spectrum/blob/master/spectrum.css'>spectrum.css</a> file, the core rules (at the top of the file), and the themable rules (at the bottom). Feel free to tweak these rules to make it look how you want.</p>
<h3 id="skinning-nonInput" class='point'>Non-input elements</h3>
<p>
You can use any element you would like to trigger the colorpicker: <a href='#' id='openWithLink'>Click me to open a colorpicker</a>, though it is strongly recommended to stick with <code>&lt;input&gt;</code> tags.
</p>
<h2 id="details">Nitty Gritty</h2>
<h3 id="details-browserSupport" class='point'>Browser Support</h3>
<p>I wanted this to work in the latest and greatest browsers, but also target backwords compatibility and <strong>mobile support</strong>.
Here are the currently supported browers:
<ul>
<li>IE <small>6+</small></li>
<li>Chrome <small>4+</small></li>
<li>Firefox <small>3.6+</small></li>
<li>Safari <small>4+</small></li>
<li>Opera <small>11.1+</small></li>
<li>iOS</li>
</ul>
<h3 id="details-ieImplementation" class='point'>IE Implementation</h3>
<p>
IE Support is provided using
<a href='http://msdn.microsoft.com/en-us/library/ms532997(v=vs.85).aspx'>proprietary filters</a>.
Other browsers use CSS gradients.
</p>
<h3 id="details-acceptedColorInputs" class='point'>Accepted Color Inputs</h3>
<p>Spectrum will use the color passed in to initialize. If there is no color passed in,
it will try to parse a color based on the <code>value</code> of the input. The color parsing is based on the <a href='https://github.com/bgrins/TinyColor'>TinyColor</a> plugin, and accepts many forms of input:</p>
<pre class='prettyprint'>
red
#fff
fff
#ffffff
ffffff
rgb(255, 0, 0)
rgb 255 0 0
hsl(0, 100, 50)
hsl(0, 100%, 50%)
hsl 0 100 50
hsl 0 100% 50%
hsv(0, 100%, 100%)
hsv(0, 100, 100)
hsv 0 100% 100%
hsv 0 100 100
</pre>
<p>It also provides the following forms of output:</p>
<pre class='prettyprint'>
var t = $("#element").spectrum("get");
t.toHex() // "ff0000"
t.toHexString() // "#ff0000"
t.toRgb() // {"r":255,"g":0,"b":0}
t.toRgbString() // "rgb(255, 0, 0)"
t.toHsv() // {"h":0,"s":1,"v":1}
t.toHsvString() // "hsv(0, 100%, 100%)"
t.toHsl() // {"h":0,"s":1,"l":0.5}
t.toHslString() // "hsl(0, 100%, 50%)"
t.toName() // "red"
</pre>
<div class='footer'>
<h2>Share</h2>
<p>
If you've made it this far, please share one of these links to help others find this project!
<br />
<a href='http://bgrins.github.com/spectrum'>JavaScript Colorpicker</a> |
<a href='http://bgrins.github.com/spectrum'>jQuery Colorpicker</a> |
<a href='http://bgrins.github.com/spectrum'>Mobile Colorpicker</a> |
<a href='http://bgrins.github.com/spectrum'>Spectrum colorpicker</a>
</p>
<p>
Thanks to all the <a href='https://github.com/bgrins/spectrum/graphs/contributors'>spectrum contributors</a> for committing code, documentation, and <a href='https://github.com/bgrins/spectrum/tree/master/i18n'>translations</a>.
</p>
<p>
If you want to let me (<a href='http://twitter.com/bgrins'>@bgrins</a>) know you are using it, send me a link where it can be seen or add it to the <a href='https://github.com/bgrins/spectrum/wiki/Sites-Using-Spectrum'>list of projects using Spectrum</a>!
</p>
</div>
</div>
</div>
<script type="text/javascript" src="docs/prettify.js"></script>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-8259845-4']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</body>
</html>
{
"name": "spectrum-colorpicker",
"description": "Spectrum: the no hassle jQuery colorpicker",
"version": "1.8.0",
"main": "spectrum.js",
"license": "MIT",
"keywords": ["jquery-plugin", "ecosystem:jquery", "color", "colorpicker", "ui"],
"homepage": "http://bgrins.github.com/spectrum",
"repository": {
"type": "git",
"url": "https://bgrins.github.com/spectrum"
},
"author": {
"name" : "Brian Grinstead",
"email" : "briangrinstead@gmail.com",
"url" : "http://briangrinstead.com/"
},
"devDependencies": {
"grunt": "~0.4.0",
"grunt-contrib-jshint": "~0.4.3",
"grunt-contrib-qunit": "~0.2.0",
"grunt-contrib-uglify": "~0.2.0"
}
}
/***
Spectrum Colorpicker v1.8.0
https://github.com/bgrins/spectrum
Author: Brian Grinstead
License: MIT
***/
.sp-container {
position:absolute;
top:0;
left:0;
display:inline-block;
*display: inline;
*zoom: 1;
/* https://github.com/bgrins/spectrum/issues/40 */
z-index: 9999994;
overflow: hidden;
}
.sp-container.sp-flat {
position: relative;
}
/* Fix for * { box-sizing: border-box; } */
.sp-container,
.sp-container * {
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
/* http://ansciath.tumblr.com/post/7347495869/css-aspect-ratio */
.sp-top {
position:relative;
width: 100%;
display:inline-block;
}
.sp-top-inner {
position:absolute;
top:0;
left:0;
bottom:0;
right:0;
}
.sp-color {
position: absolute;
top:0;
left:0;
bottom:0;
right:20%;
}
.sp-hue {
position: absolute;
top:0;
right:0;
bottom:0;
left:84%;
height: 100%;
}
.sp-clear-enabled .sp-hue {
top:33px;
height: 77.5%;
}
.sp-fill {
padding-top: 80%;
}
.sp-sat, .sp-val {
position: absolute;
top:0;
left:0;
right:0;
bottom:0;
}
.sp-alpha-enabled .sp-top {
margin-bottom: 18px;
}
.sp-alpha-enabled .sp-alpha {
display: block;
}
.sp-alpha-handle {
position:absolute;
top:-4px;
bottom: -4px;
width: 6px;
left: 50%;
cursor: pointer;
border: 1px solid black;
background: white;
opacity: .8;
}
.sp-alpha {
display: none;
position: absolute;
bottom: -14px;
right: 0;
left: 0;
height: 8px;
}
.sp-alpha-inner {
border: solid 1px #333;
}
.sp-clear {
display: none;
}
.sp-clear.sp-clear-display {
background-position: center;
}
.sp-clear-enabled .sp-clear {
display: block;
position:absolute;
top:0px;
right:0;
bottom:0;
left:84%;
height: 28px;
}
/* Don't allow text selection */
.sp-container, .sp-replacer, .sp-preview, .sp-dragger, .sp-slider, .sp-alpha, .sp-clear, .sp-alpha-handle, .sp-container.sp-dragging .sp-input, .sp-container button {
-webkit-user-select:none;
-moz-user-select: -moz-none;
-o-user-select:none;
user-select: none;
}
.sp-container.sp-input-disabled .sp-input-container {
display: none;
}
.sp-container.sp-buttons-disabled .sp-button-container {
display: none;
}
.sp-container.sp-palette-buttons-disabled .sp-palette-button-container {
display: none;
}
.sp-palette-only .sp-picker-container {
display: none;
}
.sp-palette-disabled .sp-palette-container {
display: none;
}
.sp-initial-disabled .sp-initial {
display: none;
}
/* Gradients for hue, saturation and value instead of images. Not pretty... but it works */
.sp-sat {
background-image: -webkit-gradient(linear, 0 0, 100% 0, from(#FFF), to(rgba(204, 154, 129, 0)));
background-image: -webkit-linear-gradient(left, #FFF, rgba(204, 154, 129, 0));
background-image: -moz-linear-gradient(left, #fff, rgba(204, 154, 129, 0));
background-image: -o-linear-gradient(left, #fff, rgba(204, 154, 129, 0));
background-image: -ms-linear-gradient(left, #fff, rgba(204, 154, 129, 0));
background-image: linear-gradient(to right, #fff, rgba(204, 154, 129, 0));
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr=#FFFFFFFF, endColorstr=#00CC9A81)";
filter : progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr='#FFFFFFFF', endColorstr='#00CC9A81');
}
.sp-val {
background-image: -webkit-gradient(linear, 0 100%, 0 0, from(#000000), to(rgba(204, 154, 129, 0)));
background-image: -webkit-linear-gradient(bottom, #000000, rgba(204, 154, 129, 0));
background-image: -moz-linear-gradient(bottom, #000, rgba(204, 154, 129, 0));
background-image: -o-linear-gradient(bottom, #000, rgba(204, 154, 129, 0));
background-image: -ms-linear-gradient(bottom, #000, rgba(204, 154, 129, 0));
background-image: linear-gradient(to top, #000, rgba(204, 154, 129, 0));
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#00CC9A81, endColorstr=#FF000000)";
filter : progid:DXImageTransform.Microsoft.gradient(startColorstr='#00CC9A81', endColorstr='#FF000000');
}
.sp-hue {
background: -moz-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
background: -ms-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
background: -o-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
background: -webkit-gradient(linear, left top, left bottom, from(#ff0000), color-stop(0.17, #ffff00), color-stop(0.33, #00ff00), color-stop(0.5, #00ffff), color-stop(0.67, #0000ff), color-stop(0.83, #ff00ff), to(#ff0000));
background: -webkit-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
background: linear-gradient(to bottom, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
}
/* IE filters do not support multiple color stops.
Generate 6 divs, line them up, and do two color gradients for each.
Yes, really.
*/
.sp-1 {
height:17%;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0000', endColorstr='#ffff00');
}
.sp-2 {
height:16%;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff00', endColorstr='#00ff00');
}
.sp-3 {
height:17%;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ff00', endColorstr='#00ffff');
}
.sp-4 {
height:17%;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ffff', endColorstr='#0000ff');
}
.sp-5 {
height:16%;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0000ff', endColorstr='#ff00ff');
}
.sp-6 {
height:17%;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff00ff', endColorstr='#ff0000');
}
.sp-hidden {
display: none !important;
}
/* Clearfix hack */
.sp-cf:before, .sp-cf:after { content: ""; display: table; }
.sp-cf:after { clear: both; }
.sp-cf { *zoom: 1; }
/* Mobile devices, make hue slider bigger so it is easier to slide */
@media (max-device-width: 480px) {
.sp-color { right: 40%; }
.sp-hue { left: 63%; }
.sp-fill { padding-top: 60%; }
}
.sp-dragger {
border-radius: 5px;
height: 5px;
width: 5px;
border: 1px solid #fff;
background: #000;
cursor: pointer;
position:absolute;
top:0;
left: 0;
}
.sp-slider {
position: absolute;
top:0;
cursor:pointer;
height: 3px;
left: -1px;
right: -1px;
border: 1px solid #000;
background: white;
opacity: .8;
}
/*
Theme authors:
Here are the basic themeable display options (colors, fonts, global widths).
See http://bgrins.github.io/spectrum/themes/ for instructions.
*/
.sp-container {
border-radius: 0;
background-color: #ECECEC;
border: solid 1px #f0c49B;
padding: 0;
}
.sp-container, .sp-container button, .sp-container input, .sp-color, .sp-hue, .sp-clear {
font: normal 12px "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Geneva, Verdana, sans-serif;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
}
.sp-top {
margin-bottom: 3px;
}
.sp-color, .sp-hue, .sp-clear {
border: solid 1px #666;
}
/* Input */
.sp-input-container {
float:right;
width: 100px;
margin-bottom: 4px;
}
.sp-initial-disabled .sp-input-container {
width: 100%;
}
.sp-input {
font-size: 12px !important;
border: 1px inset;
padding: 4px 5px;
margin: 0;
width: 100%;
background:transparent;
border-radius: 3px;
color: #222;
}
.sp-input:focus {
border: 1px solid orange;
}
.sp-input.sp-validation-error {
border: 1px solid red;
background: #fdd;
}
.sp-picker-container , .sp-palette-container {
float:left;
position: relative;
padding: 10px;
padding-bottom: 300px;
margin-bottom: -290px;
}
.sp-picker-container {
width: 172px;
border-left: solid 1px #fff;
}
/* Palettes */
.sp-palette-container {
border-right: solid 1px #ccc;
}
.sp-palette-only .sp-palette-container {
border: 0;
}
.sp-palette .sp-thumb-el {
display: block;
position:relative;
float:left;
width: 24px;
height: 15px;
margin: 3px;
cursor: pointer;
border:solid 2px transparent;
}
.sp-palette .sp-thumb-el:hover, .sp-palette .sp-thumb-el.sp-thumb-active {
border-color: orange;
}
.sp-thumb-el {
position:relative;
}
/* Initial */
.sp-initial {
float: left;
border: solid 1px #333;
}
.sp-initial span {
width: 30px;
height: 25px;
border:none;
display:block;
float:left;
margin:0;
}
.sp-initial .sp-clear-display {
background-position: center;
}
/* Buttons */
.sp-palette-button-container,
.sp-button-container {
float: right;
}
/* Replacer (the little preview div that shows up instead of the <input>) */
.sp-replacer {
margin:0;
overflow:hidden;
cursor:pointer;
padding: 4px;
display:inline-block;
*zoom: 1;
*display: inline;
border: solid 1px #91765d;
background: #eee;
color: #333;
vertical-align: middle;
}
.sp-replacer:hover, .sp-replacer.sp-active {
border-color: #F0C49B;
color: #111;
}
.sp-replacer.sp-disabled {
cursor:default;
border-color: silver;
color: silver;
}
.sp-dd {
padding: 2px 0;
height: 16px;
line-height: 16px;
float:left;
font-size:10px;
}
.sp-preview {
position:relative;
width:25px;
height: 20px;
border: solid 1px #222;
margin-right: 5px;
float:left;
z-index: 0;
}
.sp-palette {
*width: 220px;
max-width: 220px;
}
.sp-palette .sp-thumb-el {
width:16px;
height: 16px;
margin:2px 1px;
border: solid 1px #d0d0d0;
}
.sp-container {
padding-bottom:0;
}
/* Buttons: http://hellohappy.org/css3-buttons/ */
.sp-container button {
background-color: #eeeeee;
background-image: -webkit-linear-gradient(top, #eeeeee, #cccccc);
background-image: -moz-linear-gradient(top, #eeeeee, #cccccc);
background-image: -ms-linear-gradient(top, #eeeeee, #cccccc);
background-image: -o-linear-gradient(top, #eeeeee, #cccccc);
background-image: linear-gradient(to bottom, #eeeeee, #cccccc);
border: 1px solid #ccc;
border-bottom: 1px solid #bbb;
border-radius: 3px;
color: #333;
font-size: 14px;
line-height: 1;
padding: 5px 4px;
text-align: center;
text-shadow: 0 1px 0 #eee;
vertical-align: middle;
}
.sp-container button:hover {
background-color: #dddddd;
background-image: -webkit-linear-gradient(top, #dddddd, #bbbbbb);
background-image: -moz-linear-gradient(top, #dddddd, #bbbbbb);
background-image: -ms-linear-gradient(top, #dddddd, #bbbbbb);
background-image: -o-linear-gradient(top, #dddddd, #bbbbbb);
background-image: linear-gradient(to bottom, #dddddd, #bbbbbb);
border: 1px solid #bbb;
border-bottom: 1px solid #999;
cursor: pointer;
text-shadow: 0 1px 0 #ddd;
}
.sp-container button:active {
border: 1px solid #aaa;
border-bottom: 1px solid #888;
-webkit-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
-moz-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
-ms-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
-o-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
}
.sp-cancel {
font-size: 11px;
color: #d93f3f !important;
margin:0;
padding:2px;
margin-right: 5px;
vertical-align: middle;
text-decoration:none;
}
.sp-cancel:hover {
color: #d93f3f !important;
text-decoration: underline;
}
.sp-palette span:hover, .sp-palette span.sp-thumb-active {
border-color: #000;
}
.sp-preview, .sp-alpha, .sp-thumb-el {
position:relative;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);
}
.sp-preview-inner, .sp-alpha-inner, .sp-thumb-inner {
display:block;
position:absolute;
top:0;left:0;bottom:0;right:0;
}
.sp-palette .sp-thumb-inner {
background-position: 50% 50%;
background-repeat: no-repeat;
}
.sp-palette .sp-thumb-light.sp-thumb-active .sp-thumb-inner {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAIVJREFUeNpiYBhsgJFMffxAXABlN5JruT4Q3wfi/0DsT64h8UD8HmpIPCWG/KemIfOJCUB+Aoacx6EGBZyHBqI+WsDCwuQ9mhxeg2A210Ntfo8klk9sOMijaURm7yc1UP2RNCMbKE9ODK1HM6iegYLkfx8pligC9lCD7KmRof0ZhjQACDAAceovrtpVBRkAAAAASUVORK5CYII=);
}
.sp-palette .sp-thumb-dark.sp-thumb-active .sp-thumb-inner {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAMdJREFUOE+tkgsNwzAMRMugEAahEAahEAZhEAqlEAZhEAohEAYh81X2dIm8fKpEspLGvudPOsUYpxE2BIJCroJmEW9qJ+MKaBFhEMNabSy9oIcIPwrB+afvAUFoK4H0tMaQ3XtlrggDhOVVMuT4E5MMG0FBbCEYzjYT7OxLEvIHQLY2zWwQ3D+9luyOQTfKDiFD3iUIfPk8VqrKjgAiSfGFPecrg6HN6m/iBcwiDAo7WiBeawa+Kwh7tZoSCGLMqwlSAzVDhoK+6vH4G0P5wdkAAAAASUVORK5CYII=);
}
.sp-clear-display {
background-repeat:no-repeat;
background-position: center;
background-image: url(data:image/gif;base64,R0lGODlhFAAUAPcAAAAAAJmZmZ2dnZ6enqKioqOjo6SkpKWlpaampqenp6ioqKmpqaqqqqurq/Hx8fLy8vT09PX19ff39/j4+Pn5+fr6+vv7+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAP8ALAAAAAAUABQAAAihAP9FoPCvoMGDBy08+EdhQAIJCCMybCDAAYUEARBAlFiQQoMABQhKUJBxY0SPICEYHBnggEmDKAuoPMjS5cGYMxHW3IiT478JJA8M/CjTZ0GgLRekNGpwAsYABHIypcAgQMsITDtWJYBR6NSqMico9cqR6tKfY7GeBCuVwlipDNmefAtTrkSzB1RaIAoXodsABiZAEFB06gIBWC1mLVgBa0AAOw==);
}
// Spectrum Colorpicker v1.8.0
// https://github.com/bgrins/spectrum
// Author: Brian Grinstead
// License: MIT
(function (factory) {
"use strict";
if (typeof define === 'function' && define.amd) { // AMD
define(['jquery'], factory);
}
else if (typeof exports == "object" && typeof module == "object") { // CommonJS
module.exports = factory(require('jquery'));
}
else { // Browser
factory(jQuery);
}
})(function($, undefined) {
"use strict";
var defaultOpts = {
// Callbacks
beforeShow: noop,
move: noop,
change: noop,
show: noop,
hide: noop,
// Options
color: false,
flat: false,
showInput: false,
allowEmpty: false,
showButtons: true,
clickoutFiresChange: true,
showInitial: false,
showPalette: false,
showPaletteOnly: false,
hideAfterPaletteSelect: false,
togglePaletteOnly: false,
showSelectionPalette: true,
localStorageKey: false,
appendTo: "body",
maxSelectionSize: 7,
cancelText: "cancel",
chooseText: "choose",
togglePaletteMoreText: "more",
togglePaletteLessText: "less",
clearText: "Clear Color Selection",
noColorSelectedText: "No Color Selected",
preferredFormat: false,
className: "", // Deprecated - use containerClassName and replacerClassName instead.
containerClassName: "",
replacerClassName: "",
showAlpha: false,
theme: "sp-light",
palette: [["#ffffff", "#000000", "#ff0000", "#ff8000", "#ffff00", "#008000", "#0000ff", "#4b0082", "#9400d3"]],
selectionPalette: [],
disabled: false,
offset: null
},
spectrums = [],
IE = !!/msie/i.exec( window.navigator.userAgent ),
rgbaSupport = (function() {
function contains( str, substr ) {
return !!~('' + str).indexOf(substr);
}
var elem = document.createElement('div');
var style = elem.style;
style.cssText = 'background-color:rgba(0,0,0,.5)';
return contains(style.backgroundColor, 'rgba') || contains(style.backgroundColor, 'hsla');
})(),
replaceInput = [
"<div class='sp-replacer'>",
"<div class='sp-preview'><div class='sp-preview-inner'></div></div>",
"<div class='sp-dd'>&#9660;</div>",
"</div>"
].join(''),
markup = (function () {
// IE does not support gradients with multiple stops, so we need to simulate
// that for the rainbow slider with 8 divs that each have a single gradient
var gradientFix = "";
if (IE) {
for (var i = 1; i <= 6; i++) {
gradientFix += "<div class='sp-" + i + "'></div>";
}
}
return [
"<div class='sp-container sp-hidden'>",
"<div class='sp-palette-container'>",
"<div class='sp-palette sp-thumb sp-cf'></div>",
"<div class='sp-palette-button-container sp-cf'>",
"<button type='button' class='sp-palette-toggle'></button>",
"</div>",
"</div>",
"<div class='sp-picker-container'>",
"<div class='sp-top sp-cf'>",
"<div class='sp-fill'></div>",
"<div class='sp-top-inner'>",
"<div class='sp-color'>",
"<div class='sp-sat'>",
"<div class='sp-val'>",
"<div class='sp-dragger'></div>",
"</div>",
"</div>",
"</div>",
"<div class='sp-clear sp-clear-display'>",
"</div>",
"<div class='sp-hue'>",
"<div class='sp-slider'></div>",
gradientFix,
"</div>",
"</div>",
"<div class='sp-alpha'><div class='sp-alpha-inner'><div class='sp-alpha-handle'></div></div></div>",
"</div>",
"<div class='sp-input-container sp-cf'>",
"<input class='sp-input' type='text' spellcheck='false' />",
"</div>",
"<div class='sp-initial sp-thumb sp-cf'></div>",
"<div class='sp-button-container sp-cf'>",
"<a class='sp-cancel' href='#'></a>",
"<button type='button' class='sp-choose'></button>",
"</div>",
"</div>",
"</div>"
].join("");
})();
function paletteTemplate (p, color, className, opts) {
var html = [];
for (var i = 0; i < p.length; i++) {
var current = p[i];
if(current) {
var tiny = tinycolor(current);
var c = tiny.toHsl().l < 0.5 ? "sp-thumb-el sp-thumb-dark" : "sp-thumb-el sp-thumb-light";
c += (tinycolor.equals(color, current)) ? " sp-thumb-active" : "";
var formattedString = tiny.toString(opts.preferredFormat || "rgb");
var swatchStyle = rgbaSupport ? ("background-color:" + tiny.toRgbString()) : "filter:" + tiny.toFilter();
html.push('<span title="' + formattedString + '" data-color="' + tiny.toRgbString() + '" class="' + c + '"><span class="sp-thumb-inner" style="' + swatchStyle + ';" /></span>');
} else {
var cls = 'sp-clear-display';
html.push($('<div />')
.append($('<span data-color="" style="background-color:transparent;" class="' + cls + '"></span>')
.attr('title', opts.noColorSelectedText)
)
.html()
);
}
}
return "<div class='sp-cf " + className + "'>" + html.join('') + "</div>";
}
function hideAll() {
for (var i = 0; i < spectrums.length; i++) {
if (spectrums[i]) {
spectrums[i].hide();
}
}
}
function instanceOptions(o, callbackContext) {
var opts = $.extend({}, defaultOpts, o);
opts.callbacks = {
'move': bind(opts.move, callbackContext),
'change': bind(opts.change, callbackContext),
'show': bind(opts.show, callbackContext),
'hide': bind(opts.hide, callbackContext),
'beforeShow': bind(opts.beforeShow, callbackContext)
};
return opts;
}
function spectrum(element, o) {
var opts = instanceOptions(o, element),
flat = opts.flat,
showSelectionPalette = opts.showSelectionPalette,
localStorageKey = opts.localStorageKey,
theme = opts.theme,
callbacks = opts.callbacks,
resize = throttle(reflow, 10),
visible = false,
isDragging = false,
dragWidth = 0,
dragHeight = 0,
dragHelperHeight = 0,
slideHeight = 0,
slideWidth = 0,
alphaWidth = 0,
alphaSlideHelperWidth = 0,
slideHelperHeight = 0,
currentHue = 0,
currentSaturation = 0,
currentValue = 0,
currentAlpha = 1,
palette = [],
paletteArray = [],
paletteLookup = {},
selectionPalette = opts.selectionPalette.slice(0),
maxSelectionSize = opts.maxSelectionSize,
draggingClass = "sp-dragging",
shiftMovementDirection = null;
var doc = element.ownerDocument,
body = doc.body,
boundElement = $(element),
disabled = false,
container = $(markup, doc).addClass(theme),
pickerContainer = container.find(".sp-picker-container"),
dragger = container.find(".sp-color"),
dragHelper = container.find(".sp-dragger"),
slider = container.find(".sp-hue"),
slideHelper = container.find(".sp-slider"),
alphaSliderInner = container.find(".sp-alpha-inner"),
alphaSlider = container.find(".sp-alpha"),
alphaSlideHelper = container.find(".sp-alpha-handle"),
textInput = container.find(".sp-input"),
paletteContainer = container.find(".sp-palette"),
initialColorContainer = container.find(".sp-initial"),
cancelButton = container.find(".sp-cancel"),
clearButton = container.find(".sp-clear"),
chooseButton = container.find(".sp-choose"),
toggleButton = container.find(".sp-palette-toggle"),
isInput = boundElement.is("input"),
isInputTypeColor = isInput && boundElement.attr("type") === "color" && inputTypeColorSupport(),
shouldReplace = isInput && !flat,
replacer = (shouldReplace) ? $(replaceInput).addClass(theme).addClass(opts.className).addClass(opts.replacerClassName) : $([]),
offsetElement = (shouldReplace) ? replacer : boundElement,
previewElement = replacer.find(".sp-preview-inner"),
initialColor = opts.color || (isInput && boundElement.val()),
colorOnShow = false,
currentPreferredFormat = opts.preferredFormat,
clickoutFiresChange = !opts.showButtons || opts.clickoutFiresChange,
isEmpty = !initialColor,
allowEmpty = opts.allowEmpty && !isInputTypeColor;
function applyOptions() {
if (opts.showPaletteOnly) {
opts.showPalette = true;
}
toggleButton.text(opts.showPaletteOnly ? opts.togglePaletteMoreText : opts.togglePaletteLessText);
if (opts.palette) {
palette = opts.palette.slice(0);
paletteArray = $.isArray(palette[0]) ? palette : [palette];
paletteLookup = {};
for (var i = 0; i < paletteArray.length; i++) {
for (var j = 0; j < paletteArray[i].length; j++) {
var rgb = tinycolor(paletteArray[i][j]).toRgbString();
paletteLookup[rgb] = true;
}
}
}
container.toggleClass("sp-flat", flat);
container.toggleClass("sp-input-disabled", !opts.showInput);
container.toggleClass("sp-alpha-enabled", opts.showAlpha);
container.toggleClass("sp-clear-enabled", allowEmpty);
container.toggleClass("sp-buttons-disabled", !opts.showButtons);
container.toggleClass("sp-palette-buttons-disabled", !opts.togglePaletteOnly);
container.toggleClass("sp-palette-disabled", !opts.showPalette);
container.toggleClass("sp-palette-only", opts.showPaletteOnly);
container.toggleClass("sp-initial-disabled", !opts.showInitial);
container.addClass(opts.className).addClass(opts.containerClassName);
reflow();
}
function initialize() {
if (IE) {
container.find("*:not(input)").attr("unselectable", "on");
}
applyOptions();
if (shouldReplace) {
boundElement.after(replacer).hide();
}
if (!allowEmpty) {
clearButton.hide();
}
if (flat) {
boundElement.after(container).hide();
}
else {
var appendTo = opts.appendTo === "parent" ? boundElement.parent() : $(opts.appendTo);
if (appendTo.length !== 1) {
appendTo = $("body");
}
appendTo.append(container);
}
updateSelectionPaletteFromStorage();
offsetElement.bind("click.spectrum touchstart.spectrum", function (e) {
if (!disabled) {
toggle();
}
e.stopPropagation();
if (!$(e.target).is("input")) {
e.preventDefault();
}
});
if(boundElement.is(":disabled") || (opts.disabled === true)) {
disable();
}
// Prevent clicks from bubbling up to document. This would cause it to be hidden.
container.click(stopPropagation);
// Handle user typed input
textInput.change(setFromTextInput);
textInput.bind("paste", function () {
setTimeout(setFromTextInput, 1);
});
textInput.keydown(function (e) { if (e.keyCode == 13) { setFromTextInput(); } });
cancelButton.text(opts.cancelText);
cancelButton.bind("click.spectrum", function (e) {
e.stopPropagation();
e.preventDefault();
revert();
hide();
});
clearButton.attr("title", opts.clearText);
clearButton.bind("click.spectrum", function (e) {
e.stopPropagation();
e.preventDefault();
isEmpty = true;
move();
if(flat) {
//for the flat style, this is a change event
updateOriginalInput(true);
}
});
chooseButton.text(opts.chooseText);
chooseButton.bind("click.spectrum", function (e) {
e.stopPropagation();
e.preventDefault();
if (IE && textInput.is(":focus")) {
textInput.trigger('change');
}
if (isValid()) {
updateOriginalInput(true);
hide();
}
});
toggleButton.text(opts.showPaletteOnly ? opts.togglePaletteMoreText : opts.togglePaletteLessText);
toggleButton.bind("click.spectrum", function (e) {
e.stopPropagation();
e.preventDefault();
opts.showPaletteOnly = !opts.showPaletteOnly;
// To make sure the Picker area is drawn on the right, next to the
// Palette area (and not below the palette), first move the Palette
// to the left to make space for the picker, plus 5px extra.
// The 'applyOptions' function puts the whole container back into place
// and takes care of the button-text and the sp-palette-only CSS class.
if (!opts.showPaletteOnly && !flat) {
container.css('left', '-=' + (pickerContainer.outerWidth(true) + 5));
}
applyOptions();
});
draggable(alphaSlider, function (dragX, dragY, e) {
currentAlpha = (dragX / alphaWidth);
isEmpty = false;
if (e.shiftKey) {
currentAlpha = Math.round(currentAlpha * 10) / 10;
}
move();
}, dragStart, dragStop);
draggable(slider, function (dragX, dragY) {
currentHue = parseFloat(dragY / slideHeight);
isEmpty = false;
if (!opts.showAlpha) {
currentAlpha = 1;
}
move();
}, dragStart, dragStop);
draggable(dragger, function (dragX, dragY, e) {
// shift+drag should snap the movement to either the x or y axis.
if (!e.shiftKey) {
shiftMovementDirection = null;
}
else if (!shiftMovementDirection) {
var oldDragX = currentSaturation * dragWidth;
var oldDragY = dragHeight - (currentValue * dragHeight);
var furtherFromX = Math.abs(dragX - oldDragX) > Math.abs(dragY - oldDragY);
shiftMovementDirection = furtherFromX ? "x" : "y";
}
var setSaturation = !shiftMovementDirection || shiftMovementDirection === "x";
var setValue = !shiftMovementDirection || shiftMovementDirection === "y";
if (setSaturation) {
currentSaturation = parseFloat(dragX / dragWidth);
}
if (setValue) {
currentValue = parseFloat((dragHeight - dragY) / dragHeight);
}
isEmpty = false;
if (!opts.showAlpha) {
currentAlpha = 1;
}
move();
}, dragStart, dragStop);
if (!!initialColor) {
set(initialColor);
// In case color was black - update the preview UI and set the format
// since the set function will not run (default color is black).
updateUI();
currentPreferredFormat = opts.preferredFormat || tinycolor(initialColor).format;
addColorToSelectionPalette(initialColor);
}
else {
updateUI();
}
if (flat) {
show();
}
function paletteElementClick(e) {
if (e.data && e.data.ignore) {
set($(e.target).closest(".sp-thumb-el").data("color"));
move();
}
else {
set($(e.target).closest(".sp-thumb-el").data("color"));
move();
updateOriginalInput(true);
if (opts.hideAfterPaletteSelect) {
hide();
}
}
return false;
}
var paletteEvent = IE ? "mousedown.spectrum" : "click.spectrum touchstart.spectrum";
paletteContainer.delegate(".sp-thumb-el", paletteEvent, paletteElementClick);
initialColorContainer.delegate(".sp-thumb-el:nth-child(1)", paletteEvent, { ignore: true }, paletteElementClick);
}
function updateSelectionPaletteFromStorage() {
if (localStorageKey && window.localStorage) {
// Migrate old palettes over to new format. May want to remove this eventually.
try {
var oldPalette = window.localStorage[localStorageKey].split(",#");
if (oldPalette.length > 1) {
delete window.localStorage[localStorageKey];
$.each(oldPalette, function(i, c) {
addColorToSelectionPalette(c);
});
}
}
catch(e) { }
try {
selectionPalette = window.localStorage[localStorageKey].split(";");
}
catch (e) { }
}
}
function addColorToSelectionPalette(color) {
if (showSelectionPalette) {
var rgb = tinycolor(color).toRgbString();
if (!paletteLookup[rgb] && $.inArray(rgb, selectionPalette) === -1) {
selectionPalette.push(rgb);
while(selectionPalette.length > maxSelectionSize) {
selectionPalette.shift();
}
}
if (localStorageKey && window.localStorage) {
try {
window.localStorage[localStorageKey] = selectionPalette.join(";");
}
catch(e) { }
}
}
}
function getUniqueSelectionPalette() {
var unique = [];
if (opts.showPalette) {
for (var i = 0; i < selectionPalette.length; i++) {
var rgb = tinycolor(selectionPalette[i]).toRgbString();
if (!paletteLookup[rgb]) {
unique.push(selectionPalette[i]);
}
}
}
return unique.reverse().slice(0, opts.maxSelectionSize);
}
function drawPalette() {
var currentColor = get();
var html = $.map(paletteArray, function (palette, i) {
return paletteTemplate(palette, currentColor, "sp-palette-row sp-palette-row-" + i, opts);
});
updateSelectionPaletteFromStorage();
if (selectionPalette) {
html.push(paletteTemplate(getUniqueSelectionPalette(), currentColor, "sp-palette-row sp-palette-row-selection", opts));
}
paletteContainer.html(html.join(""));
}
function drawInitial() {
if (opts.showInitial) {
var initial = colorOnShow;
var current = get();
initialColorContainer.html(paletteTemplate([initial, current], current, "sp-palette-row-initial", opts));
}
}
function dragStart() {
if (dragHeight <= 0 || dragWidth <= 0 || slideHeight <= 0) {
reflow();
}
isDragging = true;
container.addClass(draggingClass);
shiftMovementDirection = null;
boundElement.trigger('dragstart.spectrum', [ get() ]);
}
function dragStop() {
isDragging = false;
container.removeClass(draggingClass);
boundElement.trigger('dragstop.spectrum', [ get() ]);
}
function setFromTextInput() {
var value = textInput.val();
if ((value === null || value === "") && allowEmpty) {
set(null);
updateOriginalInput(true);
}
else {
var tiny = tinycolor(value);
if (tiny.isValid()) {
set(tiny);
updateOriginalInput(true);
}
else {
textInput.addClass("sp-validation-error");
}
}
}
function toggle() {
if (visible) {
hide();
}
else {
show();
}
}
function show() {
var event = $.Event('beforeShow.spectrum');
if (visible) {
reflow();
return;
}
boundElement.trigger(event, [ get() ]);
if (callbacks.beforeShow(get()) === false || event.isDefaultPrevented()) {
return;
}
hideAll();
visible = true;
$(doc).bind("keydown.spectrum", onkeydown);
$(doc).bind("click.spectrum", clickout);
$(window).bind("resize.spectrum", resize);
replacer.addClass("sp-active");
container.removeClass("sp-hidden");
reflow();
updateUI();
colorOnShow = get();
drawInitial();
callbacks.show(colorOnShow);
boundElement.trigger('show.spectrum', [ colorOnShow ]);
}
function onkeydown(e) {
// Close on ESC
if (e.keyCode === 27) {
hide();
}
}
function clickout(e) {
// Return on right click.
if (e.button == 2) { return; }
// If a drag event was happening during the mouseup, don't hide
// on click.
if (isDragging) { return; }
if (clickoutFiresChange) {
updateOriginalInput(true);
}
else {
revert();
}
hide();
}
function hide() {
// Return if hiding is unnecessary
if (!visible || flat) { return; }
visible = false;
$(doc).unbind("keydown.spectrum", onkeydown);
$(doc).unbind("click.spectrum", clickout);
$(window).unbind("resize.spectrum", resize);
replacer.removeClass("sp-active");
container.addClass("sp-hidden");
callbacks.hide(get());
boundElement.trigger('hide.spectrum', [ get() ]);
}
function revert() {
set(colorOnShow, true);
}
function set(color, ignoreFormatChange) {
if (tinycolor.equals(color, get())) {
// Update UI just in case a validation error needs
// to be cleared.
updateUI();
return;
}
var newColor, newHsv;
if (!color && allowEmpty) {
isEmpty = true;
} else {
isEmpty = false;
newColor = tinycolor(color);
newHsv = newColor.toHsv();
currentHue = (newHsv.h % 360) / 360;
currentSaturation = newHsv.s;
currentValue = newHsv.v;
currentAlpha = newHsv.a;
}
updateUI();
if (newColor && newColor.isValid() && !ignoreFormatChange) {
currentPreferredFormat = opts.preferredFormat || newColor.getFormat();
}
}
function get(opts) {
opts = opts || { };
if (allowEmpty && isEmpty) {
return null;
}
return tinycolor.fromRatio({
h: currentHue,
s: currentSaturation,
v: currentValue,
a: Math.round(currentAlpha * 100) / 100
}, { format: opts.format || currentPreferredFormat });
}
function isValid() {
return !textInput.hasClass("sp-validation-error");
}
function move() {
updateUI();
callbacks.move(get());
boundElement.trigger('move.spectrum', [ get() ]);
}
function updateUI() {
textInput.removeClass("sp-validation-error");
updateHelperLocations();
// Update dragger background color (gradients take care of saturation and value).
var flatColor = tinycolor.fromRatio({ h: currentHue, s: 1, v: 1 });
dragger.css("background-color", flatColor.toHexString());
// Get a format that alpha will be included in (hex and names ignore alpha)
var format = currentPreferredFormat;
if (currentAlpha < 1 && !(currentAlpha === 0 && format === "name")) {
if (format === "hex" || format === "hex3" || format === "hex6" || format === "name") {
format = "rgb";
}
}
var realColor = get({ format: format }),
displayColor = '';
//reset background info for preview element
previewElement.removeClass("sp-clear-display");
previewElement.css('background-color', 'transparent');
if (!realColor && allowEmpty) {
// Update the replaced elements background with icon indicating no color selection
previewElement.addClass("sp-clear-display");
}
else {
var realHex = realColor.toHexString(),
realRgb = realColor.toRgbString();
// Update the replaced elements background color (with actual selected color)
if (rgbaSupport || realColor.alpha === 1) {
previewElement.css("background-color", realRgb);
}
else {
previewElement.css("background-color", "transparent");
previewElement.css("filter", realColor.toFilter());
}
if (opts.showAlpha) {
var rgb = realColor.toRgb();
rgb.a = 0;
var realAlpha = tinycolor(rgb).toRgbString();
var gradient = "linear-gradient(left, " + realAlpha + ", " + realHex + ")";
if (IE) {
alphaSliderInner.css("filter", tinycolor(realAlpha).toFilter({ gradientType: 1 }, realHex));
}
else {
alphaSliderInner.css("background", "-webkit-" + gradient);
alphaSliderInner.css("background", "-moz-" + gradient);
alphaSliderInner.css("background", "-ms-" + gradient);
// Use current syntax gradient on unprefixed property.
alphaSliderInner.css("background",
"linear-gradient(to right, " + realAlpha + ", " + realHex + ")");
}
}
displayColor = realColor.toString(format);
}
// Update the text entry input as it changes happen
if (opts.showInput) {
textInput.val(displayColor);
}
if (opts.showPalette) {
drawPalette();
}
drawInitial();
}
function updateHelperLocations() {
var s = currentSaturation;
var v = currentValue;
if(allowEmpty && isEmpty) {
//if selected color is empty, hide the helpers
alphaSlideHelper.hide();
slideHelper.hide();
dragHelper.hide();
}
else {
//make sure helpers are visible
alphaSlideHelper.show();
slideHelper.show();
dragHelper.show();
// Where to show the little circle in that displays your current selected color
var dragX = s * dragWidth;
var dragY = dragHeight - (v * dragHeight);
dragX = Math.max(
-dragHelperHeight,
Math.min(dragWidth - dragHelperHeight, dragX - dragHelperHeight)
);
dragY = Math.max(
-dragHelperHeight,
Math.min(dragHeight - dragHelperHeight, dragY - dragHelperHeight)
);
dragHelper.css({
"top": dragY + "px",
"left": dragX + "px"
});
var alphaX = currentAlpha * alphaWidth;
alphaSlideHelper.css({
"left": (alphaX - (alphaSlideHelperWidth / 2)) + "px"
});
// Where to show the bar that displays your current selected hue
var slideY = (currentHue) * slideHeight;
slideHelper.css({
"top": (slideY - slideHelperHeight) + "px"
});
}
}
function updateOriginalInput(fireCallback) {
var color = get(),
displayColor = '',
hasChanged = !tinycolor.equals(color, colorOnShow);
if (color) {
displayColor = color.toString(currentPreferredFormat);
// Update the selection palette with the current color
addColorToSelectionPalette(color);
}
if (isInput) {
boundElement.val(displayColor);
}
if (fireCallback && hasChanged) {
callbacks.change(color);
boundElement.trigger('change', [ color ]);
}
}
function reflow() {
if (!visible) {
return; // Calculations would be useless and wouldn't be reliable anyways
}
dragWidth = dragger.width();
dragHeight = dragger.height();
dragHelperHeight = dragHelper.height();
slideWidth = slider.width();
slideHeight = slider.height();
slideHelperHeight = slideHelper.height();
alphaWidth = alphaSlider.width();
alphaSlideHelperWidth = alphaSlideHelper.width();
if (!flat) {
container.css("position", "absolute");
if (opts.offset) {
container.offset(opts.offset);
} else {
container.offset(getOffset(container, offsetElement));
}
}
updateHelperLocations();
if (opts.showPalette) {
drawPalette();
}
boundElement.trigger('reflow.spectrum');
}
function destroy() {
boundElement.show();
offsetElement.unbind("click.spectrum touchstart.spectrum");
container.remove();
replacer.remove();
spectrums[spect.id] = null;
}
function option(optionName, optionValue) {
if (optionName === undefined) {
return $.extend({}, opts);
}
if (optionValue === undefined) {
return opts[optionName];
}
opts[optionName] = optionValue;
if (optionName === "preferredFormat") {
currentPreferredFormat = opts.preferredFormat;
}
applyOptions();
}
function enable() {
disabled = false;
boundElement.attr("disabled", false);
offsetElement.removeClass("sp-disabled");
}
function disable() {
hide();
disabled = true;
boundElement.attr("disabled", true);
offsetElement.addClass("sp-disabled");
}
function setOffset(coord) {
opts.offset = coord;
reflow();
}
initialize();
var spect = {
show: show,
hide: hide,
toggle: toggle,
reflow: reflow,
option: option,
enable: enable,
disable: disable,
offset: setOffset,
set: function (c) {
set(c);
updateOriginalInput();
},
get: get,
destroy: destroy,
container: container
};
spect.id = spectrums.push(spect) - 1;
return spect;
}
/**
* checkOffset - get the offset below/above and left/right element depending on screen position
* Thanks https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.datepicker.js
*/
function getOffset(picker, input) {
var extraY = 0;
var dpWidth = picker.outerWidth();
var dpHeight = picker.outerHeight();
var inputHeight = input.outerHeight();
var doc = picker[0].ownerDocument;
var docElem = doc.documentElement;
var viewWidth = docElem.clientWidth + $(doc).scrollLeft();
var viewHeight = docElem.clientHeight + $(doc).scrollTop();
var offset = input.offset();
offset.top += inputHeight;
offset.left -=
Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
Math.abs(offset.left + dpWidth - viewWidth) : 0);
offset.top -=
Math.min(offset.top, ((offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
Math.abs(dpHeight + inputHeight - extraY) : extraY));
return offset;
}
/**
* noop - do nothing
*/
function noop() {
}
/**
* stopPropagation - makes the code only doing this a little easier to read in line
*/
function stopPropagation(e) {
e.stopPropagation();
}
/**
* Create a function bound to a given object
* Thanks to underscore.js
*/
function bind(func, obj) {
var slice = Array.prototype.slice;
var args = slice.call(arguments, 2);
return function () {
return func.apply(obj, args.concat(slice.call(arguments)));
};
}
/**
* Lightweight drag helper. Handles containment within the element, so that
* when dragging, the x is within [0,element.width] and y is within [0,element.height]
*/
function draggable(element, onmove, onstart, onstop) {
onmove = onmove || function () { };
onstart = onstart || function () { };
onstop = onstop || function () { };
var doc = document;
var dragging = false;
var offset = {};
var maxHeight = 0;
var maxWidth = 0;
var hasTouch = ('ontouchstart' in window);
var duringDragEvents = {};
duringDragEvents["selectstart"] = prevent;
duringDragEvents["dragstart"] = prevent;
duringDragEvents["touchmove mousemove"] = move;
duringDragEvents["touchend mouseup"] = stop;
function prevent(e) {
if (e.stopPropagation) {
e.stopPropagation();
}
if (e.preventDefault) {
e.preventDefault();
}
e.returnValue = false;
}
function move(e) {
if (dragging) {
// Mouseup happened outside of window
if (IE && doc.documentMode < 9 && !e.button) {
return stop();
}
var t0 = e.originalEvent && e.originalEvent.touches && e.originalEvent.touches[0];
var pageX = t0 && t0.pageX || e.pageX;
var pageY = t0 && t0.pageY || e.pageY;
var dragX = Math.max(0, Math.min(pageX - offset.left, maxWidth));
var dragY = Math.max(0, Math.min(pageY - offset.top, maxHeight));
if (hasTouch) {
// Stop scrolling in iOS
prevent(e);
}
onmove.apply(element, [dragX, dragY, e]);
}
}
function start(e) {
var rightclick = (e.which) ? (e.which == 3) : (e.button == 2);
if (!rightclick && !dragging) {
if (onstart.apply(element, arguments) !== false) {
dragging = true;
maxHeight = $(element).height();
maxWidth = $(element).width();
offset = $(element).offset();
$(doc).bind(duringDragEvents);
$(doc.body).addClass("sp-dragging");
move(e);
prevent(e);
}
}
}
function stop() {
if (dragging) {
$(doc).unbind(duringDragEvents);
$(doc.body).removeClass("sp-dragging");
// Wait a tick before notifying observers to allow the click event
// to fire in Chrome.
setTimeout(function() {
onstop.apply(element, arguments);
}, 0);
}
dragging = false;
}
$(element).bind("touchstart mousedown", start);
}
function throttle(func, wait, debounce) {
var timeout;
return function () {
var context = this, args = arguments;
var throttler = function () {
timeout = null;
func.apply(context, args);
};
if (debounce) clearTimeout(timeout);
if (debounce || !timeout) timeout = setTimeout(throttler, wait);
};
}
function inputTypeColorSupport() {
return $.fn.spectrum.inputTypeColorSupport();
}
/**
* Define a jQuery plugin
*/
var dataID = "spectrum.id";
$.fn.spectrum = function (opts, extra) {
if (typeof opts == "string") {
var returnValue = this;
var args = Array.prototype.slice.call( arguments, 1 );
this.each(function () {
var spect = spectrums[$(this).data(dataID)];
if (spect) {
var method = spect[opts];
if (!method) {
throw new Error( "Spectrum: no such method: '" + opts + "'" );
}
if (opts == "get") {
returnValue = spect.get();
}
else if (opts == "container") {
returnValue = spect.container;
}
else if (opts == "option") {
returnValue = spect.option.apply(spect, args);
}
else if (opts == "destroy") {
spect.destroy();
$(this).removeData(dataID);
}
else {
method.apply(spect, args);
}
}
});
return returnValue;
}
// Initializing a new instance of spectrum
return this.spectrum("destroy").each(function () {
var options = $.extend({}, opts, $(this).data());
var spect = spectrum(this, options);
$(this).data(dataID, spect.id);
});
};
$.fn.spectrum.load = true;
$.fn.spectrum.loadOpts = {};
$.fn.spectrum.draggable = draggable;
$.fn.spectrum.defaults = defaultOpts;
$.fn.spectrum.inputTypeColorSupport = function inputTypeColorSupport() {
if (typeof inputTypeColorSupport._cachedResult === "undefined") {
var colorInput = $("<input type='color'/>")[0]; // if color element is supported, value will default to not null
inputTypeColorSupport._cachedResult = colorInput.type === "color" && colorInput.value !== "";
}
return inputTypeColorSupport._cachedResult;
};
$.spectrum = { };
$.spectrum.localization = { };
$.spectrum.palettes = { };
$.fn.spectrum.processNativeColorInputs = function () {
var colorInputs = $("input[type=color]");
if (colorInputs.length && !inputTypeColorSupport()) {
colorInputs.spectrum({
preferredFormat: "hex6"
});
}
};
// TinyColor v1.1.2
// https://github.com/bgrins/TinyColor
// Brian Grinstead, MIT License
(function() {
var trimLeft = /^[\s,#]+/,
trimRight = /\s+$/,
tinyCounter = 0,
math = Math,
mathRound = math.round,
mathMin = math.min,
mathMax = math.max,
mathRandom = math.random;
var tinycolor = function(color, opts) {
color = (color) ? color : '';
opts = opts || { };
// If input is already a tinycolor, return itself
if (color instanceof tinycolor) {
return color;
}
// If we are called as a function, call using new instead
if (!(this instanceof tinycolor)) {
return new tinycolor(color, opts);
}
var rgb = inputToRGB(color);
this._originalInput = color,
this._r = rgb.r,
this._g = rgb.g,
this._b = rgb.b,
this._a = rgb.a,
this._roundA = mathRound(100*this._a) / 100,
this._format = opts.format || rgb.format;
this._gradientType = opts.gradientType;
// Don't let the range of [0,255] come back in [0,1].
// Potentially lose a little bit of precision here, but will fix issues where
// .5 gets interpreted as half of the total, instead of half of 1
// If it was supposed to be 128, this was already taken care of by `inputToRgb`
if (this._r < 1) { this._r = mathRound(this._r); }
if (this._g < 1) { this._g = mathRound(this._g); }
if (this._b < 1) { this._b = mathRound(this._b); }
this._ok = rgb.ok;
this._tc_id = tinyCounter++;
};
tinycolor.prototype = {
isDark: function() {
return this.getBrightness() < 128;
},
isLight: function() {
return !this.isDark();
},
isValid: function() {
return this._ok;
},
getOriginalInput: function() {
return this._originalInput;
},
getFormat: function() {
return this._format;
},
getAlpha: function() {
return this._a;
},
getBrightness: function() {
var rgb = this.toRgb();
return (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000;
},
setAlpha: function(value) {
this._a = boundAlpha(value);
this._roundA = mathRound(100*this._a) / 100;
return this;
},
toHsv: function() {
var hsv = rgbToHsv(this._r, this._g, this._b);
return { h: hsv.h * 360, s: hsv.s, v: hsv.v, a: this._a };
},
toHsvString: function() {
var hsv = rgbToHsv(this._r, this._g, this._b);
var h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100);
return (this._a == 1) ?
"hsv(" + h + ", " + s + "%, " + v + "%)" :
"hsva(" + h + ", " + s + "%, " + v + "%, "+ this._roundA + ")";
},
toHsl: function() {
var hsl = rgbToHsl(this._r, this._g, this._b);
return { h: hsl.h * 360, s: hsl.s, l: hsl.l, a: this._a };
},
toHslString: function() {
var hsl = rgbToHsl(this._r, this._g, this._b);
var h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100);
return (this._a == 1) ?
"hsl(" + h + ", " + s + "%, " + l + "%)" :
"hsla(" + h + ", " + s + "%, " + l + "%, "+ this._roundA + ")";
},
toHex: function(allow3Char) {
return rgbToHex(this._r, this._g, this._b, allow3Char);
},
toHexString: function(allow3Char) {
return '#' + this.toHex(allow3Char);
},
toHex8: function() {
return rgbaToHex(this._r, this._g, this._b, this._a);
},
toHex8String: function() {
return '#' + this.toHex8();
},
toRgb: function() {
return { r: mathRound(this._r), g: mathRound(this._g), b: mathRound(this._b), a: this._a };
},
toRgbString: function() {
return (this._a == 1) ?
"rgb(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ")" :
"rgba(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ", " + this._roundA + ")";
},
toPercentageRgb: function() {
return { r: mathRound(bound01(this._r, 255) * 100) + "%", g: mathRound(bound01(this._g, 255) * 100) + "%", b: mathRound(bound01(this._b, 255) * 100) + "%", a: this._a };
},
toPercentageRgbString: function() {
return (this._a == 1) ?
"rgb(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%)" :
"rgba(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%, " + this._roundA + ")";
},
toName: function() {
if (this._a === 0) {
return "transparent";
}
if (this._a < 1) {
return false;
}
return hexNames[rgbToHex(this._r, this._g, this._b, true)] || false;
},
toFilter: function(secondColor) {
var hex8String = '#' + rgbaToHex(this._r, this._g, this._b, this._a);
var secondHex8String = hex8String;
var gradientType = this._gradientType ? "GradientType = 1, " : "";
if (secondColor) {
var s = tinycolor(secondColor);
secondHex8String = s.toHex8String();
}
return "progid:DXImageTransform.Microsoft.gradient("+gradientType+"startColorstr="+hex8String+",endColorstr="+secondHex8String+")";
},
toString: function(format) {
var formatSet = !!format;
format = format || this._format;
var formattedString = false;
var hasAlpha = this._a < 1 && this._a >= 0;
var needsAlphaFormat = !formatSet && hasAlpha && (format === "hex" || format === "hex6" || format === "hex3" || format === "name");
if (needsAlphaFormat) {
// Special case for "transparent", all other non-alpha formats
// will return rgba when there is transparency.
if (format === "name" && this._a === 0) {
return this.toName();
}
return this.toRgbString();
}
if (format === "rgb") {
formattedString = this.toRgbString();
}
if (format === "prgb") {
formattedString = this.toPercentageRgbString();
}
if (format === "hex" || format === "hex6") {
formattedString = this.toHexString();
}
if (format === "hex3") {
formattedString = this.toHexString(true);
}
if (format === "hex8") {
formattedString = this.toHex8String();
}
if (format === "name") {
formattedString = this.toName();
}
if (format === "hsl") {
formattedString = this.toHslString();
}
if (format === "hsv") {
formattedString = this.toHsvString();
}
return formattedString || this.toHexString();
},
_applyModification: function(fn, args) {
var color = fn.apply(null, [this].concat([].slice.call(args)));
this._r = color._r;
this._g = color._g;
this._b = color._b;
this.setAlpha(color._a);
return this;
},
lighten: function() {
return this._applyModification(lighten, arguments);
},
brighten: function() {
return this._applyModification(brighten, arguments);
},
darken: function() {
return this._applyModification(darken, arguments);
},
desaturate: function() {
return this._applyModification(desaturate, arguments);
},
saturate: function() {
return this._applyModification(saturate, arguments);
},
greyscale: function() {
return this._applyModification(greyscale, arguments);
},
spin: function() {
return this._applyModification(spin, arguments);
},
_applyCombination: function(fn, args) {
return fn.apply(null, [this].concat([].slice.call(args)));
},
analogous: function() {
return this._applyCombination(analogous, arguments);
},
complement: function() {
return this._applyCombination(complement, arguments);
},
monochromatic: function() {
return this._applyCombination(monochromatic, arguments);
},
splitcomplement: function() {
return this._applyCombination(splitcomplement, arguments);
},
triad: function() {
return this._applyCombination(triad, arguments);
},
tetrad: function() {
return this._applyCombination(tetrad, arguments);
}
};
// If input is an object, force 1 into "1.0" to handle ratios properly
// String input requires "1.0" as input, so 1 will be treated as 1
tinycolor.fromRatio = function(color, opts) {
if (typeof color == "object") {
var newColor = {};
for (var i in color) {
if (color.hasOwnProperty(i)) {
if (i === "a") {
newColor[i] = color[i];
}
else {
newColor[i] = convertToPercentage(color[i]);
}
}
}
color = newColor;
}
return tinycolor(color, opts);
};
// Given a string or object, convert that input to RGB
// Possible string inputs:
//
// "red"
// "#f00" or "f00"
// "#ff0000" or "ff0000"
// "#ff000000" or "ff000000"
// "rgb 255 0 0" or "rgb (255, 0, 0)"
// "rgb 1.0 0 0" or "rgb (1, 0, 0)"
// "rgba (255, 0, 0, 1)" or "rgba 255, 0, 0, 1"
// "rgba (1.0, 0, 0, 1)" or "rgba 1.0, 0, 0, 1"
// "hsl(0, 100%, 50%)" or "hsl 0 100% 50%"
// "hsla(0, 100%, 50%, 1)" or "hsla 0 100% 50%, 1"
// "hsv(0, 100%, 100%)" or "hsv 0 100% 100%"
//
function inputToRGB(color) {
var rgb = { r: 0, g: 0, b: 0 };
var a = 1;
var ok = false;
var format = false;
if (typeof color == "string") {
color = stringInputToObject(color);
}
if (typeof color == "object") {
if (color.hasOwnProperty("r") && color.hasOwnProperty("g") && color.hasOwnProperty("b")) {
rgb = rgbToRgb(color.r, color.g, color.b);
ok = true;
format = String(color.r).substr(-1) === "%" ? "prgb" : "rgb";
}
else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("v")) {
color.s = convertToPercentage(color.s);
color.v = convertToPercentage(color.v);
rgb = hsvToRgb(color.h, color.s, color.v);
ok = true;
format = "hsv";
}
else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("l")) {
color.s = convertToPercentage(color.s);
color.l = convertToPercentage(color.l);
rgb = hslToRgb(color.h, color.s, color.l);
ok = true;
format = "hsl";
}
if (color.hasOwnProperty("a")) {
a = color.a;
}
}
a = boundAlpha(a);
return {
ok: ok,
format: color.format || format,
r: mathMin(255, mathMax(rgb.r, 0)),
g: mathMin(255, mathMax(rgb.g, 0)),
b: mathMin(255, mathMax(rgb.b, 0)),
a: a
};
}
// Conversion Functions
// --------------------
// `rgbToHsl`, `rgbToHsv`, `hslToRgb`, `hsvToRgb` modified from:
// <http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript>
// `rgbToRgb`
// Handle bounds / percentage checking to conform to CSS color spec
// <http://www.w3.org/TR/css3-color/>
// *Assumes:* r, g, b in [0, 255] or [0, 1]
// *Returns:* { r, g, b } in [0, 255]
function rgbToRgb(r, g, b){
return {
r: bound01(r, 255) * 255,
g: bound01(g, 255) * 255,
b: bound01(b, 255) * 255
};
}
// `rgbToHsl`
// Converts an RGB color value to HSL.
// *Assumes:* r, g, and b are contained in [0, 255] or [0, 1]
// *Returns:* { h, s, l } in [0,1]
function rgbToHsl(r, g, b) {
r = bound01(r, 255);
g = bound01(g, 255);
b = bound01(b, 255);
var max = mathMax(r, g, b), min = mathMin(r, g, b);
var h, s, l = (max + min) / 2;
if(max == min) {
h = s = 0; // achromatic
}
else {
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch(max) {
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h /= 6;
}
return { h: h, s: s, l: l };
}
// `hslToRgb`
// Converts an HSL color value to RGB.
// *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100]
// *Returns:* { r, g, b } in the set [0, 255]
function hslToRgb(h, s, l) {
var r, g, b;
h = bound01(h, 360);
s = bound01(s, 100);
l = bound01(l, 100);
function hue2rgb(p, q, t) {
if(t < 0) t += 1;
if(t > 1) t -= 1;
if(t < 1/6) return p + (q - p) * 6 * t;
if(t < 1/2) return q;
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
}
if(s === 0) {
r = g = b = l; // achromatic
}
else {
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hue2rgb(p, q, h + 1/3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1/3);
}
return { r: r * 255, g: g * 255, b: b * 255 };
}
// `rgbToHsv`
// Converts an RGB color value to HSV
// *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1]
// *Returns:* { h, s, v } in [0,1]
function rgbToHsv(r, g, b) {
r = bound01(r, 255);
g = bound01(g, 255);
b = bound01(b, 255);
var max = mathMax(r, g, b), min = mathMin(r, g, b);
var h, s, v = max;
var d = max - min;
s = max === 0 ? 0 : d / max;
if(max == min) {
h = 0; // achromatic
}
else {
switch(max) {
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h /= 6;
}
return { h: h, s: s, v: v };
}
// `hsvToRgb`
// Converts an HSV color value to RGB.
// *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100]
// *Returns:* { r, g, b } in the set [0, 255]
function hsvToRgb(h, s, v) {
h = bound01(h, 360) * 6;
s = bound01(s, 100);
v = bound01(v, 100);
var i = math.floor(h),
f = h - i,
p = v * (1 - s),
q = v * (1 - f * s),
t = v * (1 - (1 - f) * s),
mod = i % 6,
r = [v, q, p, p, t, v][mod],
g = [t, v, v, q, p, p][mod],
b = [p, p, t, v, v, q][mod];
return { r: r * 255, g: g * 255, b: b * 255 };
}
// `rgbToHex`
// Converts an RGB color to hex
// Assumes r, g, and b are contained in the set [0, 255]
// Returns a 3 or 6 character hex
function rgbToHex(r, g, b, allow3Char) {
var hex = [
pad2(mathRound(r).toString(16)),
pad2(mathRound(g).toString(16)),
pad2(mathRound(b).toString(16))
];
// Return a 3 character hex if possible
if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) {
return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0);
}
return hex.join("");
}
// `rgbaToHex`
// Converts an RGBA color plus alpha transparency to hex
// Assumes r, g, b and a are contained in the set [0, 255]
// Returns an 8 character hex
function rgbaToHex(r, g, b, a) {
var hex = [
pad2(convertDecimalToHex(a)),
pad2(mathRound(r).toString(16)),
pad2(mathRound(g).toString(16)),
pad2(mathRound(b).toString(16))
];
return hex.join("");
}
// `equals`
// Can be called with any tinycolor input
tinycolor.equals = function (color1, color2) {
if (!color1 || !color2) { return false; }
return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString();
};
tinycolor.random = function() {
return tinycolor.fromRatio({
r: mathRandom(),
g: mathRandom(),
b: mathRandom()
});
};
// Modification Functions
// ----------------------
// Thanks to less.js for some of the basics here
// <https://github.com/cloudhead/less.js/blob/master/lib/less/functions.js>
function desaturate(color, amount) {
amount = (amount === 0) ? 0 : (amount || 10);
var hsl = tinycolor(color).toHsl();
hsl.s -= amount / 100;
hsl.s = clamp01(hsl.s);
return tinycolor(hsl);
}
function saturate(color, amount) {
amount = (amount === 0) ? 0 : (amount || 10);
var hsl = tinycolor(color).toHsl();
hsl.s += amount / 100;
hsl.s = clamp01(hsl.s);
return tinycolor(hsl);
}
function greyscale(color) {
return tinycolor(color).desaturate(100);
}
function lighten (color, amount) {
amount = (amount === 0) ? 0 : (amount || 10);
var hsl = tinycolor(color).toHsl();
hsl.l += amount / 100;
hsl.l = clamp01(hsl.l);
return tinycolor(hsl);
}
function brighten(color, amount) {
amount = (amount === 0) ? 0 : (amount || 10);
var rgb = tinycolor(color).toRgb();
rgb.r = mathMax(0, mathMin(255, rgb.r - mathRound(255 * - (amount / 100))));
rgb.g = mathMax(0, mathMin(255, rgb.g - mathRound(255 * - (amount / 100))));
rgb.b = mathMax(0, mathMin(255, rgb.b - mathRound(255 * - (amount / 100))));
return tinycolor(rgb);
}
function darken (color, amount) {
amount = (amount === 0) ? 0 : (amount || 10);
var hsl = tinycolor(color).toHsl();
hsl.l -= amount / 100;
hsl.l = clamp01(hsl.l);
return tinycolor(hsl);
}
// Spin takes a positive or negative amount within [-360, 360] indicating the change of hue.
// Values outside of this range will be wrapped into this range.
function spin(color, amount) {
var hsl = tinycolor(color).toHsl();
var hue = (mathRound(hsl.h) + amount) % 360;
hsl.h = hue < 0 ? 360 + hue : hue;
return tinycolor(hsl);
}
// Combination Functions
// ---------------------
// Thanks to jQuery xColor for some of the ideas behind these
// <https://github.com/infusion/jQuery-xcolor/blob/master/jquery.xcolor.js>
function complement(color) {
var hsl = tinycolor(color).toHsl();
hsl.h = (hsl.h + 180) % 360;
return tinycolor(hsl);
}
function triad(color) {
var hsl = tinycolor(color).toHsl();
var h = hsl.h;
return [
tinycolor(color),
tinycolor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }),
tinycolor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l })
];
}
function tetrad(color) {
var hsl = tinycolor(color).toHsl();
var h = hsl.h;
return [
tinycolor(color),
tinycolor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }),
tinycolor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }),
tinycolor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l })
];
}
function splitcomplement(color) {
var hsl = tinycolor(color).toHsl();
var h = hsl.h;
return [
tinycolor(color),
tinycolor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l}),
tinycolor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l})
];
}
function analogous(color, results, slices) {
results = results || 6;
slices = slices || 30;
var hsl = tinycolor(color).toHsl();
var part = 360 / slices;
var ret = [tinycolor(color)];
for (hsl.h = ((hsl.h - (part * results >> 1)) + 720) % 360; --results; ) {
hsl.h = (hsl.h + part) % 360;
ret.push(tinycolor(hsl));
}
return ret;
}
function monochromatic(color, results) {
results = results || 6;
var hsv = tinycolor(color).toHsv();
var h = hsv.h, s = hsv.s, v = hsv.v;
var ret = [];
var modification = 1 / results;
while (results--) {
ret.push(tinycolor({ h: h, s: s, v: v}));
v = (v + modification) % 1;
}
return ret;
}
// Utility Functions
// ---------------------
tinycolor.mix = function(color1, color2, amount) {
amount = (amount === 0) ? 0 : (amount || 50);
var rgb1 = tinycolor(color1).toRgb();
var rgb2 = tinycolor(color2).toRgb();
var p = amount / 100;
var w = p * 2 - 1;
var a = rgb2.a - rgb1.a;
var w1;
if (w * a == -1) {
w1 = w;
} else {
w1 = (w + a) / (1 + w * a);
}
w1 = (w1 + 1) / 2;
var w2 = 1 - w1;
var rgba = {
r: rgb2.r * w1 + rgb1.r * w2,
g: rgb2.g * w1 + rgb1.g * w2,
b: rgb2.b * w1 + rgb1.b * w2,
a: rgb2.a * p + rgb1.a * (1 - p)
};
return tinycolor(rgba);
};
// Readability Functions
// ---------------------
// <http://www.w3.org/TR/AERT#color-contrast>
// `readability`
// Analyze the 2 colors and returns an object with the following properties:
// `brightness`: difference in brightness between the two colors
// `color`: difference in color/hue between the two colors
tinycolor.readability = function(color1, color2) {
var c1 = tinycolor(color1);
var c2 = tinycolor(color2);
var rgb1 = c1.toRgb();
var rgb2 = c2.toRgb();
var brightnessA = c1.getBrightness();
var brightnessB = c2.getBrightness();
var colorDiff = (
Math.max(rgb1.r, rgb2.r) - Math.min(rgb1.r, rgb2.r) +
Math.max(rgb1.g, rgb2.g) - Math.min(rgb1.g, rgb2.g) +
Math.max(rgb1.b, rgb2.b) - Math.min(rgb1.b, rgb2.b)
);
return {
brightness: Math.abs(brightnessA - brightnessB),
color: colorDiff
};
};
// `readable`
// http://www.w3.org/TR/AERT#color-contrast
// Ensure that foreground and background color combinations provide sufficient contrast.
// *Example*
// tinycolor.isReadable("#000", "#111") => false
tinycolor.isReadable = function(color1, color2) {
var readability = tinycolor.readability(color1, color2);
return readability.brightness > 125 && readability.color > 500;
};
// `mostReadable`
// Given a base color and a list of possible foreground or background
// colors for that base, returns the most readable color.
// *Example*
// tinycolor.mostReadable("#123", ["#fff", "#000"]) => "#000"
tinycolor.mostReadable = function(baseColor, colorList) {
var bestColor = null;
var bestScore = 0;
var bestIsReadable = false;
for (var i=0; i < colorList.length; i++) {
// We normalize both around the "acceptable" breaking point,
// but rank brightness constrast higher than hue.
var readability = tinycolor.readability(baseColor, colorList[i]);
var readable = readability.brightness > 125 && readability.color > 500;
var score = 3 * (readability.brightness / 125) + (readability.color / 500);
if ((readable && ! bestIsReadable) ||
(readable && bestIsReadable && score > bestScore) ||
((! readable) && (! bestIsReadable) && score > bestScore)) {
bestIsReadable = readable;
bestScore = score;
bestColor = tinycolor(colorList[i]);
}
}
return bestColor;
};
// Big List of Colors
// ------------------
// <http://www.w3.org/TR/css3-color/#svg-color>
var names = tinycolor.names = {
aliceblue: "f0f8ff",
antiquewhite: "faebd7",
aqua: "0ff",
aquamarine: "7fffd4",
azure: "f0ffff",
beige: "f5f5dc",
bisque: "ffe4c4",
black: "000",
blanchedalmond: "ffebcd",
blue: "00f",
blueviolet: "8a2be2",
brown: "a52a2a",
burlywood: "deb887",
burntsienna: "ea7e5d",
cadetblue: "5f9ea0",
chartreuse: "7fff00",
chocolate: "d2691e",
coral: "ff7f50",
cornflowerblue: "6495ed",
cornsilk: "fff8dc",
crimson: "dc143c",
cyan: "0ff",
darkblue: "00008b",
darkcyan: "008b8b",
darkgoldenrod: "b8860b",
darkgray: "a9a9a9",
darkgreen: "006400",
darkgrey: "a9a9a9",
darkkhaki: "bdb76b",
darkmagenta: "8b008b",
darkolivegreen: "556b2f",
darkorange: "ff8c00",
darkorchid: "9932cc",
darkred: "8b0000",
darksalmon: "e9967a",
darkseagreen: "8fbc8f",
darkslateblue: "483d8b",
darkslategray: "2f4f4f",
darkslategrey: "2f4f4f",
darkturquoise: "00ced1",
darkviolet: "9400d3",
deeppink: "ff1493",
deepskyblue: "00bfff",
dimgray: "696969",
dimgrey: "696969",
dodgerblue: "1e90ff",
firebrick: "b22222",
floralwhite: "fffaf0",
forestgreen: "228b22",
fuchsia: "f0f",
gainsboro: "dcdcdc",
ghostwhite: "f8f8ff",
gold: "ffd700",
goldenrod: "daa520",
gray: "808080",
green: "008000",
greenyellow: "adff2f",
grey: "808080",
honeydew: "f0fff0",
hotpink: "ff69b4",
indianred: "cd5c5c",
indigo: "4b0082",
ivory: "fffff0",
khaki: "f0e68c",
lavender: "e6e6fa",
lavenderblush: "fff0f5",
lawngreen: "7cfc00",
lemonchiffon: "fffacd",
lightblue: "add8e6",
lightcoral: "f08080",
lightcyan: "e0ffff",
lightgoldenrodyellow: "fafad2",
lightgray: "d3d3d3",
lightgreen: "90ee90",
lightgrey: "d3d3d3",
lightpink: "ffb6c1",
lightsalmon: "ffa07a",
lightseagreen: "20b2aa",
lightskyblue: "87cefa",
lightslategray: "789",
lightslategrey: "789",
lightsteelblue: "b0c4de",
lightyellow: "ffffe0",
lime: "0f0",
limegreen: "32cd32",
linen: "faf0e6",
magenta: "f0f",
maroon: "800000",
mediumaquamarine: "66cdaa",
mediumblue: "0000cd",
mediumorchid: "ba55d3",
mediumpurple: "9370db",
mediumseagreen: "3cb371",
mediumslateblue: "7b68ee",
mediumspringgreen: "00fa9a",
mediumturquoise: "48d1cc",
mediumvioletred: "c71585",
midnightblue: "191970",
mintcream: "f5fffa",
mistyrose: "ffe4e1",
moccasin: "ffe4b5",
navajowhite: "ffdead",
navy: "000080",
oldlace: "fdf5e6",
olive: "808000",
olivedrab: "6b8e23",
orange: "ffa500",
orangered: "ff4500",
orchid: "da70d6",
palegoldenrod: "eee8aa",
palegreen: "98fb98",
paleturquoise: "afeeee",
palevioletred: "db7093",
papayawhip: "ffefd5",
peachpuff: "ffdab9",
peru: "cd853f",
pink: "ffc0cb",
plum: "dda0dd",
powderblue: "b0e0e6",
purple: "800080",
rebeccapurple: "663399",
red: "f00",
rosybrown: "bc8f8f",
royalblue: "4169e1",
saddlebrown: "8b4513",
salmon: "fa8072",
sandybrown: "f4a460",
seagreen: "2e8b57",
seashell: "fff5ee",
sienna: "a0522d",
silver: "c0c0c0",
skyblue: "87ceeb",
slateblue: "6a5acd",
slategray: "708090",
slategrey: "708090",
snow: "fffafa",
springgreen: "00ff7f",
steelblue: "4682b4",
tan: "d2b48c",
teal: "008080",
thistle: "d8bfd8",
tomato: "ff6347",
turquoise: "40e0d0",
violet: "ee82ee",
wheat: "f5deb3",
white: "fff",
whitesmoke: "f5f5f5",
yellow: "ff0",
yellowgreen: "9acd32"
};
// Make it easy to access colors via `hexNames[hex]`
var hexNames = tinycolor.hexNames = flip(names);
// Utilities
// ---------
// `{ 'name1': 'val1' }` becomes `{ 'val1': 'name1' }`
function flip(o) {
var flipped = { };
for (var i in o) {
if (o.hasOwnProperty(i)) {
flipped[o[i]] = i;
}
}
return flipped;
}
// Return a valid alpha value [0,1] with all invalid values being set to 1
function boundAlpha(a) {
a = parseFloat(a);
if (isNaN(a) || a < 0 || a > 1) {
a = 1;
}
return a;
}
// Take input from [0, n] and return it as [0, 1]
function bound01(n, max) {
if (isOnePointZero(n)) { n = "100%"; }
var processPercent = isPercentage(n);
n = mathMin(max, mathMax(0, parseFloat(n)));
// Automatically convert percentage into number
if (processPercent) {
n = parseInt(n * max, 10) / 100;
}
// Handle floating point rounding errors
if ((math.abs(n - max) < 0.000001)) {
return 1;
}
// Convert into [0, 1] range if it isn't already
return (n % max) / parseFloat(max);
}
// Force a number between 0 and 1
function clamp01(val) {
return mathMin(1, mathMax(0, val));
}
// Parse a base-16 hex value into a base-10 integer
function parseIntFromHex(val) {
return parseInt(val, 16);
}
// Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1
// <http://stackoverflow.com/questions/7422072/javascript-how-to-detect-number-as-a-decimal-including-1-0>
function isOnePointZero(n) {
return typeof n == "string" && n.indexOf('.') != -1 && parseFloat(n) === 1;
}
// Check to see if string passed in is a percentage
function isPercentage(n) {
return typeof n === "string" && n.indexOf('%') != -1;
}
// Force a hex value to have 2 characters
function pad2(c) {
return c.length == 1 ? '0' + c : '' + c;
}
// Replace a decimal with it's percentage value
function convertToPercentage(n) {
if (n <= 1) {
n = (n * 100) + "%";
}
return n;
}
// Converts a decimal to a hex value
function convertDecimalToHex(d) {
return Math.round(parseFloat(d) * 255).toString(16);
}
// Converts a hex value to a decimal
function convertHexToDecimal(h) {
return (parseIntFromHex(h) / 255);
}
var matchers = (function() {
// <http://www.w3.org/TR/css3-values/#integers>
var CSS_INTEGER = "[-\\+]?\\d+%?";
// <http://www.w3.org/TR/css3-values/#number-value>
var CSS_NUMBER = "[-\\+]?\\d*\\.\\d+%?";
// Allow positive/negative integer/number. Don't capture the either/or, just the entire outcome.
var CSS_UNIT = "(?:" + CSS_NUMBER + ")|(?:" + CSS_INTEGER + ")";
// Actual matching.
// Parentheses and commas are optional, but not required.
// Whitespace can take the place of commas or opening paren
var PERMISSIVE_MATCH3 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
var PERMISSIVE_MATCH4 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
return {
rgb: new RegExp("rgb" + PERMISSIVE_MATCH3),
rgba: new RegExp("rgba" + PERMISSIVE_MATCH4),
hsl: new RegExp("hsl" + PERMISSIVE_MATCH3),
hsla: new RegExp("hsla" + PERMISSIVE_MATCH4),
hsv: new RegExp("hsv" + PERMISSIVE_MATCH3),
hsva: new RegExp("hsva" + PERMISSIVE_MATCH4),
hex3: /^([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
hex6: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,
hex8: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/
};
})();
// `stringInputToObject`
// Permissive string parsing. Take in a number of formats, and output an object
// based on detected format. Returns `{ r, g, b }` or `{ h, s, l }` or `{ h, s, v}`
function stringInputToObject(color) {
color = color.replace(trimLeft,'').replace(trimRight, '').toLowerCase();
var named = false;
if (names[color]) {
color = names[color];
named = true;
}
else if (color == 'transparent') {
return { r: 0, g: 0, b: 0, a: 0, format: "name" };
}
// Try to match string input using regular expressions.
// Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360]
// Just return an object and let the conversion functions handle that.
// This way the result will be the same whether the tinycolor is initialized with string or object.
var match;
if ((match = matchers.rgb.exec(color))) {
return { r: match[1], g: match[2], b: match[3] };
}
if ((match = matchers.rgba.exec(color))) {
return { r: match[1], g: match[2], b: match[3], a: match[4] };
}
if ((match = matchers.hsl.exec(color))) {
return { h: match[1], s: match[2], l: match[3] };
}
if ((match = matchers.hsla.exec(color))) {
return { h: match[1], s: match[2], l: match[3], a: match[4] };
}
if ((match = matchers.hsv.exec(color))) {
return { h: match[1], s: match[2], v: match[3] };
}
if ((match = matchers.hsva.exec(color))) {
return { h: match[1], s: match[2], v: match[3], a: match[4] };
}
if ((match = matchers.hex8.exec(color))) {
return {
a: convertHexToDecimal(match[1]),
r: parseIntFromHex(match[2]),
g: parseIntFromHex(match[3]),
b: parseIntFromHex(match[4]),
format: named ? "name" : "hex8"
};
}
if ((match = matchers.hex6.exec(color))) {
return {
r: parseIntFromHex(match[1]),
g: parseIntFromHex(match[2]),
b: parseIntFromHex(match[3]),
format: named ? "name" : "hex"
};
}
if ((match = matchers.hex3.exec(color))) {
return {
r: parseIntFromHex(match[1] + '' + match[1]),
g: parseIntFromHex(match[2] + '' + match[2]),
b: parseIntFromHex(match[3] + '' + match[3]),
format: named ? "name" : "hex"
};
}
return false;
}
window.tinycolor = tinycolor;
})();
$(function () {
if ($.fn.spectrum.load) {
$.fn.spectrum.processNativeColorInputs();
}
});
});
<!doctype html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Spectrum - The No Hassle jQuery Colorpicker</title>
<meta name="description" content="Spectrum is a JavaScript colorpicker plugin using the jQuery framework. It is highly customizable, but can also be used as a simple input type=color polyfill">
<meta name="author" content="Brian Grinstead and Spectrum contributors">
<link rel="stylesheet" type="text/css" href="../spectrum.css">
<link rel="stylesheet" type="text/css" href="../docs/bootstrap.css">
<link rel="stylesheet" type="text/css" href="../docs/docs.css">
<script type="text/javascript" src="../docs/jquery-1.9.1.js"></script>
<script type="text/javascript" src="../spectrum.js"></script>
<link rel="stylesheet" type="text/css" href="sp-dark.css">
</head>
<body>
<div id='header'>
<h1><a href='http://bgrins.github.com/spectrum'>Spectrum</a></h1> <h2><em>The No Hassle jQuery Colorpicker</em></h2>
<div id='links'>
View the <a href='http://github.com/bgrins/spectrum'>Source code</a>.
Spectrum is a project by <a href='http://twitter.com/bgrins'>@bgrins</a>.
</div>
<br style='clear:both;' />
</div>
<div class="container">
<h2>Themes</h2>
<div class="alert">
This page is in development.
</div>
<div id="theme-gallery">
<h3>Gallery of existing themes</h3>
<div class="theme" id="sp-light">
<h4>sp-light</h4>
<p>This is the default theme that you know and love.</p>
<div class='example'>
<input type='text' />
</div>
</div>
<div class="theme" id="sp-dark">
<h4>sp-dark</h4>
<p>Similar to sp-light, only ... darker</p>
<div class='example'>
<input type='text' />
</div>
</div>
</div>
<div id="theme-instructions">
<h3>Instructions for building themes</h3>
<p>
You can change most any property on spectrum using CSS. Anything from borders and colors, to the size of the draggable areas, to the layout of the colorpicker can be changed with plain CSS.
</p>
<h4>Playing friendly with other themes</h4>
<p>
Please prefix all of your rules with <code>.theme-name</code>. The exception is for changes to <code>.sp-container</code> and <code>.sp-replacer</code>, which will have your theme name applied.
</p>
<p>
See a basic scaffold for a super simple theme. See <a href='sp-dark.css'>sp-dark.css</a> for a slightly more advanced example.
</p>
<pre>
.theme-name.sp-container {
}
.theme-name.sp-replacer {
}
.theme-name .sp-preview {
}
</pre>
<h3>Submitting a theme</h3>
<p>
If you have made some customizations that you would like to share, please open a <a href="http://bgrins.github.com/spectrum/pulls">pull request</a> with the theme file inside of this themes/ directory in the project. Or <a href="http://bgrins.github.com/spectrum/issues">open an issue</a> with a link to the theme.
</p>
</div>
</div>
<script>
$("#sp-light input").spectrum({
theme: "sp-light"
});
$("#sp-dark input").spectrum({
theme: "sp-dark"
});
</script>
<script type="text/javascript" src="../docs/prettify.js"></script>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-8259845-4']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</body>
</html>
/* Container */
.sp-dark.sp-container {
background-color: #333;
border: solid 1px #555;
}
/* Replacer (the little preview div that shows up instead of the <input>) */
.sp-dark.sp-replacer {
border: solid 1px #fff;
background: #333;
color: #eee;
vertical-align: middle;
}
.sp-replacer:hover, .sp-replacer.sp-active {
border-color: #F0C49B;
color: #fff;
}
.sp-replacer.sp-disabled {
border-color: silver;
color: silver;
}
.sp-dark .sp-preview {
border: solid 1px #999;
}
.sp-dark .sp-cancel {
color: #f99f9f !important;
}
.sp-dark, .sp-dark button, .sp-dark input, .sp-color, .sp-hue {
}
/* Input */
.sp-dark .sp-input-container {
}
.sp-dark .sp-initial-disabled .sp-input-container {
}
.sp-dark .sp-input {
}
.sp-dark .sp-input:focus {
}
.sp-dark .sp-input.sp-validation-error {
}
.sp-dark .sp-picker-container , .sp-dark .sp-palette-container {
}
.sp-dark .sp-picker-container {
}
/* Palettes */
.sp-dark .sp-palette-container {
}
.sp-dark .sp-palette .sp-thumb-el {
}
.sp-dark .sp-palette .sp-thumb-el:hover, .sp-dark .sp-palette .sp-thumb-el.sp-thumb-active {
}
.sp-dark .sp-thumb-el {
}
/* Initial */
.sp-dark .sp-initial {
}
.sp-dark .sp-initial span {
}
/* Buttons */
.sp-dark .sp-button-container {
}
/* Replacer (the little preview div that shows up instead of the <input>) */
.sp-dark.sp-replacer {
}
.sp-dark.sp-replacer:hover, .sp-dark.sp-replacer.sp-active {
border-color: #F0C49B;
color: #111;
}
.sp-dark.sp-replacer.sp-disabled {
}
.sp-dark .sp-dd {
}
.sp-dark .sp-preview {
}
.sp-dark .sp-palette {
}
.sp-dark .sp-palette .sp-thumb-el {
}
.sp-dark button {
}
.sp-dark button:hover {
}
.sp-dark button:active {
}
.sp-dark .sp-cancel {
}
.sp-dark .sp-cancel:hover {
}
.sp-dark .sp-palette span:hover, .sp-dark .sp-palette span.sp-thumb-active {
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment