external range

This commit is contained in:
Ondrej Zara 2019-04-30 10:02:34 +02:00
parent c2c1488d1e
commit 6d9b611928
5 changed files with 12 additions and 235 deletions

View file

@ -25,7 +25,6 @@ watch: all
while inotifywait -e MODIFY -r $(APP)/css $(APP)/js ; do make $^ ; done
clean:
systemctl --user disable $(SERVICE)
rm -f $(SERVICE) $(CSS)
.PHONY: all watch icons service clean

View file

@ -99,9 +99,11 @@ x-range {
--thumb-size: 8px;
--thumb-color: #fff;
--thumb-shadow: #000;
--thumb-hover-color: #ddd;
--track-size: 4px;
--track-color: gray;
--elapsed-color: lightgray;
--track-color: #888;
--track-shadow: #000;
--elapsed-color: #ddd;
--remaining-color: transparent;
--radius: calc(var(--track-size)/2);
width: 192px;
@ -119,7 +121,8 @@ x-range .-remaining {
x-range .-track {
width: 100%;
left: 0;
background-color: gray;
background-color: var(--track-color);
box-shadow: 0 0 1px var(--thumb-shadow);
}
x-range .-elapsed {
left: 0;
@ -150,6 +153,9 @@ x-range .-thumb {
x-range[disabled] {
opacity: 0.5;
}
x-range:not([disabled]) .-thumb:hover {
background-color: var(--thumb-hover-color);
}
main {
flex-grow: 1;
overflow: hidden;

View file

@ -1,63 +0,0 @@
x-range {
--thumb-size: 8px;
--thumb-color: #fff;
--thumb-shadow: #000;
--track-size: 4px;
--track-color: gray;
--elapsed-color: lightgray;
--remaining-color: transparent;
--radius: calc(var(--track-size)/2);
width: 192px;
height: 16px;
position: relative;
.-track, .-elapsed, .-remaining {
position: absolute;
top: calc(50% - var(--track-size)/2);
height: var(--track-size);
border-radius: var(--radius);
}
.-track {
width: 100%;
left: 0;
background-color: gray;
}
.-elapsed {
left: 0;
background-color: var(--elapsed-color);
}
.-remaining {
right: 0;
background-color: var(--remaining-color);
}
.-inner {
position: absolute;
left: var(--thumb-size);
right: var(--thumb-size);
top: 0;
bottom: 0;
}
.-thumb {
all: unset;
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
border-radius: 50%;
width: calc(2*var(--thumb-size));
height: calc(2*var(--thumb-size));
background-color: var(--thumb-color);
box-shadow: 0 0 2px var(--thumb-shadow);
}
&[disabled] {
opacity: 0.5;
}
}

1
app/css/range.less Symbolic link
View file

@ -0,0 +1 @@
../../node_modules/custom-range/range.less

View file

@ -1,168 +0,0 @@
import * as html from "./html.js";
class Range extends HTMLElement {
static get observedAttributes() { return ["min", "max", "value", "step", "disabled"]; }
constructor() {
super();
this._dom = {};
this.innerHTML = `
<span class="-track"></span>
<span class="-elapsed"></span>
<span class="-remaining"></span>
<div class="-inner">
<button class="-thumb"></button>
</div>
`;
Array.from(this.querySelectorAll("[class^='-']")).forEach(node => {
let name = node.className.substring(1);
this._dom[name] = node;
});
this._update();
this.addEventListener("mousedown", this);
this.addEventListener("keydown", this);
}
get _valueAsNumber() {
let raw = (this.hasAttribute("value") ? Number(this.getAttribute("value")) : 50);
return this._constrain(raw);
}
get _minAsNumber() {
return (this.hasAttribute("min") ? Number(this.getAttribute("min")) : 0);
}
get _maxAsNumber() {
return (this.hasAttribute("max") ? Number(this.getAttribute("max")) : 100);
}
get _stepAsNumber() {
return (this.hasAttribute("step") ? Number(this.getAttribute("step")) : 1);
}
get value() { return String(this._valueAsNumber); }
get valueAsNumber() { return this._valueAsNumber; }
get min() { return this.hasAttribute("min") ? this.getAttribute("min") : ""; }
get max() { return this.hasAttribute("max") ? this.getAttribute("max") : ""; }
get step() { return this.hasAttribute("step") ? this.getAttribute("step") : ""; }
get disabled() { return this.hasAttribute("disabled"); }
set _valueAsNumber(value) { this.value = String(value); }
set min(min) { this.setAttribute("min", min); }
set max(max) { this.setAttribute("max", max); }
set value(value) { this.setAttribute("value", value); }
set step(step) { this.setAttribute("step", step); }
set disabled(disabled) {
disabled ? this.setAttribute("disabled", "") : this.removeAttribute("disabled");
}
attributeChangedCallback(name, oldValue, newValue) {
switch (name) {
case "min":
case "max":
case "value":
case "step":
this._update();
break;
}
}
handleEvent(e) {
switch (e.type) {
case "mousedown":
if (this.disabled) { return; }
document.addEventListener("mousemove", this);
document.addEventListener("mouseup", this);
this._setToMouse(e);
break;
case "mousemove":
this._setToMouse(e);
break;
case "mouseup":
document.removeEventListener("mousemove", this);
document.removeEventListener("mouseup", this);
this.dispatchEvent(new CustomEvent("change"));
break;
case "keydown":
if (this.disabled) { return; }
this._handleKey(e.code);
this.dispatchEvent(new CustomEvent("input"));
this.dispatchEvent(new CustomEvent("change"));
break;
}
}
_handleKey(code) {
let min = this._minAsNumber;
let max = this._maxAsNumber;
let range = max - min;
let step = this._stepAsNumber;
switch (code) {
case "ArrowLeft":
case "ArrowDown":
this._valueAsNumber = this._constrain(this._valueAsNumber - step);
break;
case "ArrowRight":
case "ArrowUp":
this._valueAsNumber = this._constrain(this._valueAsNumber + step);
break;
case "Home": this._valueAsNumber = this._constrain(min); break;
case "End": this._valueAsNumber = this._constrain(max); break;
case "PageUp": this._valueAsNumber = this._constrain(this._valueAsNumber + range/10); break;
case "PageDown": this._valueAsNumber = this._constrain(this._valueAsNumber - range/10); break;
}
}
_constrain(value) {
const min = this._minAsNumber;
const max = this._maxAsNumber;
const step = this._stepAsNumber;
value = Math.max(value, min);
value = Math.min(value, max);
value -= min;
value = Math.round(value / step) * step;
value += min;
if (value > max) { value -= step; }
return value;
}
_update() {
let min = this._minAsNumber;
let max = this._maxAsNumber;
let frac = (this._valueAsNumber-min) / (max-min);
this._dom.thumb.style.left = `${frac * 100}%`;
this._dom.remaining.style.left = `${frac * 100}%`;
this._dom.elapsed.style.width = `${frac * 100}%`;
}
_setToMouse(e) {
let rect = this._dom.inner.getBoundingClientRect();
let x = e.clientX;
x = Math.max(x, rect.left);
x = Math.min(x, rect.right);
let min = this._minAsNumber;
let max = this._maxAsNumber;
let frac = (x-rect.left) / (rect.right-rect.left);
let value = this._constrain(min + frac * (max-min));
if (value == this._valueAsNumber) { return; }
this._valueAsNumber = value;
this.dispatchEvent(new CustomEvent("input"));
}
}
customElements.define('x-range', Range);

1
app/js/lib/range.js Symbolic link
View file

@ -0,0 +1 @@
../../../node_modules/custom-range/range.js

View file

@ -4,6 +4,7 @@
"description": "",
"main": "index.js",
"dependencies": {
"custom-range": "^1.0.0",
"node-static": "^0.7.11",
"ws2mpd": "^2.0.0"
},