Skip to content

Commit

Permalink
feat: compute value optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
andreruffert committed Oct 4, 2019
1 parent 91db9eb commit f3341dd
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 26 deletions.
10 changes: 8 additions & 2 deletions examples/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
</div>

<div>
<range-slider min="-20" max="0"></range-slider>
<range-slider min="-10" max="10"></range-slider>
</div>

<div>
Expand All @@ -39,6 +39,10 @@
<range-slider min="200" max="1000" step="100"></range-slider>
</div>

<div>
<input type="range">
</div>


<script src="../index.js"></script>
<script>
Expand All @@ -53,7 +57,9 @@
document.addEventListener('input', e => {
const input = e.target;
const output = input.nextElementSibling;
output.textContent = input.value;
if (output) {
output.textContent = input.value;
}
});

</script>
Expand Down
56 changes: 39 additions & 17 deletions range-slider-element.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as style from './styles.css';

const UPDATE_EVENTS = ['input', 'change'];
const REFLECTED_ATTRIBUTES = ['min', 'max', 'step', 'value', 'disabled'];
const REFLECTED_ATTRIBUTES = ['min', 'max', 'step', 'value', 'disabled', 'value-precision'];

class RangeSliderElement extends HTMLElement {
constructor() {
Expand All @@ -25,12 +25,14 @@ class RangeSliderElement extends HTMLElement {
get max() { return this.getAttribute('max') || '100'; }
get step() { return this.getAttribute('step') || '1'; }
get value() { return this.getAttribute('value') || this._defaultValue; }
get disabled() { return this.getAttribute('disabled') || false }
get valuePrecision() { return this.getAttribute('label-precision') || ''; }

set min(min) { this.setAttribute('min', min); }
set max(max) { this.setAttribute('max', max); }
set step(step) { this.setAttribute('step', step); }
set value(value) { this.setAttribute('value', value); }
set disabled(disabled) { this.setAttribute('disabled', disabled); }
set valuePrecision(precision) { this.setAttribute('label-precision', precision); }

connectedCallback() {
Expand Down Expand Up @@ -61,13 +63,16 @@ class RangeSliderElement extends HTMLElement {
}

_startHandler = e => {
this.classList.add('touch-active');

// Click and drag
this.setPointerCapture(e.pointerId);
this.addEventListener('pointermove', this._moveHandler, false);
this.classList.add('touch-active');

console.log(e);
if (e.target.matches('.thumb')) return;
this._reflectValue(e);
// Click jump
if (!e.target.matches('.thumb')) {
this._reflectValue(e);
}
}

_moveHandler = e => {
Expand All @@ -76,9 +81,9 @@ class RangeSliderElement extends HTMLElement {
}

_endHandler = e => {
this.classList.remove('touch-active');
this.releasePointerCapture(e.pointerId);
this.removeEventListener('pointermove', this._moveHandler, false);
this.classList.remove('touch-active');

// TODO: check if value changed
this.dispatchEvent(new Event('change', { bubbles: true }));
Expand All @@ -88,31 +93,48 @@ class RangeSliderElement extends HTMLElement {
const min = Number(this.min);
const max = Number(this.max);
const step = Number(this.step);
const oldValue = Number(this.value);
const oldValue = this.value;
const valuePrecision = Number(this.valuePrecision) || getPrescision(this.step) || 0;
const fullWidth = event.target.offsetWidth;
const offsetX = event.offsetX;
const stepInPixels = (max > 0) ? fullWidth / max : fullWidth / min;
const tmpValue = Math.min(Math.max(offsetX / stepInPixels, min), max);
const nearestValue = Math.ceil(tmpValue / step) * step; // Rounding in steps
const newValue = valuePrecision
? nearestValue.toFixed(valuePrecision)
: Math.round(nearestValue).toString()
;
const offsetX = Math.min(Math.max(event.offsetX, 0), fullWidth);
const percentComplete = offsetX / fullWidth;

// TODO: RTL support
// if (this.adapter_.isRTL()) {
// percentComplete = 1 - percentComplete;
// }

console.log({ fullWidth, offsetX, stepInPixels, oldValue, newValue});
// Fit the percentage complete between the range [min,max]
// by remapping from [0, 1] to [min, min+(max-min)].
const computedValue = min + percentComplete * (max - min);

// Rounding in steps
const nearestValue = Math.round(computedValue / step) * step;

// Value precision
const newValue = valuePrecision ? nearestValue.toFixed(valuePrecision) : Math.round(nearestValue).toString();

console.log({ fullWidth, offsetX, oldValue, computedValue, newValue});

if (oldValue !== newValue) {
this.value = newValue;
this.dispatchEvent(new Event('input', { bubbles: true }));
}
}

_stepUp(amount = this.step) {
this.value += amount;
}

_stepDown(amount = this.step) {
this.value -= amount;
}

_update() {
const min = Number(this.min);
const max = Number(this.max);
const value = Number(this.value);
const percent = (max > 0) ? (100 * (value - min)) / (max - min) : (100 * (value - max)) / (min - max);
const percent = (100 * (value - min)) / (max - min);

if (this._valueDisplay) {
this._valueDisplay.textContent = value;
Expand Down
14 changes: 7 additions & 7 deletions styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ range-slider {
position: relative;
display: flex;
height: 24px;
width: 130px;
width: 100%;
min-width: 130px;
margin: 2px;
overflow: visible;

Expand All @@ -16,27 +17,26 @@ range-slider[disabled] {
}

range-slider::before {
--height: 3px;
--height: 5px;

content: "";
display: block;
position: absolute;
top: calc(50% - var(--height) / 2);
left: 0;
width: 100%;
height: 3px;
height: var(--height);
border-radius: 1px;
box-shadow: 0 -.5px 0 rgba(0,0,0,0.3), inset 0 .5px 0 rgba(255,255,255,0.2), 0 .5px 0 rgba(255,255,255,0.3);
background: linear-gradient(#FF0080, #FF0080) 0/ var(--value-percent, 0%) 100% no-repeat #eee;
/* box-shadow: 0 -.5px 0 rgba(0,0,0,0.3), inset 0 .5px 0 rgba(255,255,255,0.2), 0 .5px 0 rgba(255,255,255,0.3); */
background: linear-gradient(#6221ea, #6221ea) 0/ var(--value-percent, 0%) 100% no-repeat #c6afe5;
}

.thumb {
pointer-events: none;
position: absolute;
bottom: 6px;
left: var(--value-percent, 0%);
margin-left: -6px;
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10"><circle cx="5" cy="5" r="1" fill="currentColor" /></svg>') center no-repeat #FF0080;
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10"><circle cx="5" cy="5" r="1" fill="currentColor" /></svg>') center no-repeat #6221ea;
border-radius: 50%;
width: 12px;
height: 12px;
Expand Down

0 comments on commit f3341dd

Please sign in to comment.