Skip to content

Commit

Permalink
fix: createVideoContext
Browse files Browse the repository at this point in the history
  • Loading branch information
helsonxiao committed Oct 16, 2020
1 parent 262b4dd commit 7be9696
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 34 deletions.
6 changes: 6 additions & 0 deletions packages/taro-components/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ export namespace Components {
* 是否开启控制进度的手势
*/
'enableProgressGesture': boolean;
'exitFullScreen': () => Promise<void>;
/**
* 指定视频初始播放位置
*/
Expand All @@ -314,10 +315,14 @@ export namespace Components {
* 当视频大小与 video 容器大小不一致时,视频的表现形式
*/
'objectFit': 'contain' | 'fill' | 'cover';
'pause': () => Promise<void>;
'play': () => Promise<void>;
/**
* 视频封面的图片网络资源地址或云文件ID(2.3.0)。若 controls 属性值为 false 则设置 poster 无效
*/
'poster': string;
'requestFullScreen': () => Promise<void>;
'seek': (position: number) => Promise<void>;
/**
* 是否显示视频中间的播放按钮
*/
Expand All @@ -339,6 +344,7 @@ export namespace Components {
* 要播放视频的资源地址
*/
'src': string;
'stop': () => Promise<void>;
/**
* 在非全屏模式下,是否开启亮度与音量调节手势
*/
Expand Down
153 changes: 125 additions & 28 deletions packages/taro-components/src/components/video/video.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { Component, h, ComponentInterface, Prop, State, Event, EventEmitter, Host, Watch, Listen, Element } from '@stencil/core'
import { Component, h, ComponentInterface, Prop, State, Event, EventEmitter, Host, Watch, Listen, Element, Method } from '@stencil/core'
import classNames from 'classnames'
import {
formatTime,
Expand All @@ -8,6 +8,75 @@ import {
throttle
} from './utils'

/**
* @returns: {requestFullscreen: 'requestFullscreen', exitFullscreen: 'exitFullscreen', ...}
*/
const screenFn: {[key: string]: any} = (function () {
let val
const fnMap = [
[
'requestFullscreen',
'exitFullscreen',
'fullscreenElement',
'fullscreenEnabled',
'fullscreenchange',
'fullscreenerror'
],
// New WebKit
[
'webkitRequestFullscreen',
'webkitExitFullscreen',
'webkitFullscreenElement',
'webkitFullscreenEnabled',
'webkitfullscreenchange',
'webkitfullscreenerror'

],
// Old WebKit
[
'webkitRequestFullScreen',
'webkitCancelFullScreen',
'webkitCurrentFullScreenElement',
'webkitCancelFullScreen',
'webkitfullscreenchange',
'webkitfullscreenerror'
],
[
'mozRequestFullScreen',
'mozCancelFullScreen',
'mozFullScreenElement',
'mozFullScreenEnabled',
'mozfullscreenchange',
'mozfullscreenerror'
],
[
'msRequestFullscreen',
'msExitFullscreen',
'msFullscreenElement',
'msFullscreenEnabled',
'MSFullscreenChange',
'MSFullscreenError'
]
]

let i = 0
const l = fnMap.length
const ret = {}
// This for loop essentially checks the current document object for the property/methods above.
for (; i < l; i++) {
val = fnMap[i]
if (val && val[1] in document) {
for (i = 0; i < val.length; i++) {
ret[fnMap[0][i]] = val[i]
}
return ret
}
}
// If it doesn't find any of them, this whole function returns false
// and the fn variable is set to this returned value.
return ret
})()

@Component({
tag: 'taro-video-core',
styleUrl: './style/index.scss'
Expand Down Expand Up @@ -380,23 +449,40 @@ export class Video implements ComponentInterface {
})
}

play = () => {
@Method()
async play () {
this.videoRef.play()
}

pause = () => {
@Method()
async pause () {
this.videoRef.pause()
}

stop = () => {
@Method()
async stop () {
this.videoRef.pause()
this.seek(0)
}

seek = (position: number) => {
@Method()
async seek (position: number) {
this.videoRef.currentTime = position
}

@Method()
async requestFullScreen () {
this.toggleFullScreen(true)
}

@Method()
async exitFullScreen () {
if (document[screenFn.fullscreenElement]) {
document[screenFn.exitFullScreen]()
}
this.toggleFullScreen(false)
}

onTouchStartContainer = (e: TouchEvent) => {
this.lastTouchScreenX = e.touches[0].screenX
this.lastTouchScreenY = e.touches[0].screenY
Expand All @@ -419,12 +505,23 @@ export class Video implements ComponentInterface {
this.toggleFullScreen()
}

// 全屏后,"点击按钮退出"走的是浏览器事件,在此同步状态
@Listen('fullscreenchange')
onNativeFullScreenExit (e: any) {
// 在接到下面的定制事件以及处于全屏状态时不处理
if (e.detail || document[screenFn.fullscreenElement]) return
this.toggleFullScreen(false)
}

toggleFullScreen = (nextFullScreenState?) => {
const isFullScreen = nextFullScreenState === undefined ? !this.isFullScreen : nextFullScreenState
this.isFullScreen = isFullScreen
const nextState = nextFullScreenState === undefined ? !this.isFullScreen : nextFullScreenState
if (nextState) {
this.videoRef[screenFn.requestFullscreen]()
}
this.isFullScreen = nextState
this.controlsRef.toggleVisibility(true)
this.onFullScreenChange.emit({
fullScreen: isFullScreen,
fullScreen: this.isFullScreen,
direction: 'vertical'
})
}
Expand Down Expand Up @@ -474,13 +571,13 @@ export class Video implements ComponentInterface {
onClick={this.onClickContainer}
>
<video
class='taro-video-video'
className='taro-video-video'
style={{
'object-fit': objectFit
}}
ref={dom => (this.videoRef = dom as HTMLVideoElement)}
src={src}
autoplay={autoplay}
autoPlay={autoplay}
loop={loop}
muted={muted}
poster={controls ? poster : undefined}
Expand Down Expand Up @@ -508,23 +605,23 @@ export class Video implements ComponentInterface {
currentTime={this.currentTime}
duration={this.duration || this._duration || undefined}
isPlaying={this.isPlaying}
pauseFunc={this.pause}
playFunc={this.play}
seekFunc={this.seek}
pauseFunc={() => this.pause()}
playFunc={() => this.play()}
seekFunc={pos => this.seek(pos)}
showPlayBtn={this.showPlayBtn}
showProgress={this.showProgress}
>
{showMuteBtn && (
<div
class={classNames('taro-video-mute', {
className={classNames('taro-video-mute', {
'taro-video-type-mute': isMute
})}
onClick={this.toggleMute}
/>
)}
{danmuBtn && (
<div
class={classNames('taro-video-danmu-button', {
className={classNames('taro-video-danmu-button', {
'taro-video-danmu-button-active': _enableDanmu
})}
onClick={this.toggleDanmu}>
Expand All @@ -533,7 +630,7 @@ export class Video implements ComponentInterface {
)}
{showFullscreenBtn && (
<div
class={classNames('taro-video-fullscreen', {
className={classNames('taro-video-fullscreen', {
'taro-video-type-fullscreen': isFullScreen
})}
onClick={this.onClickFullScreenBtn}
Expand All @@ -551,40 +648,40 @@ export class Video implements ComponentInterface {
/>

{isFirst && showCenterPlayBtn && !isPlaying && (
<div class='taro-video-cover'>
<div class='taro-video-cover-play-button' onClick={this.play} />
<p class='taro-video-cover-duration'>{durationTime}</p>
<div className='taro-video-cover'>
<div className='taro-video-cover-play-button' onClick={() => this.play()} />
<p className='taro-video-cover-duration'>{durationTime}</p>
</div>
)}

<div class='taro-video-toast taro-video-toast-volume' ref={dom => {
<div className='taro-video-toast taro-video-toast-volume' ref={dom => {
if (dom) {
this.toastVolumeRef = dom
}
}}>
<div class='taro-video-toast-title'>音量</div>
<div class='taro-video-toast-icon' />
<div class='taro-video-toast-value'>
<div class='taro-video-toast-value-content' ref={dom => {
<div className='taro-video-toast-title'>音量</div>
<div className='taro-video-toast-icon' />
<div className='taro-video-toast-value'>
<div className='taro-video-toast-value-content' ref={dom => {
if (dom) {
this.toastVolumeBarRef = dom
}
}}>
<div class='taro-video-toast-volume-grids'>
<div className='taro-video-toast-volume-grids'>
{Array(10).fill(1).map(() => (
<div class='taro-video-toast-volume-grids-item' />
<div className='taro-video-toast-volume-grids-item' />
))}
</div>
</div>
</div>
</div>

<div class='taro-video-toast taro-video-toast-progress' ref={dom => {
<div className='taro-video-toast taro-video-toast-progress' ref={dom => {
if (dom) {
this.toastProgressRef = dom
}
}}>
<div class='taro-video-toast-title' ref={dom => {
<div className='taro-video-toast-title' ref={dom => {
if (dom) {
this.toastProgressTitleRef = dom
}
Expand Down
6 changes: 6 additions & 0 deletions packages/taro-components/types/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ export namespace Components {
* 是否开启控制进度的手势
*/
'enableProgressGesture': boolean;
'exitFullScreen': () => Promise<void>;
/**
* 指定视频初始播放位置
*/
Expand All @@ -314,10 +315,14 @@ export namespace Components {
* 当视频大小与 video 容器大小不一致时,视频的表现形式
*/
'objectFit': 'contain' | 'fill' | 'cover';
'pause': () => Promise<void>;
'play': () => Promise<void>;
/**
* 视频封面的图片网络资源地址或云文件ID(2.3.0)。若 controls 属性值为 false 则设置 poster 无效
*/
'poster': string;
'requestFullScreen': () => Promise<void>;
'seek': (position: number) => Promise<void>;
/**
* 是否显示视频中间的播放按钮
*/
Expand All @@ -339,6 +344,7 @@ export namespace Components {
* 要播放视频的资源地址
*/
'src': string;
'stop': () => Promise<void>;
/**
* 在非全屏模式下,是否开启亮度与音量调节手势
*/
Expand Down
6 changes: 3 additions & 3 deletions packages/taro-h5/src/api/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,9 +241,9 @@ function processOpenapi (apiName, defaultOptions, formatResult = res => res, for
}
}

const findRef = (refId, componentInstance) => {
if (componentInstance.isRoute) return
return componentInstance[refId] || findRef(refId, componentInstance.vnode._owner)
const findRef = (refId) => {
const element = document.getElementById(refId)
return element
}

/**
Expand Down
5 changes: 2 additions & 3 deletions packages/taro-h5/src/api/video/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ export function chooseVideo (options) {
* @param {string} id <video> 组件的 id
* @param {object} componentInstance 在自定义组件下,当前组件实例的this,以操作组件内 <video> 组件
*/
export function createVideoContext (id, componentInstance) {
const refId = `__taroref_${id}`
return findRef(refId, componentInstance)
export function createVideoContext (id, _componentInstance) {
return findRef(id)
}

0 comments on commit 7be9696

Please sign in to comment.