import { Draggable } from './Draggable.js';
const RangeHTML = [
'
',
].join( '\n' );
document.querySelectorAll( 'range' ).forEach( el => {
const temp = document.createElement( 'div' );
temp.innerHTML = RangeHTML;
const range = temp.querySelector( '.range' );
const rangeLabel = range.querySelector( '.range__label' );
const rangeList = range.querySelector( '.range__list' );
range.setAttribute( 'name', el.getAttribute( 'name' ) );
rangeLabel.innerHTML = el.getAttribute( 'title' );
if ( el.hasAttribute( 'color' ) ) {
range.classList.add( 'range--type-color' );
range.classList.add( 'range--color-' + el.getAttribute( 'name' ) );
}
if ( el.hasAttribute( 'list' ) ) {
el.getAttribute( 'list' ).split( ',' ).forEach( listItemText => {
const listItem = document.createElement( 'div' );
listItem.innerHTML = listItemText;
rangeList.appendChild( listItem );
} );
}
el.parentNode.replaceChild( range, el );
} );
class Range {
constructor( name, options ) {
options = Object.assign( {
range: [ 0, 1 ],
value: 0,
step: 0,
onUpdate: () => {},
onComplete: () => {},
}, options || {} );
this.element = document.querySelector( '.range[name="' + name + '"]' );
this.track = this.element.querySelector( '.range__track' );
this.handle = this.element.querySelector( '.range__handle' );
this.list = [].slice.call( this.element.querySelectorAll( '.range__list div' ) );
this.value = options.value;
this.min = options.range[0];
this.max = options.range[1];
this.step = options.step;
this.onUpdate = options.onUpdate;
this.onComplete = options.onComplete;
this.setValue( this.value );
this.initDraggable();
}
setValue( value ) {
this.value = this.round( this.limitValue( value ) );
this.setHandlePosition();
}
initDraggable() {
const oldPosition = null;
let current;
this.draggable = new Draggable( this.handle, { calcDelta: true } );
this.draggable.onDragStart = position => {
current = this.positionFromValue( this.value );
this.handle.style.left = current + 'px';
}
this.draggable.onDragMove = position => {
current = this.limitPosition( current + position.delta.x );
this.value = this.round( this.valueFromPosition( current ) );
this.setHandlePosition();
this.onUpdate( this.value );
}
this.draggable.onDragEnd = position => {
this.onComplete( this.value );
}
}
round( value ) {
if ( this.step < 1 ) return value;
return Math.round( ( value - this.min ) / this.step ) * this.step + this.min;
}
limitValue( value ) {
const max = Math.max( this.max, this.min );
const min = Math.min( this.max, this.min );
return Math.min( Math.max( value, min ), max );
}
limitPosition( position ) {
return Math.min( Math.max( position, 0 ), this.track.offsetWidth );
}
percentsFromValue( value ) {
return ( value - this.min ) / ( this.max - this.min );
}
valueFromPosition( position ) {
return this.min + ( this.max - this.min ) * ( position / this.track.offsetWidth );
}
positionFromValue( value ) {
return this.percentsFromValue( value ) * this.track.offsetWidth;
}
setHandlePosition() {
this.handle.style.left = this.percentsFromValue( this.value ) * 100 + '%';
}
}
export { Range };