JSFiddle - React, Tailwind, and code Playground
by jcubed111
HTML
<template id="sliderTemplate">
<div class="vbar">
<div class="topper"></div>
<div class="sliderOuter">
<div class="sliderInner"></div>
<div class="sliderMarker"></div>
</div>
<div class="numberWrapper">
<input class="numberBox" />
<div class="arrowWrapper">
<div class="arrow arrowUp">⯅</div>
<div class="arrow arrowDown">⯆</div>
</div>
</div>
</div>
</template>
SCSS
@import url('https://fonts.googleapis.com/css?family=Inconsolata:400,700&display=swap');
*{
box-sizing: border-box;
}
body{
background: #181818;
}
.vbar{
height: 376px; // This must be even! Otherwise positional math comes out weid.
border-radius: 8px;
border: 1px solid #000;
background: #222;
width: 90px;
display: flex;
flex-direction: column;
padding: 5px;
.topper,
.numberWrapper{
border-radius: 4px;
overflow: hidden;
height: 0px;
flex-grow: 1;
border: 1px solid #000;
}
.sliderOuter{
$vMargin: 12px;
height: 256px + $vMargin*2;
position: relative;
.sliderInner{
box-sizing: content-box;
height: 256px;
background: linear-gradient(#ff0000, #000000);
position: absolute;
border: 1px solid #000;
top: $vMargin - 1px;
left: 3px;
right: 3px;
border-radius: 3px;
}
.sliderMarker{
box-sizing: content-box;
position: absolute;
left: 0px;
right: 0px;
margin-top: $vMargin - 7px;
top: 180px;
height: 1px;
border: 7px solid #ccc;
background: transparent;
border-top-color: transparent;
border-bottom-color: transparent;
}
}
.topper{
background: rgb(75, 0, 0);
}
.numberWrapper{
display: flex;
.numberBox{
margin: 0;
box-sizing: border-box;
border: 0px none;
width: 0px;
flex-shrink: 1;
flex-grow: 1;
background: #181818;
color: #aaa;
font-size: 23px;
font-family: Inconsolata, monospace;
padding: 5px 8px;
letter-spacing: 1px;
}
.arrowWrapper{
...
JavaScript
function rgb(...args) { return 'rgb(' + args.map(a => ~~a).join(',') + ')'; }
class View{
constructor() {
this.el = this.el();
}
$(s) {
return this.el.querySelector(s);
}
}
class Color{
constructor() {
this.isRgb = true;
this.value = [0, 0, 0, 255];
}
r() { return this.asRgb()[0]; }
g() { return this.asRgb()[1]; }
b() { return this.asRgb()[2]; }
h() { return this.asHsv()[0]; }
s() { return this.asHsv()[1]; }
v() { return this.asHsv()[2]; }
a() { return this.asRgb()[3]; }
setR(v) {
this.convertToRgb();
this.value[0] = v;
}
setG(v) {
this.convertToRgb();
this.value[1] = v;
}
setB(v) {
this.convertToRgb();
this.value[2] = v;
}
setH(v) {
this.convertToHsv();
this.value[0] = v;
}
setS(v) {
this.convertToHsv();
this.value[1] = v;
}
setV(v) {
this.convertToHsv();
this.value[2] = v;
}
setA(v) {
this.value[3] = v;
}
convertToRgb() {
this.value = this.asRgb();
this.isRgb = true;
}
convertToHsv() {
this.value = this.asHsv();
this.isRgb = false;
}
asRgb() {
if(this.isRgb) {
return this.value.slice();
}else{
let h, s, v;
let [r, g, b, a] = this.value;
let max = Math.max(r, g, b);
let min = Math.min(r, g, b);
if(max == min) {
h = 0;
}else if(max == r) {
h = 60 * (0 + (g - b) / (max - min));
}else if(max == g) {
h = 60 * (2 + (b - r) / (max - min));
}else if(max == b) {
h = 60 * (4 + (r - g) / (max - min));
}
if(max == 0) {
s = 0;
}else{
s = (max - min) / max * 100;
}
v = max / 255 * 100;
return [+h.toFixed(0), +s.toFixed(1), +v.toFixed(1), a];
...