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. 122
      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,
height: 420,
theme: '#00D3FF',
isShowMultiple: false,
poster: 'https://cdn.gudsen.com/2021/06/28/f81356b08b4842d7a3719499f557c8e4.JPG',
language: 'en',
}}
onProgressMouseDown={onProgressMouseDown}
onPlay={onPlay}

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

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

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

@ -1,20 +1,34 @@
import React, { memo, FC } from 'react';
import style from './index.module.scss';
import Broadcast from '@/components/svgIcon';
import { languageType } from '@/interface';
import { defaultTheme, defaultLanguage } from '@/core/config';
import { il8n } from '@/language';
const Index: FC<{
setIsscreenshot: Function;
screenshotLoading: boolean;
}> = memo(function Index({ setIsscreenshot, screenshotLoading }) {
theme: string | undefined;
language: languageType | undefined;
}> = memo(function Index({ setIsscreenshot, screenshotLoading, theme, language }) {
return (
<div className={style.screenshot}>
<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 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>
<p className={style.save}>
{screenshotLoading ? '截图加载失败,在点击下' : '鼠标右键图片另存为'}
{il8n(
language || defaultLanguage,
screenshotLoading ? 'screenshotsFailText' : 'screenshotsSucessText',
)}
</p>
</div>
);

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

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

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

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

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

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

@ -14,8 +14,6 @@ import Broadcast from '@/components/svgIcon';
import { useVideo } from '@/core/useVideo';
import useVideoCallback from '@/core/useVideoCallback';
import { defaultTheme } from '@/core/config';
// import videoUrl from '@/assets/haiwang.mp4';
import '@/assets/css/reset.scss';
import './index.scss';
@ -175,12 +173,5 @@ const JoLPlayer = function JoLPlayer(props: videoparameter, ref: React.Ref<unkno
};
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;

@ -172,7 +172,7 @@ const Index = memo(function Index(props) {
return (
<div
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-buffered" style={{ width: `${calculateBufferedPercent}%` }}></div>

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