Skip to content

Instantly share code, notes, and snippets.

@jarek-foksa
Created October 7, 2015 16:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jarek-foksa/ce0797b97d7671b51962 to your computer and use it in GitHub Desktop.
Save jarek-foksa/ce0797b97d7671b51962 to your computer and use it in GitHub Desktop.
// @copyright
// © 2012-2015 Jarosław Foksa
import {registerElement} from "../utils/dom";
import {normalize} from "../utils/math";
const DEBUG = false;
const INNER_HTML = `
<style>
@import url("stylesheets/bx-hueslider.css");
</style>
<main>
<canvas id="canvas"></canvas>
<div id="marker"></div>
</main>
`;
const SPECTRUM_STOPS = [
// R G B
[0.00, [255, 0, 0]],
[0.15, [255, 255, 0]],
[0.33, [ 0, 255, 0]],
[0.49, [ 0, 255, 255]],
[0.67, [ 0, 0, 255]],
[0.84, [255, 0, 255]],
[1.00, [255, 0, 0]]
];
// @events
// markerdragstart
// markerdrag hue:number
// markerdragend
class BXHueSliderElement extends HTMLElement {
createdCallback() {
this._shadowRoot = this.createShadowRoot({mode: "closed"});
this._shadowRoot.innerHTML = INNER_HTML;
for (let element of this._shadowRoot.querySelectorAll("[id]")) this["#" + element.id] = element;
this["#canvas"].addEventListener("mousedown", (event) => this._onMouseDown(event));
this._drawSpectrum();
}
attributeChangedCallback(name, oldValue, newValue) {
if (oldValue === newValue) {
return;
}
else if (name === "hue") {
this._onHueChange();
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// @property
// reflected
// @type
// number
// @default
// 360
get hue() {
if (this.hasAttribute("hue")) {
return parseInt(this.getAttribute("hue"));
}
else {
return 360;
}
}
set hue(hue) {
this.setAttribute("hue", hue);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
_onMouseDown(mouseDownEvent) {
this.dispatchEvent(
new CustomEvent("markerdragstart")
);
let cachedClientX, mouseMoveListener, mouseUpListener;
let canvasX = this["#canvas"].getBoundingClientRect().left;
this._onMarkerDrag(mouseDownEvent.clientX - canvasX);
window.addEventListener("mousemove", mouseMoveListener = (mouseMoveEvent) => {
if (mouseMoveEvent.clientX === cachedClientX) {
return;
}
cachedClientX = mouseMoveEvent.clientX;
this._onMarkerDrag(mouseMoveEvent.clientX - canvasX);
});
window.addEventListener("mouseup", mouseUpListener = () => {
window.removeEventListener("mousemove", mouseMoveListener);
window.removeEventListener("mouseup", mouseUpListener);
this.dispatchEvent(
new CustomEvent("markerdragend")
);
});
}
_onMarkerDrag(x) {
let hue = normalize(((x / this["#canvas"].clientWidth) * 360), 0, 360, 0);
if (this.hue !== hue) {
this.hue = hue;
this.dispatchEvent(
new CustomEvent("markerdrag", {
detail: this.hue
})
);
if (DEBUG) {
console.log('%c ', `background: hsl(${hue}, 100%, 50%)`, `hue = ${hue}`);
}
}
}
_onHueChange() {
let hue = normalize(this.hue, 0, 360, 0);
this["#marker"].style.left = ((hue / 360) * 100) + "%";
}
_drawSpectrum() {
let width = this["#canvas"].width = 800;
let height = this["#canvas"].height = 100;
let context = this["#canvas"].getContext("2d");
let gradient = context.createLinearGradient(0, 0, width, 0);
for (let stop of SPECTRUM_STOPS) {
gradient.addColorStop(stop[0], `rgb(${stop[1][0]}, ${stop[1][1]}, ${stop[1][2]})`);
}
context.fillStyle = gradient;
context.fillRect(0, 0, width, height);
}
};
export default registerElement("bx-hueslider", BXHueSliderElement);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment