306 lines
15 KiB
JavaScript
306 lines
15 KiB
JavaScript
|
// ------ ColorPicker ------ //
|
|||
|
|
|||
|
(function (window) {
|
|||
|
window.jsColorPicker = function(selectors, config) {
|
|||
|
var renderCallback = function(colors, mode) {
|
|||
|
var options = this,
|
|||
|
input = options.input,
|
|||
|
patch = options.patch,
|
|||
|
RGB = colors.RND.rgb,
|
|||
|
HSL = colors.RND.hsl,
|
|||
|
AHEX = options.isIE8 ? (colors.alpha < 0.16 ? '0' : '') +
|
|||
|
(Math.round(colors.alpha * 100)).toString(16).toUpperCase() + colors.HEX : '',
|
|||
|
RGBInnerText = RGB.r + ',' + RGB.g + ',' + RGB.b,
|
|||
|
RGBAText = RGBInnerText + ',' + colors.alpha,
|
|||
|
isAlpha = colors.alpha !== 1 && !options.isIE8,
|
|||
|
colorMode = input.getAttribute('data-colorMode');
|
|||
|
|
|||
|
patch.style.cssText =
|
|||
|
'color:' + (colors.rgbaMixCustom.luminance > 0.22 ? '#222' : '#ddd') + ';' + // Black...???
|
|||
|
'background-color: rgba(' + RGBAText + ');' +
|
|||
|
'filter:' + (options.isIE8 ? 'progid:DXImageTransform.Microsoft.gradient(' + // IE<9
|
|||
|
'startColorstr=#' + AHEX + ',' + 'endColorstr=#' + AHEX + ')' : '');
|
|||
|
|
|||
|
input.value = RGBAText;
|
|||
|
|
|||
|
if (options.displayCallback) {
|
|||
|
options.displayCallback(colors, mode, options);
|
|||
|
}
|
|||
|
},
|
|||
|
extractValue = function(elm) {
|
|||
|
var val = elm.value || elm.getAttribute('value') || elm.style.backgroundColor || "0,0,0,1";
|
|||
|
if (/^[0-9 ]+,[0-9 ]+,[0-9 ]+,[0-9. ]+$/.test(val)) return "rgba("+val+")";
|
|||
|
if (/^[0-9 ]+,[0-9 ]+,[0-9 ]+$/.test(val)) return "rgba("+val+",1)";
|
|||
|
return null;
|
|||
|
},
|
|||
|
actionCallback = function(event, action) {
|
|||
|
var options = this,
|
|||
|
colorPicker = colorPickers.current;
|
|||
|
|
|||
|
if (action === 'toMemory') {
|
|||
|
var memos = colorPicker.nodes.memos,
|
|||
|
backgroundColor = '',
|
|||
|
opacity = 0,
|
|||
|
cookieTXT = [];
|
|||
|
|
|||
|
for (var n = 0, m = memos.length; n < m; n++) {
|
|||
|
backgroundColor = memos[n].style.backgroundColor;
|
|||
|
opacity = memos[n].style.opacity;
|
|||
|
opacity = Math.round((opacity === '' ? 1 : opacity) * 100) / 100;
|
|||
|
cookieTXT.push(backgroundColor.
|
|||
|
replace(/, /g, ',').
|
|||
|
replace('rgb(', 'rgba(').
|
|||
|
replace(')', ',' + opacity + ')')
|
|||
|
);
|
|||
|
}
|
|||
|
cookieTXT = '\'' + cookieTXT.join('\',\'') + '\'';
|
|||
|
ColorPicker.docCookies('colorPickerMemos' + (options.noAlpha ? 'NoAlpha' : ''), cookieTXT);
|
|||
|
} else if (action === 'resizeApp') {
|
|||
|
ColorPicker.docCookies('colorPickerSize', colorPicker.color.options.currentSize);
|
|||
|
} else if (action === 'modeChange') {
|
|||
|
var mode = colorPicker.color.options.mode;
|
|||
|
|
|||
|
ColorPicker.docCookies('colorPickerMode', mode.type + '-' + mode.z);
|
|||
|
}
|
|||
|
},
|
|||
|
createInstance = function(elm, config) {
|
|||
|
var initConfig = {
|
|||
|
klass: window.ColorPicker,
|
|||
|
input: elm,
|
|||
|
patch: elm,
|
|||
|
isIE8: !!document.all && !document.addEventListener, // Opera???
|
|||
|
// *** animationSpeed: 200,
|
|||
|
// *** draggable: true,
|
|||
|
margin: {left: -1, top: 2},
|
|||
|
customBG: '#FFFFFF',
|
|||
|
// displayCallback: displayCallback,
|
|||
|
/* --- regular colorPicker options from this point --- */
|
|||
|
color: extractValue(elm),
|
|||
|
initStyle: 'display: none',
|
|||
|
mode: ColorPicker.docCookies('colorPickerMode') || 'hsv-h',
|
|||
|
// memoryColors: (function(colors, config) {
|
|||
|
// return config.noAlpha ?
|
|||
|
// colors.replace(/\,\d*\.*\d*\)/g, ',1)') : colors;
|
|||
|
// })($.docCookies('colorPickerMemos'), config || {}),
|
|||
|
memoryColors: ColorPicker.docCookies('colorPickerMemos' +
|
|||
|
((config || {}).noAlpha ? 'NoAlpha' : '')),
|
|||
|
size: ColorPicker.docCookies('colorPickerSize') || 1,
|
|||
|
renderCallback: renderCallback,
|
|||
|
actionCallback: actionCallback
|
|||
|
};
|
|||
|
|
|||
|
for (var n in config) {
|
|||
|
initConfig[n] = config[n];
|
|||
|
}
|
|||
|
return new initConfig.klass(initConfig);
|
|||
|
},
|
|||
|
doEventListeners = function(elm, multiple, off) {
|
|||
|
var onOff = off ? 'removeEventListener' : 'addEventListener',
|
|||
|
inputListener = function(e) {
|
|||
|
var index = multiple ? Array.prototype.indexOf.call(elms, this) : 0,
|
|||
|
colorPicker = colorPickers[index] ||
|
|||
|
(colorPickers[index] = createInstance(this, config)),
|
|||
|
options = colorPicker.color.options;
|
|||
|
|
|||
|
options.color = extractValue(elm); // brings color to default on reset
|
|||
|
//检查颜色合法性
|
|||
|
if (options.color != null && options.color == options.color.match(/rgba\([0-9 ]+,[0-9 ]+,[0-9 ]+,[0-9. ]+\)/)[0]) {
|
|||
|
var chec = options.color.match(/[0-9.]+/g);
|
|||
|
if (chec.length != 4)
|
|||
|
return;
|
|||
|
for (var i = 0; i < 3; i++) {
|
|||
|
if (chec[i] != chec[i].match(/\d+/)[0] || +chec[i] < 0 || +chec[i] > 255)
|
|||
|
return;
|
|||
|
}
|
|||
|
if (chec[3] != chec[3].match(/\d+(\.\d+)?/)[0] || parseFloat(chec[3]) > 1 || parseFloat(chec[3] < 0))
|
|||
|
return;
|
|||
|
if (!multiple) {
|
|||
|
colorPicker.setColor(extractValue(elm), undefined, undefined, true);
|
|||
|
colorPicker.saveAsBackground();
|
|||
|
}
|
|||
|
colorPickers.current = colorPickers[index];
|
|||
|
}
|
|||
|
},
|
|||
|
createListener = function() {
|
|||
|
elm = document.getElementById("colorPicker");
|
|||
|
var input = elm,
|
|||
|
position = window.ColorPicker.getOrigin(input),
|
|||
|
index = multiple ? Array.prototype.indexOf.call(elms, elm) : 0,
|
|||
|
colorPicker = colorPickers[index] ||
|
|||
|
(colorPickers[index] = createInstance(elm, config)),
|
|||
|
options = colorPicker.color.options,
|
|||
|
colorPickerUI = colorPicker.nodes.colorPicker,
|
|||
|
appendTo = (options.appendTo || document.body),
|
|||
|
isStatic = /static/.test(window.getComputedStyle(appendTo).position),
|
|||
|
atrect = isStatic ? {left: 0, top: 0} : appendTo.getBoundingClientRect(),
|
|||
|
waitTimer = 0;
|
|||
|
|
|||
|
options.color = extractValue(elm); // brings color to default on reset
|
|||
|
colorPickerUI.style.cssText =
|
|||
|
'position: absolute;' + (!colorPickers[index].cssIsReady ? 'display: none;' : '') +
|
|||
|
'left:' + (position.left + options.margin.left - atrect.left) + 'px;' +
|
|||
|
'top:' + (position.top + +input.offsetHeight + options.margin.top - atrect.top) + 'px;';
|
|||
|
|
|||
|
if (!multiple) {
|
|||
|
options.input = elm;
|
|||
|
options.patch = elm; // check again???
|
|||
|
colorPicker.setColor(extractValue(elm), undefined, undefined, true);
|
|||
|
colorPicker.saveAsBackground();
|
|||
|
}
|
|||
|
colorPickers.current = colorPickers[index];
|
|||
|
appendTo.appendChild(colorPickerUI);
|
|||
|
waitTimer = setInterval(function() { // compensating late style on onload in colorPicker
|
|||
|
if (colorPickers.current.cssIsReady) {
|
|||
|
waitTimer = clearInterval(waitTimer);
|
|||
|
colorPickerUI.style.display = 'block';
|
|||
|
}
|
|||
|
}, 10);
|
|||
|
},
|
|||
|
hideListener = function(e) {
|
|||
|
var colorPicker = colorPickers.current,
|
|||
|
colorPickerUI = (colorPicker ? colorPicker.nodes.colorPicker : undefined),
|
|||
|
animationSpeed = colorPicker ? colorPicker.color.options.animationSpeed : 0,
|
|||
|
isColorPicker = colorPicker && (function(elm) {
|
|||
|
while (elm) {
|
|||
|
if ((elm.className || '').indexOf('cpPanel') !== -1) return elm;
|
|||
|
elm = elm.parentNode;
|
|||
|
}
|
|||
|
return false;
|
|||
|
})(e.target),
|
|||
|
inputIndex = Array.prototype.indexOf.call(elms, e.target);
|
|||
|
|
|||
|
if (isColorPicker && Array.prototype.indexOf.call(colorPickers, isColorPicker)) {
|
|||
|
if (e.target === colorPicker.nodes.exit) {
|
|||
|
colorPickerUI.parentNode.style.display = 'none';
|
|||
|
document.activeElement.blur();
|
|||
|
} else {
|
|||
|
// ...
|
|||
|
}
|
|||
|
} else if (inputIndex !== -1) {
|
|||
|
// ...
|
|||
|
} else if (colorPickerUI) {
|
|||
|
colorPickerUI.parentNode.style.display = 'none';
|
|||
|
}
|
|||
|
};
|
|||
|
elm[onOff]('input', inputListener);
|
|||
|
window.jsColorPicker.create = createListener;
|
|||
|
},
|
|||
|
// this is a way to prevent data binding on HTMLElements
|
|||
|
colorPickers = window.jsColorPicker.colorPickers || [],
|
|||
|
elms = document.querySelectorAll(selectors),
|
|||
|
testColors = new window.Colors({customBG: config.customBG, allMixDetails: true});
|
|||
|
|
|||
|
window.jsColorPicker.colorPickers = colorPickers;
|
|||
|
|
|||
|
for (var n = 0, m = elms.length; n < m; n++) {
|
|||
|
var elm = elms[n];
|
|||
|
|
|||
|
if (config === 'destroy') {
|
|||
|
doEventListeners(elm, (config && config.multipleInstances), true);
|
|||
|
if (colorPickers[n]) {
|
|||
|
colorPickers[n].destroyAll();
|
|||
|
}
|
|||
|
} else {
|
|||
|
var color = extractValue(elm);
|
|||
|
var value = color.split('(');
|
|||
|
|
|||
|
testColors.setColor(color);
|
|||
|
if (config && config.init) {
|
|||
|
config.init(elm, testColors.colors);
|
|||
|
}
|
|||
|
elm.setAttribute('data-colorMode', value[1] ? value[0].substr(0, 3) : 'HEX');
|
|||
|
doEventListeners(elm, (config && config.multipleInstances), false);
|
|||
|
if (config && config.readOnly) {
|
|||
|
elm.readOnly = true;
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
return window.jsColorPicker.colorPickers;
|
|||
|
};
|
|||
|
|
|||
|
window.ColorPicker.docCookies = function(key, val, options) {
|
|||
|
var encode = encodeURIComponent, decode = decodeURIComponent,
|
|||
|
cookies, n, tmp, cache = {},
|
|||
|
days;
|
|||
|
|
|||
|
if (val === undefined) { // all about reading cookies
|
|||
|
cookies = document.cookie.split(/;\s*/) || [];
|
|||
|
for (n = cookies.length; n--; ) {
|
|||
|
tmp = cookies[n].split('=');
|
|||
|
if (tmp[0]) cache[decode(tmp.shift())] = decode(tmp.join('=')); // there might be '='s in the value...
|
|||
|
}
|
|||
|
|
|||
|
if (!key) return cache; // return Json for easy access to all cookies
|
|||
|
else return cache[key]; // easy access to cookies from here
|
|||
|
} else { // write/delete cookie
|
|||
|
options = options || {};
|
|||
|
|
|||
|
if (val === '' || options.expires < 0) { // prepare deleteing the cookie
|
|||
|
options.expires = -1;
|
|||
|
// options.path = options.domain = options.secure = undefined; // to make shure the cookie gets deleted...
|
|||
|
}
|
|||
|
|
|||
|
if (options.expires !== undefined) { // prepare date if any
|
|||
|
days = new Date();
|
|||
|
days.setDate(days.getDate() + options.expires);
|
|||
|
}
|
|||
|
|
|||
|
document.cookie = encode(key) + '=' + encode(val) +
|
|||
|
(days ? '; expires=' + days.toUTCString() : '') +
|
|||
|
(options.path ? '; path=' + options.path : '') +
|
|||
|
(options.domain ? '; domain=' + options.domain : '') +
|
|||
|
(options.secure ? '; secure' : '');
|
|||
|
}
|
|||
|
};
|
|||
|
})(this);
|
|||
|
|
|||
|
// Added
|
|||
|
jsColorPicker('input.color', {
|
|||
|
customBG: '#222',
|
|||
|
readOnly: false,
|
|||
|
// patch: false,
|
|||
|
init: function(elm, colors) { // colors is a different instance (not connected to colorPicker)
|
|||
|
elm.style.backgroundColor = elm.value;
|
|||
|
elm.style.color = colors.rgbaMixCustom.luminance > 0.22 ? '#222' : '#ddd';
|
|||
|
},
|
|||
|
appendTo: document.getElementById("colorPanel"),
|
|||
|
size: 1,
|
|||
|
});
|
|||
|
|
|||
|
function openColorPicker(px, py, callback) {
|
|||
|
window.jsColorPicker.confirm = callback;
|
|||
|
var colorPanel = document.getElementById('colorPanel');
|
|||
|
if (colorPanel.style.display=='none' && px != null && py != null) {
|
|||
|
colorPanel.style.display = "inline-block";
|
|||
|
colorPanel.style.left = px + 'px';
|
|||
|
colorPanel.style.top = py + 'px';
|
|||
|
window.jsColorPicker.create();
|
|||
|
}
|
|||
|
else {
|
|||
|
colorPanel.style.display = 'none';
|
|||
|
delete window.jsColorPicker.confirm;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function confirmColor() {
|
|||
|
var colorPicker = document.getElementById("colorPicker");
|
|||
|
if (window.jsColorPicker.confirm) { /* 存在块 */
|
|||
|
// 检测需要是合法数值
|
|||
|
var val = colorPicker.value;
|
|||
|
if (/^[0-9 ]+,[0-9 ]+,[0-9 ]+,[0-9. ]+$/.test(val)) val = "rgba("+val+")";
|
|||
|
else if (/^[0-9 ]+,[0-9 ]+,[0-9 ]+$/.test(val)) val = "rgba("+val+",1)";
|
|||
|
else val = null;
|
|||
|
if (val) window.jsColorPicker.confirm(val);
|
|||
|
}
|
|||
|
else {
|
|||
|
colorPicker.select();
|
|||
|
document.execCommand("Copy");
|
|||
|
}
|
|||
|
colorPanel.style.display = 'none';
|
|||
|
delete window.jsColorPicker.confirm;
|
|||
|
}
|
|||
|
|
|||
|
// ------ AutoCompletion ------
|
|||
|
|