complete the development of common functions

master
lgf 3 years ago
parent d421bb6559
commit 285992f38d
  1. 2
      src/appComponent.tsx
  2. 1
      src/components/end/index.module.scss
  3. 11
      src/components/end/index.tsx
  4. 1
      src/components/screenshot/index.module.scss
  5. 22
      src/components/screenshot/index.tsx
  6. 2
      src/core/config/index.ts
  7. 12
      src/core/controller/index.tsx
  8. 58
      src/core/controls/index.tsx
  9. 3
      src/core/controls/multiple.tsx
  10. 12
      src/core/controls/set.tsx
  11. 3
      src/core/controls/volume.tsx
  12. 11
      src/core/index.tsx
  13. 2
      src/core/progress/index.tsx
  14. 6
      src/interface/index.ts
  15. 53
      src/language/index.ts
  16. 10
      src/utils/index.ts

@ -79,8 +79,8 @@ const AppComponent = memo(function AppComponent(props) {
width: 750, width: 750,
height: 420, height: 420,
theme: '#00D3FF', theme: '#00D3FF',
isShowMultiple: false,
poster: 'https://cdn.gudsen.com/2021/06/28/f81356b08b4842d7a3719499f557c8e4.JPG', poster: 'https://cdn.gudsen.com/2021/06/28/f81356b08b4842d7a3719499f557c8e4.JPG',
language: 'en',
}} }}
onProgressMouseDown={onProgressMouseDown} onProgressMouseDown={onProgressMouseDown}
onPlay={onPlay} onPlay={onPlay}

@ -2,6 +2,7 @@
.end { .end {
@include position(absolute, 0, 0, 0, 0); @include position(absolute, 0, 0, 0, 0);
z-index: 1300; z-index: 1300;
cursor: default;
background: rgba($color: #000000, $alpha: 0.4); background: rgba($color: #000000, $alpha: 0.4);
.replay { .replay {
@include position(absolute, 50%, 0, 0, 50%); @include position(absolute, 50%, 0, 0, 50%);

@ -1,8 +1,13 @@
import React, { memo, FC } from 'react'; import React, { memo, FC } from 'react';
import style from './index.module.scss'; import style from './index.module.scss';
import Broadcast from '@/components/svgIcon'; import Broadcast from '@/components/svgIcon';
import { languageType } from '@/interface';
const Index: FC<{ handle: Function }> = memo(function Index({ handle }) { import { il8n } from '@/language';
import { defaultLanguage } from '@/core/config';
const Index: FC<{ handle: Function; language: languageType | undefined }> = memo(function Index({
handle,
language,
}) {
const handleFunc = () => { const handleFunc = () => {
handle(); handle();
}; };
@ -12,7 +17,7 @@ const Index: FC<{ handle: Function }> = memo(function Index({ handle }) {
<div className={style.cicle} onClick={handleFunc}> <div className={style.cicle} onClick={handleFunc}>
<Broadcast iconClass="replay" fill="#fff" fontSize={'37px'} /> <Broadcast iconClass="replay" fill="#fff" fontSize={'37px'} />
</div> </div>
<p></p> <p>{il8n(language || defaultLanguage, 'replay')}</p>
</div> </div>
</div> </div>
); );

@ -32,5 +32,6 @@
.save { .save {
padding: 10px; padding: 10px;
text-align: center; text-align: center;
font-size: 13px;
} }
} }

@ -1,20 +1,34 @@
import React, { memo, FC } from 'react'; import React, { memo, FC } from 'react';
import style from './index.module.scss'; import style from './index.module.scss';
import Broadcast from '@/components/svgIcon'; import Broadcast from '@/components/svgIcon';
import { languageType } from '@/interface';
import { defaultTheme, defaultLanguage } from '@/core/config';
import { il8n } from '@/language';
const Index: FC<{ const Index: FC<{
setIsscreenshot: Function; setIsscreenshot: Function;
screenshotLoading: boolean; screenshotLoading: boolean;
}> = memo(function Index({ setIsscreenshot, screenshotLoading }) { theme: string | undefined;
language: languageType | undefined;
}> = memo(function Index({ setIsscreenshot, screenshotLoading, theme, language }) {
return ( return (
<div className={style.screenshot}> <div className={style.screenshot}>
<div className={style.close} onClick={() => setIsscreenshot(false)}> <div className={style.close} onClick={() => setIsscreenshot(false)}>
<Broadcast iconClass="close" fill="red" className={style.icon} /> <Broadcast iconClass="close" fill={theme || defaultTheme} className={style.icon} />
</div> </div>
<div className={style.img} id="JoL-screenshotCanvas"> <div className={style.img} id="JoL-screenshotCanvas">
<Broadcast iconClass="loading" className="player-loading" fontSize="55px" /> <Broadcast
iconClass="loading"
fill={theme || defaultTheme}
className="player-loading"
fontSize="55px"
/>
</div> </div>
<p className={style.save}> <p className={style.save}>
{screenshotLoading ? '截图加载失败,在点击下' : '鼠标右键图片另存为'} {il8n(
language || defaultLanguage,
screenshotLoading ? 'screenshotsFailText' : 'screenshotsSucessText',
)}
</p> </p>
</div> </div>
); );

@ -10,3 +10,5 @@ export const multipleList = [
export const defaultTheme: string = 'blue'; export const defaultTheme: string = 'blue';
export const defaultVolume: number = 60; export const defaultVolume: number = 60;
export const defaultLanguage = 'zh';

@ -141,7 +141,12 @@ const Index = memo(function Index() {
onMouseLeave={(e) => [controlsContainerMove('leave')]} onMouseLeave={(e) => [controlsContainerMove('leave')]}
> >
{isScreenshot ? ( {isScreenshot ? (
<Screenshot setIsscreenshot={setIsscreenshot} screenshotLoading={screenshotLoading} /> <Screenshot
setIsscreenshot={setIsscreenshot}
screenshotLoading={screenshotLoading}
theme={propsAttributes!.theme}
language={propsAttributes!.language}
/>
) : null} ) : null}
<Progress /> <Progress />
<Controls setIsscreenshot={setIsscreenshot} setScreenshotLoading={setScreenshotLoading} /> <Controls setIsscreenshot={setIsscreenshot} setScreenshotLoading={setScreenshotLoading} />
@ -150,7 +155,10 @@ const Index = memo(function Index() {
propsAttributes!.setEndPlayContent ? ( propsAttributes!.setEndPlayContent ? (
propsAttributes!.setEndPlayContent propsAttributes!.setEndPlayContent
) : ( ) : (
<EndComponent handle={() => [handleChangePlayState(), showControl('enter')]} /> <EndComponent
handle={() => [handleChangePlayState(), showControl('enter')]}
language={propsAttributes!.language}
/>
) )
) : null} ) : null}
</div> </div>

@ -3,15 +3,16 @@ import Broadcast from '@/components/svgIcon';
import Tooltip from '@/components/tooltip'; import Tooltip from '@/components/tooltip';
import { contextType, FlowContext } from '@/core/context'; import { contextType, FlowContext } from '@/core/context';
import { useVideo } from '@/core/useVideo'; import { useVideo } from '@/core/useVideo';
import { secondsToMinutesAndSecondes, capture } from '@/utils'; import { secondsToMinutesAndSecondes, capture, filterDefaults } from '@/utils';
import { useControls } from './variable'; import { useControls } from './variable';
import useWindowClient from '@/utils/useWindowClient'; import useWindowClient from '@/utils/useWindowClient';
import screenfull, { Screenfull } from 'screenfull'; import screenfull, { Screenfull } from 'screenfull';
import { multipleList, defaultVolume } from '@/core/config'; import { multipleList, defaultVolume, defaultLanguage } from '@/core/config';
import SetComponent from './set'; import SetComponent from './set';
import MultipleComponent from './multiple'; import MultipleComponent from './multiple';
import VolumeComponent from './volume'; import VolumeComponent from './volume';
import MonitorComponent from './monitor'; import MonitorComponent from './monitor';
import { il8n } from '@/language';
import './index.scss'; import './index.scss';
const Index: FC<{ setIsscreenshot: Function; setScreenshotLoading: Function }> = memo( const Index: FC<{ setIsscreenshot: Function; setScreenshotLoading: Function }> = memo(
@ -162,7 +163,7 @@ const Index: FC<{ setIsscreenshot: Function; setScreenshotLoading: Function }> =
}; };
const multipleText = useMemo(() => { const multipleText = useMemo(() => {
if (controlsState.multiple === 1.0) { if (controlsState.multiple === 1.0) {
return '倍数'; return il8n(propsAttributes!.language || defaultLanguage, 'multiple');
} else { } else {
return multipleList.filter((item) => item.id === controlsState.multiple)[0].name; return multipleList.filter((item) => item.id === controlsState.multiple)[0].name;
} }
@ -217,11 +218,17 @@ const Index: FC<{ setIsscreenshot: Function; setScreenshotLoading: Function }> =
dispatch({ type: 'isMuted', data: controlsState.isMuted ? false : true }); dispatch({ type: 'isMuted', data: controlsState.isMuted ? false : true });
reviceProps.videoRef!.muted = controlsState.isMuted ? false : true; reviceProps.videoRef!.muted = controlsState.isMuted ? false : true;
}; };
/**
* @description
*/
const space = useMemo(() => {
return controlsState.isScreentFull || controlsState.isWebPageFullScreen ? '13px' : '8px';
}, [controlsState.isWebPageFullScreen, controlsState.isScreentFull]);
return ( return (
<div <div
className="JoL-controls-container" className="JoL-controls-container"
// style={{ opacity: reviceProps.videoFlow!.isControl ? '1' : '0' }} style={{ opacity: reviceProps.videoFlow!.isControl ? '1' : '0' }}
> >
<MonitorComponent <MonitorComponent
isPlay={isPlay} isPlay={isPlay}
@ -230,15 +237,17 @@ const Index: FC<{ setIsscreenshot: Function; setScreenshotLoading: Function }> =
totalTime={secondsToMinutesAndSecondes(duration)} totalTime={secondsToMinutesAndSecondes(duration)}
/> />
<div className="JoL-multifunction"> <div className="JoL-multifunction">
{propsAttributes!.isShowMultiple && ( {filterDefaults(propsAttributes!.isShowMultiple) && (
<MultipleComponent <MultipleComponent
multipleText={multipleText} multipleText={multipleText}
multiple={controlsState.multiple} multiple={controlsState.multiple}
selectPlayRate={selectPlayRate} selectPlayRate={selectPlayRate}
/> />
)} )}
<VolumeComponent <VolumeComponent
style={{
padding: `0 ${space}`,
}}
ref={volumeSliderMirror} ref={volumeSliderMirror}
volume={controlsState.volume} volume={controlsState.volume}
changeCurrentVolume={changeCurrentVolume} changeCurrentVolume={changeCurrentVolume}
@ -247,10 +256,18 @@ const Index: FC<{ setIsscreenshot: Function; setScreenshotLoading: Function }> =
isMuted={controlsState.isMuted} isMuted={controlsState.isMuted}
toggleVolume={toggleVolume} toggleVolume={toggleVolume}
/> />
<SetComponent switchChange={switchChange} /> {filterDefaults(propsAttributes!.isShowSet) && (
<SetComponent
switchChange={switchChange}
style={{
padding: `0 ${space}`,
}}
/>
)}
{filterDefaults(propsAttributes!.isShowScreenshot) && (
<Tooltip <Tooltip
styleCss={{ padding: '0 5px' }} styleCss={{ padding: `0 ${space}` }}
title="截图" title={il8n(propsAttributes!.language || defaultLanguage, 'screenshots')}
icon={ icon={
<Broadcast <Broadcast
iconClass="screenshot" iconClass="screenshot"
@ -260,9 +277,14 @@ const Index: FC<{ setIsscreenshot: Function; setScreenshotLoading: Function }> =
/> />
} }
/> />
)}
{filterDefaults(propsAttributes!.isShowPicture) && (
<Tooltip <Tooltip
styleCss={{ padding: '0 5px' }} styleCss={{ padding: `0 ${space}` }}
title={isPictureinpicture ? '关闭画中画' : '开启画中画'} title={il8n(
propsAttributes!.language || defaultLanguage,
isPictureinpicture ? 'closePicture' : 'openPicture',
)}
icon={ icon={
<Broadcast <Broadcast
iconClass="fullScreen" iconClass="fullScreen"
@ -273,9 +295,11 @@ const Index: FC<{ setIsscreenshot: Function; setScreenshotLoading: Function }> =
/> />
} }
/> />
)}
{filterDefaults(propsAttributes!.isShowWebFullScreen) && (
<Tooltip <Tooltip
styleCss={{ padding: '0 5px' }} styleCss={{ padding: `0 ${space}` }}
title="网页全屏" title={il8n(propsAttributes!.language || defaultLanguage, 'Fullscreen')}
icon={ icon={
<Broadcast <Broadcast
iconClass="fullScreen" iconClass="fullScreen"
@ -286,9 +310,13 @@ const Index: FC<{ setIsscreenshot: Function; setScreenshotLoading: Function }> =
/> />
} }
/> />
)}
<Tooltip <Tooltip
styleCss={{ padding: '0 5px' }} styleCss={{ padding: `0 ${space}` }}
title={controlsState.isScreentFull ? '退出全屏' : '全屏'} title={il8n(
propsAttributes!.language || defaultLanguage,
controlsState.isScreentFull ? 'closefullScreen' : 'fullScreen',
)}
icon={ icon={
<Broadcast <Broadcast
iconClass="fullScreen" iconClass="fullScreen"

@ -7,12 +7,14 @@ export interface MultipleType {
multipleText: string; multipleText: string;
selectPlayRate: Function; selectPlayRate: Function;
multiple: number; multiple: number;
style?: React.CSSProperties;
} }
const Multiple: FC<MultipleType> = memo(function Multiple({ const Multiple: FC<MultipleType> = memo(function Multiple({
multipleText, multipleText,
selectPlayRate, selectPlayRate,
multiple, multiple,
style,
}) { }) {
const reviceProps = useContext(FlowContext); const reviceProps = useContext(FlowContext);
@ -25,6 +27,7 @@ const Multiple: FC<MultipleType> = memo(function Multiple({
className="JoL-multifunction-multiple" className="JoL-multifunction-multiple"
onClick={(e) => setIsShow((pre) => !pre)} onClick={(e) => setIsShow((pre) => !pre)}
onMouseLeave={(e) => [setIsShow(false)]} onMouseLeave={(e) => [setIsShow(false)]}
style={style}
> >
<p>{multipleText}</p> <p>{multipleText}</p>
<div <div

@ -2,16 +2,19 @@ import React, { memo, FC, useState, useContext } from 'react';
import Broadcast from '@/components/svgIcon'; import Broadcast from '@/components/svgIcon';
import Switch from '@/components/switch'; import Switch from '@/components/switch';
import { FlowContext } from '@/core/context'; import { FlowContext } from '@/core/context';
import { il8n } from '@/language';
import { defaultLanguage } from '@/core/config';
import './index.scss'; import './index.scss';
export interface SetType { export interface SetType {
switchChange: Function; switchChange: Function;
style?: React.CSSProperties;
} }
const Set: FC<SetType> = memo(function Set({ switchChange }) { const Set: FC<SetType> = memo(function Set({ switchChange, style }) {
const reviceProps = useContext(FlowContext); const reviceProps = useContext(FlowContext);
const { theme } = reviceProps.propsAttributes!; const { theme, language } = reviceProps.propsAttributes!;
const [isShow, setIsShow] = useState<boolean>(false); const [isShow, setIsShow] = useState<boolean>(false);
return ( return (
@ -19,6 +22,7 @@ const Set: FC<SetType> = memo(function Set({ switchChange }) {
className="JoL-multifunction-set" className="JoL-multifunction-set"
onMouseEnter={(e) => [setIsShow(true), e.stopPropagation()]} onMouseEnter={(e) => [setIsShow(true), e.stopPropagation()]}
onMouseLeave={(e) => [setIsShow(false)]} onMouseLeave={(e) => [setIsShow(false)]}
style={style}
> >
<Broadcast iconClass="set" fill="#fff" className="hover-icon-rotateAnimate" /> <Broadcast iconClass="set" fill="#fff" className="hover-icon-rotateAnimate" />
<div <div
@ -29,7 +33,7 @@ const Set: FC<SetType> = memo(function Set({ switchChange }) {
<li> <li>
<Switch <Switch
sole="lights" sole="lights"
label="关灯" label={il8n(language || defaultLanguage, 'closeLights')}
onChange={(e: string) => switchChange(e, 'lights')} onChange={(e: string) => switchChange(e, 'lights')}
theme={theme} theme={theme}
/> />
@ -37,7 +41,7 @@ const Set: FC<SetType> = memo(function Set({ switchChange }) {
<li> <li>
<Switch <Switch
sole="loop" sole="loop"
label="循环" label={il8n(language || defaultLanguage, 'loop')}
theme={theme} theme={theme}
onChange={(e: string) => switchChange(e, 'loop')} onChange={(e: string) => switchChange(e, 'loop')}
/> />

@ -11,6 +11,7 @@ export interface VolumeType {
slideCurrentVolume: React.MouseEventHandler<HTMLDivElement>; slideCurrentVolume: React.MouseEventHandler<HTMLDivElement>;
clearVolumeInterval: React.MouseEventHandler<HTMLDivElement>; clearVolumeInterval: React.MouseEventHandler<HTMLDivElement>;
toggleVolume: Function; toggleVolume: Function;
style?: React.CSSProperties;
} }
const Volume = function Volume( const Volume = function Volume(
@ -21,6 +22,7 @@ const Volume = function Volume(
clearVolumeInterval, clearVolumeInterval,
isMuted, isMuted,
toggleVolume, toggleVolume,
style,
}: VolumeType, }: VolumeType,
ref: React.Ref<unknown> | undefined, ref: React.Ref<unknown> | undefined,
) { ) {
@ -42,6 +44,7 @@ const Volume = function Volume(
onMouseEnter={(e) => [setIsShow(true)]} onMouseEnter={(e) => [setIsShow(true)]}
onMouseLeave={(e) => [setIsShow(false)]} onMouseLeave={(e) => [setIsShow(false)]}
onClick={(e) => [toggleVolume()]} onClick={(e) => [toggleVolume()]}
style={style}
> >
<Broadcast iconClass={isMuted ? 'set' : 'volume'} fill="#fff" fontSize={'20px'} /> <Broadcast iconClass={isMuted ? 'set' : 'volume'} fill="#fff" fontSize={'20px'} />
<div <div

@ -14,8 +14,6 @@ import Broadcast from '@/components/svgIcon';
import { useVideo } from '@/core/useVideo'; import { useVideo } from '@/core/useVideo';
import useVideoCallback from '@/core/useVideoCallback'; import useVideoCallback from '@/core/useVideoCallback';
import { defaultTheme } from '@/core/config'; import { defaultTheme } from '@/core/config';
// import videoUrl from '@/assets/haiwang.mp4';
import '@/assets/css/reset.scss'; import '@/assets/css/reset.scss';
import './index.scss'; import './index.scss';
@ -175,12 +173,5 @@ const JoLPlayer = function JoLPlayer(props: videoparameter, ref: React.Ref<unkno
}; };
const JoLPlayerComponent = forwardRef<JoLPlayerRef, videoparameter>(JoLPlayer); const JoLPlayerComponent = forwardRef<JoLPlayerRef, videoparameter>(JoLPlayer);
JoLPlayerComponent.defaultProps = {
option: {
width: 750,
height: 420,
videoSrc: 'https://cdn.gudsen.com/2021/06/28/f81356b08b4842d7a3719499f557c8e4.JPG',
isShowMultiple: true,
},
};
export default JoLPlayerComponent; export default JoLPlayerComponent;

@ -172,7 +172,7 @@ const Index = memo(function Index(props) {
return ( return (
<div <div
className="JoL-progress-container" className="JoL-progress-container"
// style={{ opacity: reviceProps.videoFlow!.isControl ? '1' : '0' }} style={{ opacity: reviceProps.videoFlow!.isControl ? '1' : '0' }}
> >
<div className="progress-bg" ref={progressBgRef}> <div className="progress-bg" ref={progressBgRef}>
<div className="progress-buffered" style={{ width: `${calculateBufferedPercent}%` }}></div> <div className="progress-buffered" style={{ width: `${calculateBufferedPercent}%` }}></div>

@ -7,6 +7,8 @@ export interface hoverShowStyleType {
progressScrubberRefEle: HTMLDivElement; progressScrubberRefEle: HTMLDivElement;
} }
export type pausePlacement = 'bottomRight' | 'center'; export type pausePlacement = 'bottomRight' | 'center';
export type languageType = 'zh' | 'en';
export interface videoOption<T = string, K = boolean, U = number> { export interface videoOption<T = string, K = boolean, U = number> {
/** /**
* @description width * @description width
@ -64,6 +66,10 @@ export interface videoOption<T = string, K = boolean, U = number> {
* @description * @description
*/ */
isShowWebFullScreen?: K; isShowWebFullScreen?: K;
/**
* @description ,
*/
language?: languageType;
} }
export interface videoAttributes<T = number, K = boolean> { export interface videoAttributes<T = number, K = boolean> {
/** /**

@ -0,0 +1,53 @@
import { languageType } from '@/interface';
export interface langType<T = string> {
multiple: T;
closeLights: T;
loop: T;
screenshots: T;
openPicture: T;
closePicture: T;
Fullscreen: T;
fullScreen: T;
replay: T;
closeFullscreen: T;
closefullScreen: T;
screenshotsFailText: T;
screenshotsSucessText: T;
}
export const zhJson: langType = {
multiple: '倍数',
closeLights: '关灯',
loop: '循环',
screenshots: '截图',
openPicture: '开启画中画',
closePicture: '关闭画中画',
Fullscreen: '网页全屏',
closeFullscreen: '关闭网页全屏',
fullScreen: '全屏',
closefullScreen: '关闭全屏',
replay: '重播',
screenshotsSucessText: '鼠标右键图片另存为',
screenshotsFailText: '截图加载失败,在点击下',
};
export const enJson: langType = {
multiple: 'multiple',
closeLights: 'lights',
loop: 'loops',
screenshots: 'screenshots',
openPicture: 'open Picture',
closePicture: 'close Picture',
Fullscreen: 'Full screen',
closeFullscreen: 'close Full screen',
fullScreen: 'full Screen',
closefullScreen: 'close full Screen',
replay: 'Replay',
screenshotsSucessText: 'Right mouse button to save the picture as',
screenshotsFailText: 'The screenshot failed to load, click',
};
export const il8n = (lang: languageType, key: keyof langType) => {
if (lang === 'zh') {
return zhJson[key];
} else {
return enJson[key];
}
};

@ -48,3 +48,13 @@ export const capture = (video: HTMLVideoElement, scaleFactor: number = 0.25) =>
ctx!.drawImage(video, 0, 0, w, h); ctx!.drawImage(video, 0, 0, w, h);
return canvas; return canvas;
}; };
export const filterDefaults = (val: unknown) => {
if (val === null || val === undefined) {
return true;
} else if (val === true) {
return true;
} else {
return false;
}
};

Loading…
Cancel
Save