Created
October 7, 2015 16:45
-
-
Save jarek-foksa/ce0797b97d7671b51962 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @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