mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
397 lines
13 KiB
JavaScript
397 lines
13 KiB
JavaScript
|
define([
|
||
|
'lib/stapes',
|
||
|
'lib/tinycolor',
|
||
|
'utils/Tools',
|
||
|
'views/Slider'
|
||
|
], function (Stapes, Tinycolor, tools, Slider) {
|
||
|
'use strict';
|
||
|
var timer;
|
||
|
|
||
|
function showMessageField (text, type) {
|
||
|
var dom, wrapper;
|
||
|
|
||
|
dom = document.querySelector('.work .msg');
|
||
|
|
||
|
if (!dom) {
|
||
|
dom = document.createElement('div');
|
||
|
dom.classList.add('msg');
|
||
|
dom.classList.add(type);
|
||
|
wrapper = document.createElement('div');
|
||
|
wrapper.classList.add('wrapper_msg');
|
||
|
wrapper.classList.add('invisible');
|
||
|
wrapper.appendChild(dom);
|
||
|
|
||
|
document.querySelector('.work').appendChild(wrapper);
|
||
|
setTimeout(function () {
|
||
|
wrapper.classList.remove('invisible');
|
||
|
}, 0);
|
||
|
}
|
||
|
|
||
|
if (!dom.classList.contains(type)) {
|
||
|
dom.className = 'msg';
|
||
|
dom.classList.add(type);
|
||
|
}
|
||
|
dom.innerHTML = text;
|
||
|
if (timer) {
|
||
|
clearTimeout(timer);
|
||
|
}
|
||
|
timer = setTimeout(function () {
|
||
|
var error = document.querySelector('.work .wrapper_msg');
|
||
|
if (error) {
|
||
|
error.parentNode.removeChild(error);
|
||
|
}
|
||
|
}, 1600);
|
||
|
}
|
||
|
|
||
|
return Stapes.subclass(/** @lends MainView.prototype*/{
|
||
|
pointer: null,
|
||
|
colorpicker: null,
|
||
|
slider: null,
|
||
|
sliderinput: null,
|
||
|
cpradius: 0,
|
||
|
cpcenter: 0,
|
||
|
drag: false,
|
||
|
color: null,
|
||
|
brightness: 1.0,
|
||
|
inputbox: null,
|
||
|
|
||
|
/**
|
||
|
* @class MainView
|
||
|
* @construct
|
||
|
* @fires barClick
|
||
|
* @fires colorChange
|
||
|
*/
|
||
|
constructor: function () {
|
||
|
var ev;
|
||
|
this.pointer = document.querySelector('#colorpicker #pointer');
|
||
|
this.colorpicker = document.querySelector('#colorpicker #colorwheelbg');
|
||
|
this.slider = new Slider({
|
||
|
element: document.getElementById('brightness'),
|
||
|
min: 0,
|
||
|
max: 1,
|
||
|
step: 0.02,
|
||
|
value: 1
|
||
|
});
|
||
|
this.inputbox = document.querySelector('#color input.value');
|
||
|
|
||
|
this.cpradius = this.colorpicker.offsetWidth / 2;
|
||
|
this.cpcenter = this.colorpicker.offsetLeft + this.cpradius;
|
||
|
|
||
|
this.bindEventHandlers();
|
||
|
|
||
|
ev = document.createEvent('Event');
|
||
|
ev.initEvent('resize', true, true);
|
||
|
window.dispatchEvent(ev);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
*/
|
||
|
bindEventHandlers: function () {
|
||
|
var cptouchrect;
|
||
|
|
||
|
window.addEventListener('resize', function () {
|
||
|
var attrW, attrH, side, w = this.colorpicker.parentNode.clientWidth, h = this.colorpicker.parentNode.clientHeight;
|
||
|
|
||
|
attrW = this.colorpicker.getAttribute('width');
|
||
|
attrH = this.colorpicker.getAttribute('height');
|
||
|
side = attrW === 'auto' ? attrH : attrW;
|
||
|
if (w > h) {
|
||
|
if (attrH !== side) {
|
||
|
this.colorpicker.setAttribute('height', side);
|
||
|
this.colorpicker.setAttribute('width', 'auto');
|
||
|
}
|
||
|
} else if (attrW !== side) {
|
||
|
this.colorpicker.setAttribute('height', 'auto');
|
||
|
this.colorpicker.setAttribute('width', side);
|
||
|
}
|
||
|
|
||
|
this.cpradius = this.colorpicker.offsetWidth / 2;
|
||
|
this.cpcenter = this.colorpicker.offsetLeft + this.cpradius;
|
||
|
if (this.color) {
|
||
|
this.updatePointer();
|
||
|
}
|
||
|
}.bind(this));
|
||
|
|
||
|
window.addClickHandler(document.querySelector('.footer'), function (event) {
|
||
|
this.emit('barClick', event.target.parentNode.dataset.area);
|
||
|
}.bind(this));
|
||
|
|
||
|
|
||
|
this.slider.on('changeValue', function (value) {
|
||
|
this.brightness = value.value;
|
||
|
this.updateInput();
|
||
|
this.fireColorEvent();
|
||
|
}, this);
|
||
|
|
||
|
this.inputbox.addEventListener('input', function (event) {
|
||
|
var bright, rgb = new Tinycolor(event.target.value).toRgb();
|
||
|
|
||
|
if (rgb.r === 0 && rgb.g === 0 && rgb.b === 0) {
|
||
|
this.brightness = 0;
|
||
|
this.color = new Tinycolor({
|
||
|
r: 0xff,
|
||
|
g: 0xff,
|
||
|
b: 0xff
|
||
|
});
|
||
|
} else {
|
||
|
bright = Math.max(rgb.r, rgb.g, rgb.b) / 256;
|
||
|
rgb.r = Math.round(rgb.r / bright);
|
||
|
rgb.g = Math.round(rgb.g / bright);
|
||
|
rgb.b = Math.round(rgb.b / bright);
|
||
|
this.brightness = bright;
|
||
|
this.color = new Tinycolor(rgb);
|
||
|
}
|
||
|
|
||
|
this.fireColorEvent();
|
||
|
this.updatePointer();
|
||
|
this.updateSlider();
|
||
|
}.bind(this), false);
|
||
|
|
||
|
this.inputbox.addEventListener('keydown', function (event) {
|
||
|
switch (event.keyCode) {
|
||
|
case 8:
|
||
|
case 9:
|
||
|
case 16:
|
||
|
case 37:
|
||
|
case 38:
|
||
|
case 39:
|
||
|
case 40:
|
||
|
case 46:
|
||
|
break;
|
||
|
default:
|
||
|
{
|
||
|
if (event.target.value.length >= 6 && (event.target.selectionEnd - event.target.selectionStart) === 0) {
|
||
|
event.preventDefault();
|
||
|
event.stopPropagation();
|
||
|
} else if (event.keyCode < 48 || event.keyCode > 71) {
|
||
|
event.preventDefault();
|
||
|
event.stopPropagation();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
cptouchrect = document.querySelector('#colorpicker .touchrect');
|
||
|
window.addPointerDownHandler(cptouchrect, function (event) {
|
||
|
this.leaveInput();
|
||
|
this.drag = true;
|
||
|
this.handleEvent(event);
|
||
|
}.bind(this));
|
||
|
|
||
|
window.addPointerMoveHandler(cptouchrect, function (event) {
|
||
|
if (this.drag) {
|
||
|
this.handleEvent(event);
|
||
|
event.preventDefault();
|
||
|
}
|
||
|
}.bind(this));
|
||
|
|
||
|
window.addPointerUpHandler(cptouchrect, function () {
|
||
|
this.drag = false;
|
||
|
}.bind(this));
|
||
|
|
||
|
window.addClickHandler(document.querySelector('#clear_button'), function () {
|
||
|
this.emit('clear');
|
||
|
}.bind(this));
|
||
|
|
||
|
window.addClickHandler(document.querySelector('#clearall_button'), function () {
|
||
|
this.emit('clearall');
|
||
|
}.bind(this));
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
* @param event
|
||
|
*/
|
||
|
handleEvent: function (event) {
|
||
|
var point, x, y;
|
||
|
|
||
|
if (event.touches) {
|
||
|
x = event.touches[0].clientX;
|
||
|
y = event.touches[0].clientY;
|
||
|
} else {
|
||
|
x = event.clientX;
|
||
|
y = event.clientY;
|
||
|
}
|
||
|
point = this.getCirclePoint(x, y);
|
||
|
this.color = this.getColorFromPoint(point);
|
||
|
|
||
|
this.updatePointer();
|
||
|
this.updateSlider();
|
||
|
this.updateInput();
|
||
|
|
||
|
this.fireColorEvent();
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
* @param {number} x
|
||
|
* @param {number} y
|
||
|
* @returns {{x: number, y: number}}
|
||
|
*/
|
||
|
getCirclePoint: function (x, y) {
|
||
|
var p = {
|
||
|
x: x,
|
||
|
y: y
|
||
|
}, c = {
|
||
|
x: this.colorpicker.offsetLeft + this.cpradius,
|
||
|
y: this.colorpicker.offsetTop + this.cpradius
|
||
|
}, n;
|
||
|
|
||
|
n = Math.sqrt(Math.pow((x - c.x), 2) + Math.pow((y - c.y), 2));
|
||
|
|
||
|
if (n > this.cpradius) {
|
||
|
p.x = (c.x) + this.cpradius * ((x - c.x) / n);
|
||
|
p.y = (c.y) + this.cpradius * ((y - c.y) / n);
|
||
|
}
|
||
|
|
||
|
return p;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
* @param {{x: number, y: number}} p
|
||
|
* @returns {Tinycolor}
|
||
|
*/
|
||
|
getColorFromPoint: function (p) {
|
||
|
var h, t, s, x, y;
|
||
|
x = p.x - this.colorpicker.offsetLeft - this.cpradius;
|
||
|
y = this.cpradius - p.y + this.colorpicker.offsetTop;
|
||
|
t = Math.atan2(y, x);
|
||
|
h = (t * (180 / Math.PI) + 360) % 360;
|
||
|
s = Math.min(Math.sqrt(x * x + y * y) / this.cpradius, 1);
|
||
|
|
||
|
return new Tinycolor({
|
||
|
h: h,
|
||
|
s: s,
|
||
|
v: 1
|
||
|
});
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
* @param color
|
||
|
* @returns {{x: number, y: number}}
|
||
|
*/
|
||
|
getPointFromColor: function (color) {
|
||
|
var t, x, y, p = {};
|
||
|
|
||
|
t = color.h * (Math.PI / 180);
|
||
|
y = Math.sin(t) * this.cpradius * color.s;
|
||
|
x = Math.cos(t) * this.cpradius * color.s;
|
||
|
|
||
|
p.x = Math.round(x + this.colorpicker.offsetLeft + this.cpradius);
|
||
|
p.y = Math.round(this.cpradius - y + this.colorpicker.offsetTop);
|
||
|
|
||
|
return p;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
*/
|
||
|
fireColorEvent: function () {
|
||
|
var rgb = this.color.toRgb();
|
||
|
rgb.r = Math.round(rgb.r * this.brightness);
|
||
|
rgb.g = Math.round(rgb.g * this.brightness);
|
||
|
rgb.b = Math.round(rgb.b * this.brightness);
|
||
|
this.emit('colorChange', rgb);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
*
|
||
|
* @param rgb
|
||
|
*/
|
||
|
setColor: function (rgb) {
|
||
|
var bright;
|
||
|
|
||
|
if (rgb.r === 0 && rgb.g === 0 && rgb.b === 0) {
|
||
|
this.brightness = 0;
|
||
|
this.color = new Tinycolor({
|
||
|
r: 0xff,
|
||
|
g: 0xff,
|
||
|
b: 0xff
|
||
|
});
|
||
|
} else {
|
||
|
bright = Math.max(rgb.r, rgb.g, rgb.b) / 256;
|
||
|
rgb.r = Math.round(rgb.r / bright);
|
||
|
rgb.g = Math.round(rgb.g / bright);
|
||
|
rgb.b = Math.round(rgb.b / bright);
|
||
|
this.brightness = bright;
|
||
|
this.color = new Tinycolor(rgb);
|
||
|
}
|
||
|
|
||
|
this.updatePointer();
|
||
|
this.updateSlider();
|
||
|
this.updateInput();
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
*/
|
||
|
updateSlider: function () {
|
||
|
this.slider.setValue(this.brightness);
|
||
|
this.slider.dom.style.backgroundImage = '-webkit-linear-gradient(left, #000000 0%, ' + this.color.toHexString() + ' 100%)';
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
*/
|
||
|
updatePointer: function () {
|
||
|
var point = this.getPointFromColor(this.color.toHsv());
|
||
|
|
||
|
this.pointer.style.left = (point.x - this.pointer.offsetWidth / 2) + 'px';
|
||
|
this.pointer.style.top = (point.y - this.pointer.offsetHeight / 2) + 'px';
|
||
|
this.pointer.style.backgroundColor = this.color.toHexString();
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
*/
|
||
|
updateInput: function () {
|
||
|
var rgb = this.color.toRgb();
|
||
|
rgb.r = Math.round(rgb.r * this.brightness);
|
||
|
rgb.g = Math.round(rgb.g * this.brightness);
|
||
|
rgb.b = Math.round(rgb.b * this.brightness);
|
||
|
|
||
|
this.inputbox.value = tools.b2hexstr(rgb.r) + tools.b2hexstr(rgb.g) + tools.b2hexstr(rgb.b);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Scroll to the specific tab content
|
||
|
* @param {string} id - Id of the tab to scroll to
|
||
|
*/
|
||
|
scrollToArea: function (id) {
|
||
|
var area, index;
|
||
|
document.querySelector('.footer .selected').classList.remove('selected');
|
||
|
document.querySelector('.footer .button[data-area =' + id + ']').classList.add('selected');
|
||
|
|
||
|
area = document.getElementById(id);
|
||
|
index = area.offsetLeft / area.clientWidth;
|
||
|
area.parentNode.style.left = (-index * 100) + '%';
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Shows a status message
|
||
|
* @param {string} message - Text to show
|
||
|
*/
|
||
|
showStatus: function (message) {
|
||
|
showMessageField(message, 'status');
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Shows the error text
|
||
|
* @param {string} error - Error message
|
||
|
*/
|
||
|
showError: function (error) {
|
||
|
showMessageField(error, 'error');
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
*/
|
||
|
leaveInput: function () {
|
||
|
this.inputbox.blur();
|
||
|
}
|
||
|
});
|
||
|
});
|