| 3 | import { EventEmitter, IEvent } from '../Events' |
| 4 | |
| 5 | export class ProgressBarView implements IComponent { |
| 6 | public readonly element: HTMLElement |
| 7 | |
| 8 | private _progressElement: HTMLElement |
| 9 | private _progressHover: HTMLElement |
| 10 | |
| 11 | private _onSeek: EventEmitter<number> = new EventEmitter<number>() |
| 12 | public get onSeek(): IEvent<number> { return this._onSeek.onEvent } |
| 13 | |
| 14 | private _progress: number = 0 |
| 15 | |
| 16 | constructor() { |
| 17 | const el = this.element = $div({ class: 'xp-progress-bar' }, |
| 18 | this._progressElement = $div({ class: 'xp-progress' }), |
| 19 | this._progressHover = $div({ class: 'xp-progress-hover', attrs: { style: 'opacity: 0' } }) |
| 20 | ) |
| 21 | |
| 22 | addDisposableDomListener(el, 'mousemove', this._updateProgressHover.bind(this)) |
| 23 | addDisposableDomListener(el, 'mouseenter', () => this._progressHover.style.opacity = '1') |
| 24 | addDisposableDomListener(el, 'mouseleave', () => this._progressHover.style.opacity = '0') |
| 25 | addDisposableDomListener(el, 'mousedown', (evt: MouseEvent) => { |
| 26 | this._onSeek.fire((evt.clientX - el.getBoundingClientRect().left) / el.clientWidth) |
| 27 | }) |
| 28 | |
| 29 | this._updateProgress() |
| 30 | } |
| 31 | |
| 32 | public get progress(): number { |
| 33 | return this._progress |
| 34 | } |
| 35 | public set progress(value: number) { |
| 36 | if (value !== this._progress) { |
| 37 | this._progress = Math.max(0.0, Math.min(value, 1.0)) |
| 38 | this._updateProgress() |
| 39 | } |
| 40 | } |
| 41 | |
| 42 | private _updateProgress() { |
| 43 | this._progressElement.style.width = (100 * this._progress) + '%' |
| 44 | } |
| 45 | private _updateProgressHover(evt: MouseEvent) { |
| 46 | const percent = (evt.clientX - this.element.getBoundingClientRect().left) / this.element.clientWidth |
| 47 | this._progressHover.style.width = (100 * percent) + '%' |
| 48 | } |
| 49 | } |
nothing calls this directly
no outgoing calls
no test coverage detected