MAAAJOOOOR

This commit is contained in:
Mahdi Dibaiee
2014-02-05 16:32:07 +03:30
parent e7d1c2399f
commit cfe3bb7e99
17 changed files with 1307 additions and 94 deletions

View File

@ -0,0 +1,290 @@
/*
Purty Picker Copyright 2013 Jayden Seric (MIT license).
A super lightweight visual HSL, RGB and hex color picker with a responsive, touch-friendly and customizable UI.
Requires jQuery or Zepto with core and event modules.
https://github.com/jaydenseric/Purty-Picker
*/
// DOM ready
$(function() {
'use strict';
//-------------------------------------------- Color conversions
//---------------------- Convert HSL to RGB
// Source: http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c
function HSLToRGB(h, s, l) {
h /= 360;
s /= 100;
l /= 100;
var r, g, b;
if(s == 0) {
r = g = b = l; // Achromatic
} else {
var hueToRGB = function(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;
};
var q = l < 0.5 ? l * (1 + s) : l + s - l * s,
p = 2 * l - q;
r = hueToRGB(p, q, h + 1/3);
g = hueToRGB(p, q, h);
b = hueToRGB(p, q, h - 1/3);
}
return {
red: Math.round(r * 255),
green: Math.round(g * 255),
blue: Math.round(b * 255)
};
}
//---------------------- Convert RGB to HSL
// Source: http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c
function RGBToHSL(r, g, b) {
r /= 255,
g /= 255,
b /= 255;
var max = Math.max(r, g, b),
min = Math.min(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 {
hue: Math.round(h * 360),
saturation: Math.round(s * 100),
luminosity: Math.round(l * 100)
};
}
//---------------------- Convert RGB to Hex
// Source: http://stackoverflow.com/a/5624139
function RGBToHex(r, g, b) {
return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}
//---------------------- Convert hex to RGB
// Source: http://stackoverflow.com/a/11508164
function hexToRGB(hex) {
var bigInt = parseInt(hex.replace('#', ''), 16),
r = (bigInt >> 16) & 255,
g = (bigInt >> 8) & 255,
b = bigInt & 255;
return {
red: r,
green: g,
blue: b
};
}
//---------------------- Convert hex to HSL
function hexToHSL(hex) {
var RGB = hexToRGB(hex);
return RGBToHSL(RGB.red, RGB.green, RGB.blue);
}
//---------------------- Convert HSL to hex
function HSLToHex(h, s, l) {
var RGB = HSLToRGB(h, s, l);
return RGBToHex(RGB.red, RGB.green, RGB.blue);
}
//-------------------------------------------- Setup each color picker
$.each($('.color-picker'), function() {
//---------------------- Find componenets
var picker = $(this),
formatInput = picker.find('.format'),
colorInput = picker.find('.color'),
luminosityInput = picker.find('input[type=range]'),
spectrum = picker.find('.spectrum'),
pin = picker.find('.pin');
//---------------------- Get current color in HSL
function getHSL() {
var position = picker.find('.pin').position(),
width = spectrum.width(),
height = spectrum.height();
return {
hue: Math.round(position.left / width * 360),
saturation: Math.round(position.top / height * 100),
luminosity: luminosityInput.val()
};
}
//---------------------- Output color in desired format
function updateColorInput() {
var HSL = getHSL();
switch (formatInput.val()) {
case 'HSL':
colorInput.val('hsl(' + HSL.hue + ', ' + HSL.saturation + '%, ' + HSL.luminosity + '%)');
break;
case 'RGB':
var RGB = HSLToRGB(HSL.hue, HSL.saturation, HSL.luminosity);
colorInput.val('rgb(' + RGB.red + ', ' + RGB.green + ', ' + RGB.blue + ')');
break;
case 'Hex':
colorInput.val(HSLToHex(HSL.hue, HSL.saturation, HSL.luminosity));
break;
}
// Trigger color picker change event for custom callbacks
picker.trigger('change');
}
//---------------------- Set color format
formatInput.on('change', function() {
updateColorInput();
});
//---------------------- Set color
colorInput.on('change', function() {
// Get the color values in HSL format
var HSL;
switch (formatInput.val()) {
case 'HSL':
var values = $(this).val().match(/\d+/g);
HSL = {
hue: values[0],
saturation: values[1],
luminosity: values[2]
};
break;
case 'RGB':
var values = $(this).val().match(/\d+/g);
HSL = RGBToHSL(values[0], values[1], values[2]);
break;
case 'Hex':
HSL = hexToHSL($(this).val());
break;
}
// Set the luminosity
luminosityInput.val(HSL.luminosity);
setLuminosity(HSL.luminosity);
// Place the pin
pin.css({
left: HSL.hue / 360 * 100 + '%',
top: HSL.saturation + '%'
});
// Trigger color picker change event for custom callbacks
picker.trigger('change');
});
//---------------------- Set luminosity
//---------- Set the luminosity spectrum overlay
function setLuminosity(luminosity) {
var color,
alpha;
if (luminosity <= 50) {
color = '0, 0, 0';
alpha = 1 - luminosity / 100 * 2;
} else {
color = '255, 255, 255';
alpha = luminosity / 100 * 2 - 1;
}
// Apply luminosity to the spectrum
spectrum.children().css('background-color', 'rgba(' + color + ', ' + alpha + ')');
}
//---------- Luminosity input interaction
luminosityInput.on('change', function() {
setLuminosity($(this).val());
updateColorInput();
});
//---------------------- Set hue, saturation via pin
//---------- Move the pin
var movePin = function(event) {
var offset = spectrum.offset(),
width = spectrum.width(),
height = spectrum.height(),
x = event.changedTouches[0].clientX - offset.left,
y = event.changedTouches[0].clientY - offset.top;
// Account for pin being dragged outside the spectrum area
// Sanatize x
if (x < 0) {
x = 0;
} else if (x >= width) {
x = width;
}
// Sanatize y
if (y < 0) {
y = 0;
} else if (y >= height) {
y = height;
}
// Place the pin
pin.css({
left: x / width * 100 + '%',
top: y / height * 100 + '%'
});
// Output new color value
updateColorInput();
};
//---------- Pin interaction
spectrum.on('touchstart', function(event) {
event.preventDefault();
movePin(event);
spectrum.addClass('active');
$(document).on('touchmove', movePin);
});
$(document).on('touchend', function() {
spectrum.removeClass('active');
$(document).off('touchmove', movePin);
});
spectrum.on('touchmove touchstart', movePin);
//---------------------- Output color preview
picker.on('change', function() {
colorInput.css('background-color', colorInput.val()).toggleClass('dark', luminosityInput.val() <= 50);
});
//---------------------- Initialize this color picker
colorInput.trigger('change');
});
});

289
js/libs/color-picker.js Normal file
View File

@ -0,0 +1,289 @@
/*
Purty Picker Copyright 2013 Jayden Seric (MIT license).
A super lightweight visual HSL, RGB and hex color picker with a responsive, touch-friendly and customizable UI.
Requires jQuery or Zepto with core and event modules.
https://github.com/jaydenseric/Purty-Picker
*/
// DOM ready
$(function() {
'use strict';
//-------------------------------------------- Color conversions
//---------------------- Convert HSL to RGB
// Source: http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c
function HSLToRGB(h, s, l) {
h /= 360;
s /= 100;
l /= 100;
var r, g, b;
if(s == 0) {
r = g = b = l; // Achromatic
} else {
var hueToRGB = function(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;
};
var q = l < 0.5 ? l * (1 + s) : l + s - l * s,
p = 2 * l - q;
r = hueToRGB(p, q, h + 1/3);
g = hueToRGB(p, q, h);
b = hueToRGB(p, q, h - 1/3);
}
return {
red: Math.round(r * 255),
green: Math.round(g * 255),
blue: Math.round(b * 255)
};
}
//---------------------- Convert RGB to HSL
// Source: http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c
function RGBToHSL(r, g, b) {
r /= 255,
g /= 255,
b /= 255;
var max = Math.max(r, g, b),
min = Math.min(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 {
hue: Math.round(h * 360),
saturation: Math.round(s * 100),
luminosity: Math.round(l * 100)
};
}
//---------------------- Convert RGB to Hex
// Source: http://stackoverflow.com/a/5624139
function RGBToHex(r, g, b) {
return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}
//---------------------- Convert hex to RGB
// Source: http://stackoverflow.com/a/11508164
function hexToRGB(hex) {
var bigInt = parseInt(hex.replace('#', ''), 16),
r = (bigInt >> 16) & 255,
g = (bigInt >> 8) & 255,
b = bigInt & 255;
return {
red: r,
green: g,
blue: b
};
}
//---------------------- Convert hex to HSL
function hexToHSL(hex) {
var RGB = hexToRGB(hex);
return RGBToHSL(RGB.red, RGB.green, RGB.blue);
}
//---------------------- Convert HSL to hex
function HSLToHex(h, s, l) {
var RGB = HSLToRGB(h, s, l);
return RGBToHex(RGB.red, RGB.green, RGB.blue);
}
//-------------------------------------------- Setup each color picker
$.each($('.color-picker'), function() {
//---------------------- Find componenets
var picker = $(this),
formatInput = picker.find('.format'),
colorInput = picker.find('.color'),
luminosityInput = picker.find('input[type=range]'),
spectrum = picker.find('.spectrum'),
pin = picker.find('.pin');
//---------------------- Get current color in HSL
function getHSL() {
var position = picker.find('.pin').position(),
width = spectrum.width(),
height = spectrum.height();
return {
hue: Math.round(position.left / width * 360),
saturation: Math.round(position.top / height * 100),
luminosity: luminosityInput.val()
};
}
//---------------------- Output color in desired format
function updateColorInput() {
var HSL = getHSL();
switch (formatInput.val()) {
case 'HSL':
colorInput.val('hsl(' + HSL.hue + ', ' + HSL.saturation + '%, ' + HSL.luminosity + '%)');
break;
case 'RGB':
var RGB = HSLToRGB(HSL.hue, HSL.saturation, HSL.luminosity);
colorInput.val('rgb(' + RGB.red + ', ' + RGB.green + ', ' + RGB.blue + ')');
break;
case 'Hex':
colorInput.val(HSLToHex(HSL.hue, HSL.saturation, HSL.luminosity));
break;
}
// Trigger color picker change event for custom callbacks
picker.trigger('change');
}
//---------------------- Set color format
formatInput.on('change', function() {
updateColorInput();
});
//---------------------- Set color
colorInput.on('change', function() {
// Get the color values in HSL format
var HSL;
switch (formatInput.val()) {
case 'HSL':
var values = $(this).val().match(/\d+/g);
HSL = {
hue: values[0],
saturation: values[1],
luminosity: values[2]
};
break;
case 'RGB':
var values = $(this).val().match(/\d+/g);
HSL = RGBToHSL(values[0], values[1], values[2]);
break;
case 'Hex':
HSL = hexToHSL($(this).val());
break;
}
// Set the luminosity
luminosityInput.val(HSL.luminosity);
setLuminosity(HSL.luminosity);
// Place the pin
pin.css({
left: HSL.hue / 360 * 100 + '%',
top: HSL.saturation + '%'
});
// Trigger color picker change event for custom callbacks
picker.trigger('change');
});
//---------------------- Set luminosity
//---------- Set the luminosity spectrum overlay
function setLuminosity(luminosity) {
var color,
alpha;
if (luminosity <= 50) {
color = '0, 0, 0';
alpha = 1 - luminosity / 100 * 2;
} else {
color = '255, 255, 255';
alpha = luminosity / 100 * 2 - 1;
}
// Apply luminosity to the spectrum
spectrum.children().css('background-color', 'rgba(' + color + ', ' + alpha + ')');
}
//---------- Luminosity input interaction
luminosityInput.on('change', function() {
setLuminosity($(this).val());
updateColorInput();
});
//---------------------- Set hue, saturation via pin
//---------- Move the pin
var movePin = function(event) {
var offset = spectrum.offset(),
width = spectrum.width(),
height = spectrum.height(),
x = event.clientX - offset.left,
y = event.clientY - offset.top;
// Account for pin being dragged outside the spectrum area
// Sanatize x
if (x < 0) {
x = 0;
} else if (x >= width) {
x = width;
}
// Sanatize y
if (y < 0) {
y = 0;
} else if (y >= height) {
y = height;
}
// Place the pin
pin.css({
left: x / width * 100 + '%',
top: y / height * 100 + '%'
});
// Output new color value
updateColorInput();
};
//---------- Pin interaction
spectrum.on('mousedown', function(event) {
event.preventDefault();
movePin(event);
spectrum.addClass('active');
$(document).on('mousemove', movePin);
});
$(document).on('mouseup', function() {
spectrum.removeClass('active');
$(document).off('mousemove', movePin);
});
spectrum.on('touchmove touchstart', movePin);
//---------------------- Output color preview
picker.on('change', function() {
colorInput.css('background-color', colorInput.val()).toggleClass('dark', luminosityInput.val() <= 50);
});
//---------------------- Initialize this color picker
colorInput.trigger('change');
});
});

22
js/libs/stack.js Normal file
View File

@ -0,0 +1,22 @@
// Zepto.js
// (c) 2010-2014 Thomas Fuchs
// Zepto.js may be freely distributed under the MIT license.
;(function($){
$.fn.end = function(){
return this.prevObject || $()
}
$.fn.andSelf = function(){
return this.add(this.prevObject || $())
}
'filter,add,not,eq,first,last,find,closest,parents,parent,children,siblings'.split(',').forEach(function(property){
var fn = $.fn[property]
$.fn[property] = function(){
var ret = fn.apply(this, arguments)
ret.prevObject = this
return ret
}
})
})(Zepto)

165
js/libs/touch.js Normal file
View File

@ -0,0 +1,165 @@
// Zepto.js
// (c) 2010-2014 Thomas Fuchs
// Zepto.js may be freely distributed under the MIT license.
;(function($){
var touch = {},
touchTimeout, tapTimeout, swipeTimeout, longTapTimeout,
longTapDelay = 750,
gesture
function swipeDirection(x1, x2, y1, y2) {
return Math.abs(x1 - x2) >=
Math.abs(y1 - y2) ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down')
}
function longTap() {
longTapTimeout = null
if (touch.last) {
touch.el.trigger('longTap')
touch = {}
}
}
function cancelLongTap() {
if (longTapTimeout) clearTimeout(longTapTimeout)
longTapTimeout = null
}
function cancelAll() {
if (touchTimeout) clearTimeout(touchTimeout)
if (tapTimeout) clearTimeout(tapTimeout)
if (swipeTimeout) clearTimeout(swipeTimeout)
if (longTapTimeout) clearTimeout(longTapTimeout)
touchTimeout = tapTimeout = swipeTimeout = longTapTimeout = null
touch = {}
}
function isPrimaryTouch(event){
return (event.pointerType == 'touch' ||
event.pointerType == event.MSPOINTER_TYPE_TOUCH)
&& event.isPrimary
}
function isPointerEventType(e, type){
return (e.type == 'pointer'+type ||
e.type.toLowerCase() == 'mspointer'+type)
}
$(document).ready(function(){
var now, delta, deltaX = 0, deltaY = 0, firstTouch, _isPointerType
if ('MSGesture' in window) {
gesture = new MSGesture()
gesture.target = document.body
}
$(document)
.bind('MSGestureEnd', function(e){
var swipeDirectionFromVelocity =
e.velocityX > 1 ? 'Right' : e.velocityX < -1 ? 'Left' : e.velocityY > 1 ? 'Down' : e.velocityY < -1 ? 'Up' : null;
if (swipeDirectionFromVelocity) {
touch.el.trigger('swipe')
touch.el.trigger('swipe'+ swipeDirectionFromVelocity)
}
})
.on('touchstart MSPointerDown pointerdown', function(e){
if((_isPointerType = isPointerEventType(e, 'down')) &&
!isPrimaryTouch(e)) return
firstTouch = _isPointerType ? e : e.touches[0]
if (e.touches && e.touches.length === 1 && touch.x2) {
// Clear out touch movement data if we have it sticking around
// This can occur if touchcancel doesn't fire due to preventDefault, etc.
touch.x2 = undefined
touch.y2 = undefined
}
now = Date.now()
delta = now - (touch.last || now)
touch.el = $('tagName' in firstTouch.target ?
firstTouch.target : firstTouch.target.parentNode)
touchTimeout && clearTimeout(touchTimeout)
touch.x1 = firstTouch.pageX
touch.y1 = firstTouch.pageY
if (delta > 0 && delta <= 250) touch.isDoubleTap = true
touch.last = now
longTapTimeout = setTimeout(longTap, longTapDelay)
// adds the current touch contact for IE gesture recognition
if (gesture && _isPointerType) gesture.addPointer(e.pointerId);
})
.on('touchmove MSPointerMove pointermove', function(e){
if((_isPointerType = isPointerEventType(e, 'move')) &&
!isPrimaryTouch(e)) return
firstTouch = _isPointerType ? e : e.touches[0]
cancelLongTap()
touch.x2 = firstTouch.pageX
touch.y2 = firstTouch.pageY
deltaX += Math.abs(touch.x1 - touch.x2)
deltaY += Math.abs(touch.y1 - touch.y2)
})
.on('touchend MSPointerUp pointerup', function(e){
if((_isPointerType = isPointerEventType(e, 'up')) &&
!isPrimaryTouch(e)) return
cancelLongTap()
// swipe
if ((touch.x2 && Math.abs(touch.x1 - touch.x2) > 30) ||
(touch.y2 && Math.abs(touch.y1 - touch.y2) > 30))
swipeTimeout = setTimeout(function() {
touch.el.trigger('swipe')
touch.el.trigger('swipe' + (swipeDirection(touch.x1, touch.x2, touch.y1, touch.y2)))
touch = {}
}, 0)
// normal tap
else if ('last' in touch)
// don't fire tap when delta position changed by more than 30 pixels,
// for instance when moving to a point and back to origin
if (deltaX < 30 && deltaY < 30) {
// delay by one tick so we can cancel the 'tap' event if 'scroll' fires
// ('tap' fires before 'scroll')
tapTimeout = setTimeout(function() {
// trigger universal 'tap' with the option to cancelTouch()
// (cancelTouch cancels processing of single vs double taps for faster 'tap' response)
var event = $.Event('tap')
event.cancelTouch = cancelAll
touch.el.trigger(event)
// trigger double tap immediately
if (touch.isDoubleTap) {
if (touch.el) touch.el.trigger('doubleTap')
touch = {}
}
// trigger single tap after 250ms of inactivity
else {
touchTimeout = setTimeout(function(){
touchTimeout = null
if (touch.el) touch.el.trigger('singleTap')
touch = {}
}, 250)
}
}, 0)
} else {
touch = {}
}
deltaX = deltaY = 0
})
// when the browser window loses focus,
// for example when a modal dialog is shown,
// cancel all ongoing events
.on('touchcancel MSPointerCancel pointercancel', cancelAll)
// scrolling the window indicates intention of the user
// to scroll, not tap or swipe, so cancel all ongoing events
$(window).on('scroll', cancelAll)
})
;['swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown',
'doubleTap', 'tap', 'singleTap', 'longTap'].forEach(function(eventName){
$.fn[eventName] = function(callback){ return this.on(eventName, callback) }
})
})(Zepto)

File diff suppressed because one or more lines are too long