external range
This commit is contained in:
parent
c2c1488d1e
commit
6d9b611928
5 changed files with 12 additions and 235 deletions
1
Makefile
1
Makefile
|
@ -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
|
||||
|
|
12
app/app.css
12
app/app.css
|
@ -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;
|
||||
|
|
|
@ -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
1
app/css/range.less
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../node_modules/custom-range/range.less
|
|
@ -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
1
app/js/lib/range.js
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../../node_modules/custom-range/range.js
|
|
@ -4,6 +4,7 @@
|
|||
"description": "",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"custom-range": "^1.0.0",
|
||||
"node-static": "^0.7.11",
|
||||
"ws2mpd": "^2.0.0"
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue