import {SliderMarks} from './components/AbstractSlider'; /** * No operation. */ function noop( ..._rest: any[] ): void { // No operation } /** * Clamp value to the range. */ function clampValue( value: number, {min, max}: {min: number, max: number}, ): number { if ( value <= min ) { return min; } if ( value >= max ) { return max; } return value; } /** * Is value out of range? */ function isValueOutOfRange( value: number, {min, max}: {min: number, max: number}, ): boolean { return ( ( value < min ) || ( value > max ) ); } /** * Get precision from step. */ function getPrecision( step: number ): number { const stepString = step.toString(); const dotIndex = stepString.indexOf( '.' ); let precision = 0; if ( dotIndex !== -1 ) { precision = stepString.length - dotIndex - 1; } return precision; } export function clampValueToSurroundingHandles( value: number, {allowCross}: {allowCross: boolean}, {handle, bounds}: {handle: number | null, bounds: number[]}, ): number { if ( !allowCross && ( handle != null ) ) { if ( ( handle > 0 ) && ( value <= bounds[handle - 1] ) ) { return bounds[handle - 1]; } if ( ( handle < (bounds.length - 1) ) && ( value >= bounds[handle + 1] ) ) { return bounds[handle + 1]; } } return value; } /** * Properties required to align value. */ export interface AlignValueProps { marks: SliderMarks; step: number; min: number; } /** * Get point on slider closest to value. */ function getClosestPoint( value: number, {marks, step, min}: AlignValueProps, ): number { const points = Object.keys( marks ).map( Number ); if ( ( step != null ) && ( step > 0 ) ) { const closestStep = Math.round( (value - min) / step) * step + min; points.push( closestStep ); } const diffs = points.map( ( point ) => Math.abs( value - point ), ); return ( points[diffs.indexOf( Math.min( ...diffs ) )] || min ); } /** * Align value to available values using step and marks. */ function alignValue( value: number, props: AlignValueProps, ): number { const {step} = props; const closestPoint = getClosestPoint( value, props ); return ( ( // If step is less or equal 0, value is taken from marks and should // not be rounded. ( step == null ) || ( step <= 0 ) ) ? closestPoint : Number( closestPoint.toFixed( getPrecision( step ) ), ) ); } /** * Get center position of handle element. */ function getHandleCenterPosition( vertical: boolean, handle: Element ): number { const coords = handle.getBoundingClientRect(); return ( vertical ? coords.top + ( coords.height / 2 ) : coords.left + ( coords.width / 2 ) ); } /** * Get mouse position. */ function getMousePosition( vertical: boolean, event: MouseEvent ): number { return ( vertical ? event.clientY : event.pageX ); } /** * Get touch position. */ function getTouchPosition( vertical: boolean, event: TouchEvent ): number { return ( vertical ? event.touches[0].clientY : event.touches[0].pageX ); } /** * Is event from handle? */ function isEventFromHandle( event: Event, handles: Element[] ): boolean { return ( handles.some( ( handle ) => event.target === handle, ) ); } /** * Is touch event is not correct to move handle? */ function isNotCorrectTouchEvent( event: TouchEvent ): boolean { return ( ( event.touches.length > 1 ) || ( ( event.type.toLowerCase() === 'touchend' ) && ( event.touches.length > 0 ) ) ); } /** * Prevent and stop event. */ function killEvent( event: Event ): void { event.stopPropagation(); event.preventDefault(); } /** * Module. */ export { noop, clampValue, isValueOutOfRange, alignValue, getHandleCenterPosition, getMousePosition, getTouchPosition, isEventFromHandle, isNotCorrectTouchEvent, killEvent, // AlignValueProps, }; const ONEHOUR = 3600; export const zeroPad = (num: number) => num >= 100 ? `${Math.floor(num)}` : `00${Math.floor(num)}`.slice(-2); export const formatTime = (seconds: number) => { if (isNaN(seconds) || seconds === Infinity) { return ''; } if (seconds > 604800) { const date = new Date(seconds * 1000); return ( zeroPad(date.getHours()) + ':' + zeroPad(date.getMinutes()) + ':' + zeroPad(date.getSeconds()) ); } let sign = ''; if (seconds < 0) { seconds = Math.abs(seconds); sign = '-'; } if (seconds < ONEHOUR) { return sign + zeroPad(seconds / 60) + ':' + zeroPad(seconds % 60); } const formatted = Math.floor(seconds / ONEHOUR) + ':' + zeroPad((seconds % ONEHOUR) / 60) + ':' + zeroPad(seconds % 60); return `${sign}${formatted}`; };