UNPKG

@tarojs/components

Version:

Taro 组件库

355 lines (354 loc) • 9.98 kB
import { h, Host } from '@stencil/core'; import { formatTime } from './utils'; export class VideoControl { constructor() { this.visible = false; this.isDraggingProgressBall = false; this.percentage = 0; this.progressDimensions = { left: 0, width: 0 }; this.calcPercentage = (pageX) => { let pos = pageX - this.progressDimensions.left; pos = Math.max(pos, 0); pos = Math.min(pos, this.progressDimensions.width); return pos / this.progressDimensions.width; }; this.onDragProgressBallStart = () => { this.isDraggingProgressBall = true; this.hideControlsTimer && clearTimeout(this.hideControlsTimer); }; this.onClickProgress = (e) => { e.stopPropagation(); const percentage = this.calcPercentage(e.pageX); this.seekFunc(percentage * this.duration); this.toggleVisibility(true); }; this.controls = undefined; this.currentTime = undefined; this.duration = undefined; this.isPlaying = undefined; this.pauseFunc = undefined; this.playFunc = undefined; this.seekFunc = undefined; this.showPlayBtn = undefined; this.showProgress = undefined; } onDocumentTouchMove(e) { if (!this.isDraggingProgressBall) return; const touchX = e.touches[0].pageX; this.percentage = this.calcPercentage(touchX); this.setProgressBall(this.percentage); this.setCurrentTime(this.percentage * this.duration); } onDocumentTouchEnd() { if (!this.isDraggingProgressBall) return; this.isDraggingProgressBall = false; this.seekFunc(this.percentage * this.duration); this.toggleVisibility(true); } async setProgressBall(percentage) { if (this.progressBallRef) { this.progressBallRef.style.left = `${percentage * 100}%`; } } async toggleVisibility(nextVisible) { const visible = nextVisible === undefined ? !this.visible : nextVisible; if (visible) { this.hideControlsTimer && clearTimeout(this.hideControlsTimer); if (this.isPlaying) { this.hideControlsTimer = setTimeout(() => { this.toggleVisibility(false); }, 2000); } this.el.style.visibility = 'visible'; } else { this.el.style.visibility = 'hidden'; } this.visible = !!visible; } async getIsDraggingProgressBall() { return this.isDraggingProgressBall; } async setCurrentTime(time) { this.currentTimeRef.innerHTML = formatTime(time); } render() { const { controls, currentTime, duration, isPlaying, pauseFunc, playFunc, showPlayBtn, showProgress } = this; const formattedDuration = formatTime(duration); let playBtn; if (!showPlayBtn) { playBtn = null; } else if (isPlaying) { playBtn = h("div", { class: 'taro-video-control-button taro-video-control-button-pause', onClick: pauseFunc }); } else { playBtn = h("div", { class: 'taro-video-control-button taro-video-control-button-play', onClick: playFunc }); } return (h(Host, { class: 'taro-video-bar taro-video-bar-full' }, controls && (h("div", { class: 'taro-video-controls' }, playBtn, showProgress && (h("div", { class: 'taro-video-current-time', ref: dom => (this.currentTimeRef = dom) }, formatTime(currentTime))), showProgress && (h("div", { class: 'taro-video-progress-container', onClick: this.onClickProgress }, h("div", { class: 'taro-video-progress', ref: ref => { if (!ref) return; const rect = ref.getBoundingClientRect(); this.progressDimensions.left = rect.left; this.progressDimensions.width = rect.width; } }, h("div", { class: 'taro-video-progress-buffered', style: { width: '100%' } }), h("div", { class: 'taro-video-ball', ref: dom => (this.progressBallRef = dom), onTouchStart: this.onDragProgressBallStart, style: { left: `${formattedDuration ? (this.currentTime / duration) * 100 : 0}%` } }, h("div", { class: 'taro-video-inner' }))))), showProgress && h("div", { class: 'taro-video-duration' }, formattedDuration))), h("slot", null))); } static get is() { return "taro-video-control"; } static get properties() { return { "controls": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "" }, "attribute": "controls", "reflect": false }, "currentTime": { "type": "number", "mutable": false, "complexType": { "original": "number", "resolved": "number", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "" }, "attribute": "current-time", "reflect": false }, "duration": { "type": "number", "mutable": false, "complexType": { "original": "number", "resolved": "number", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "" }, "attribute": "duration", "reflect": false }, "isPlaying": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "" }, "attribute": "is-playing", "reflect": false }, "pauseFunc": { "type": "unknown", "mutable": false, "complexType": { "original": "() => void", "resolved": "() => void", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "" } }, "playFunc": { "type": "unknown", "mutable": false, "complexType": { "original": "() => void", "resolved": "() => void", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "" } }, "seekFunc": { "type": "unknown", "mutable": false, "complexType": { "original": "(position: number) => void", "resolved": "(position: number) => void", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "" } }, "showPlayBtn": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "" }, "attribute": "show-play-btn", "reflect": false }, "showProgress": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "" }, "attribute": "show-progress", "reflect": false } }; } static get methods() { return { "setProgressBall": { "complexType": { "signature": "(percentage: number) => Promise<void>", "parameters": [{ "tags": [], "text": "" }], "references": { "Promise": { "location": "global" } }, "return": "Promise<void>" }, "docs": { "text": "", "tags": [] } }, "toggleVisibility": { "complexType": { "signature": "(nextVisible?: boolean) => Promise<void>", "parameters": [{ "tags": [], "text": "" }], "references": { "Promise": { "location": "global" } }, "return": "Promise<void>" }, "docs": { "text": "", "tags": [] } }, "getIsDraggingProgressBall": { "complexType": { "signature": "() => Promise<boolean>", "parameters": [], "references": { "Promise": { "location": "global" } }, "return": "Promise<boolean>" }, "docs": { "text": "", "tags": [] } }, "setCurrentTime": { "complexType": { "signature": "(time: number) => Promise<void>", "parameters": [{ "tags": [], "text": "" }], "references": { "Promise": { "location": "global" } }, "return": "Promise<void>" }, "docs": { "text": "", "tags": [] } } }; } static get elementRef() { return "el"; } static get listeners() { return [{ "name": "touchmove", "method": "onDocumentTouchMove", "target": "document", "capture": false, "passive": true }, { "name": "touchend", "method": "onDocumentTouchEnd", "target": "document", "capture": false, "passive": true }, { "name": "touchcancel", "method": "onDocumentTouchEnd", "target": "document", "capture": false, "passive": true }]; } }