|
@@ -16,7 +16,8 @@ import { useRoute, useRouter } from 'vue-router';
|
|
|
import {
|
|
|
listenerMessage,
|
|
|
postMessage,
|
|
|
- promisefiyPostMessage
|
|
|
+ promisefiyPostMessage,
|
|
|
+ removeListenerMessage
|
|
|
} from '@/helpers/native-message';
|
|
|
import MusicScore from './component/musicScore';
|
|
|
import iconMenu from './image/icon-menu.svg';
|
|
@@ -28,29 +29,17 @@ import Points from './component/points';
|
|
|
import { browser, getSecondRPM } from '@/helpers/utils';
|
|
|
import { Vue3Lottie } from 'vue3-lottie';
|
|
|
import playLoadData from './datas/data.json';
|
|
|
-import { usePageVisibility, useRect } from '@vant/use';
|
|
|
+import { usePageVisibility } from '@vant/use';
|
|
|
import VideoPlay from './component/video-play';
|
|
|
-import Tool, { ToolItem, ToolType } from './component/tool';
|
|
|
import AudioItem from './component/audio-item';
|
|
|
import { api_lessonCoursewareKnowledgeDetailDetail } from './api';
|
|
|
+import VideoItem from './component/video-item';
|
|
|
|
|
|
export default defineComponent({
|
|
|
name: 'CoursewarePlay',
|
|
|
setup() {
|
|
|
const pageVisibility = usePageVisibility();
|
|
|
- const isPlay = ref(false);
|
|
|
- /** 页面显示和隐藏 */
|
|
|
- watch(pageVisibility, value => {
|
|
|
- const activeItem = data.itemList[popupData.activeIndex];
|
|
|
- if (activeItem.type != 'VIDEO') return;
|
|
|
- if (value == 'hidden') {
|
|
|
- isPlay.value = !activeItem.videoEle?.paused;
|
|
|
- togglePlay(activeItem, false);
|
|
|
- } else {
|
|
|
- // 页面显示,并且
|
|
|
- if (isPlay.value) togglePlay(activeItem, true);
|
|
|
- }
|
|
|
- });
|
|
|
+
|
|
|
/** 设置播放容器 16:9 */
|
|
|
const parentContainer = reactive({
|
|
|
width: '100vw'
|
|
@@ -110,15 +99,10 @@ export default defineComponent({
|
|
|
});
|
|
|
|
|
|
const route = useRoute();
|
|
|
- const router = useRouter();
|
|
|
const headeRef = ref();
|
|
|
const data = reactive({
|
|
|
- detail: null,
|
|
|
knowledgePointList: [] as any,
|
|
|
itemList: [] as any,
|
|
|
- showHead: true,
|
|
|
- isCourse: false,
|
|
|
- isRecordPlay: false,
|
|
|
videoRefs: {} as any[]
|
|
|
});
|
|
|
const activeData = reactive({
|
|
@@ -132,24 +116,6 @@ export default defineComponent({
|
|
|
timer: null as any,
|
|
|
item: null as any
|
|
|
});
|
|
|
- const getTempList = async (materialList: any, name: any) => {
|
|
|
- const list: any = [];
|
|
|
- const browserInfo = browser();
|
|
|
- for (let j = 0; j < materialList.length; j++) {
|
|
|
- const material = materialList[j];
|
|
|
-
|
|
|
- list.push({
|
|
|
- ...material,
|
|
|
- iframeRef: null,
|
|
|
- videoEle: null,
|
|
|
- tabName: name,
|
|
|
- autoPlay: false, //加载完成是否自动播放
|
|
|
- isprepare: false, // 视频是否加载完成
|
|
|
- isRender: false // 是否渲染了
|
|
|
- });
|
|
|
- }
|
|
|
- return list;
|
|
|
- };
|
|
|
const getDetail = async () => {
|
|
|
const res = await api_lessonCoursewareKnowledgeDetailDetail({
|
|
|
lessonCoursewareKnowledgeDetailId: route.query.id
|
|
@@ -162,14 +128,16 @@ export default defineComponent({
|
|
|
};
|
|
|
});
|
|
|
}
|
|
|
- popupData.itemActive = data.knowledgePointList[0].id;
|
|
|
- popupData.itemName = data.knowledgePointList[0].name;
|
|
|
data.itemList = data.knowledgePointList.map((m: any, index: number) => {
|
|
|
+ if (!popupData.itemActive) {
|
|
|
+ popupData.itemActive = m.id;
|
|
|
+ popupData.itemName = m.name;
|
|
|
+ }
|
|
|
return {
|
|
|
...m,
|
|
|
iframeRef: null,
|
|
|
videoEle: null,
|
|
|
- autoPlay: false, //加载完成是否自动播放
|
|
|
+ autoPlay: index === 0, //加载完成是否自动播放
|
|
|
isprepare: false, // 视频是否加载完成
|
|
|
isRender: false // 是否渲染了
|
|
|
};
|
|
@@ -209,31 +177,10 @@ export default defineComponent({
|
|
|
const popupData = reactive({
|
|
|
open: false,
|
|
|
activeIndex: 0,
|
|
|
- tabActive: '',
|
|
|
- tabName: '',
|
|
|
itemActive: '',
|
|
|
- itemName: '',
|
|
|
- guideOpen: false,
|
|
|
- toolOpen: false // 工具弹窗控制
|
|
|
+ itemName: ''
|
|
|
});
|
|
|
|
|
|
- /**停止所有的播放 */
|
|
|
- const handleStop = () => {
|
|
|
- for (let i = 0; i < data.itemList.length; i++) {
|
|
|
- const activeItem = data.itemList[i];
|
|
|
- if (activeItem.type === 'VIDEO' && activeItem.videoEle) {
|
|
|
- activeItem.videoEle.stop();
|
|
|
- }
|
|
|
- // console.log('🚀 ~ activeItem:', activeItem)
|
|
|
- // 停止曲谱的播放
|
|
|
- if (activeItem.type === 'SONG') {
|
|
|
- activeItem.iframeRef?.contentWindow?.postMessage(
|
|
|
- { api: 'setPlayState' },
|
|
|
- '*'
|
|
|
- );
|
|
|
- }
|
|
|
- }
|
|
|
- };
|
|
|
// 切换素材
|
|
|
const toggleMaterial = (itemActive: any) => {
|
|
|
const index = data.itemList.findIndex((n: any) => n.id == itemActive);
|
|
@@ -245,51 +192,18 @@ export default defineComponent({
|
|
|
const setModelOpen = () => {
|
|
|
clearTimeout(activeData.timer);
|
|
|
closeToast();
|
|
|
+ activeData.model = true;
|
|
|
activeData.timer = setTimeout(() => {
|
|
|
activeData.model = false;
|
|
|
- Object.values(data.videoRefs).map((n: any) =>
|
|
|
- n.toggleHideControl(false)
|
|
|
- );
|
|
|
}, 4000);
|
|
|
};
|
|
|
- /** 立即收起所有的模态框 */
|
|
|
- const clearModel = () => {
|
|
|
- clearTimeout(activeData.timer);
|
|
|
- closeToast();
|
|
|
- activeData.model = false;
|
|
|
- Object.values(data.videoRefs).map((n: any) => n.toggleHideControl(false));
|
|
|
- };
|
|
|
- const toggleModel = (type: boolean = true) => {
|
|
|
- activeData.model = type;
|
|
|
- Object.values(data.videoRefs).map((n: any) => n.toggleHideControl(type));
|
|
|
- };
|
|
|
|
|
|
// 双击
|
|
|
const handleDbClick = (item: any) => {
|
|
|
- if (item && item.type === 'VIDEO') {
|
|
|
- const videoEle: HTMLVideoElement = item.videoEle;
|
|
|
- if (videoEle) {
|
|
|
- if (videoEle.paused) {
|
|
|
- closeToast();
|
|
|
- videoEle.play();
|
|
|
- } else {
|
|
|
- showToast('已暂停');
|
|
|
- videoEle.pause();
|
|
|
- }
|
|
|
- }
|
|
|
+ if (item && ['VIDEO'].includes(item.type)) {
|
|
|
+ console.log('双击');
|
|
|
}
|
|
|
};
|
|
|
-
|
|
|
- // 切换播放
|
|
|
- const togglePlay = (m: any, isPlay: boolean) => {
|
|
|
- if (isPlay) {
|
|
|
- m.videoEle?.play();
|
|
|
- } else {
|
|
|
- m.videoEle?.pause();
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- const showIndex = ref(-4);
|
|
|
const effectIndex = ref(3);
|
|
|
const effects = [
|
|
|
{
|
|
@@ -354,62 +268,12 @@ export default defineComponent({
|
|
|
const handleSwipeChange = (index: number) => {
|
|
|
// 如果是当前正在播放 或者是视频最后一个
|
|
|
if (popupData.activeIndex == index) return;
|
|
|
- handleStop();
|
|
|
clearTimeout(acitveTimer.value);
|
|
|
- // checkedAnimation(popupData.activeIndex, index);
|
|
|
- popupData.activeIndex = index;
|
|
|
-
|
|
|
- acitveTimer.value = setTimeout(
|
|
|
- () => {
|
|
|
- const item = data.itemList[index];
|
|
|
- if (item) {
|
|
|
- popupData.tabActive = item.knowledgePointId;
|
|
|
- popupData.itemActive = item.id;
|
|
|
- popupData.itemName = item.name;
|
|
|
- popupData.tabName = item.tabName;
|
|
|
- if (item.type == 'SONG') {
|
|
|
- activeData.model = true;
|
|
|
- }
|
|
|
- if (item.type === 'VIDEO') {
|
|
|
- // 自动播放下一个视频
|
|
|
- clearTimeout(activeData.timer);
|
|
|
- closeToast();
|
|
|
- item.autoPlay = true;
|
|
|
- nextTick(() => {
|
|
|
- item.videoEle?.play();
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
- // requestAnimationFrame(() => {
|
|
|
- // const _effectIndex = effectIndex.value + 1;
|
|
|
- // effectIndex.value =
|
|
|
- // _effectIndex >= effects.length - 1 ? 0 : _effectIndex;
|
|
|
- // });
|
|
|
- },
|
|
|
- activeData.isAnimation ? 800 : 0
|
|
|
- );
|
|
|
- };
|
|
|
-
|
|
|
- /** 是否有转场动画 */
|
|
|
- const checkedAnimation = (index: number, nextIndex?: number) => {
|
|
|
const item = data.itemList[index];
|
|
|
- const nextItem = data.itemList[nextIndex!];
|
|
|
- if (nextItem) {
|
|
|
- if (nextItem.knowledgePointId != item.knowledgePointId) {
|
|
|
- activeData.isAnimation = true;
|
|
|
- return;
|
|
|
- }
|
|
|
- const videoEle = item.videoEle;
|
|
|
- const nextVideo = nextItem.videoEle;
|
|
|
- if (videoEle && videoEle.duration < 8 && index < nextIndex!) {
|
|
|
- activeData.isAnimation = false;
|
|
|
- } else if (nextVideo && nextVideo.duration < 8 && index > nextIndex!) {
|
|
|
- activeData.isAnimation = false;
|
|
|
- } else {
|
|
|
- activeData.isAnimation = true;
|
|
|
- }
|
|
|
- } else {
|
|
|
- activeData.isAnimation = item?.adviseStudyTimeSecond < 8 ? false : true;
|
|
|
+ popupData.activeIndex = index;
|
|
|
+ popupData.itemActive = item.id;
|
|
|
+ if (item.type == 'MUSIC') {
|
|
|
+ activeData.model = true;
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -424,29 +288,14 @@ export default defineComponent({
|
|
|
|
|
|
/** 弹窗关闭 */
|
|
|
const handleClosePopup = () => {
|
|
|
- const item = data.itemList[popupData.activeIndex];
|
|
|
- if (item?.type == 'VIDEO' && !item.videoEle?.paused) {
|
|
|
- setModelOpen();
|
|
|
- }
|
|
|
+ setModelOpen();
|
|
|
};
|
|
|
-
|
|
|
return () => (
|
|
|
<div id="playContent" class={styles.playContent}>
|
|
|
- <div
|
|
|
- onClick={() => {
|
|
|
- clearTimeout(activeData.timer);
|
|
|
- activeData.model = !activeData.model;
|
|
|
- Object.values(data.videoRefs).map((n: any) =>
|
|
|
- n.toggleHideControl(activeData.model)
|
|
|
- );
|
|
|
- }}>
|
|
|
+ <div onClick={() => setModelOpen()} onTouchmove={() => setModelOpen()}>
|
|
|
<div
|
|
|
class={styles.coursewarePlay}
|
|
|
- style={{ width: parentContainer.width }}
|
|
|
- onClick={(e: Event) => {
|
|
|
- e.stopPropagation();
|
|
|
- setModelOpen();
|
|
|
- }}>
|
|
|
+ style={{ width: parentContainer.width }}>
|
|
|
<div class={styles.wraps}>
|
|
|
{data.itemList.map((m: any, mIndex: number) => {
|
|
|
const isRender =
|
|
@@ -474,94 +323,87 @@ export default defineComponent({
|
|
|
: {}
|
|
|
}
|
|
|
onClick={(e: Event) => {
|
|
|
- e.stopPropagation();
|
|
|
- clearTimeout(activeData.timer);
|
|
|
if (Date.now() - activeData.nowTime < 300) {
|
|
|
handleDbClick(m);
|
|
|
return;
|
|
|
}
|
|
|
activeData.nowTime = Date.now();
|
|
|
- activeData.timer = setTimeout(() => {
|
|
|
- activeData.model = !activeData.model;
|
|
|
- Object.values(data.videoRefs).map((n: any) =>
|
|
|
- n.toggleHideControl(activeData.model)
|
|
|
- );
|
|
|
- if (activeData.model) {
|
|
|
- setModelOpen();
|
|
|
- }
|
|
|
- }, 300);
|
|
|
}}>
|
|
|
- {m.type === 'VIDEO' ? (
|
|
|
- <>
|
|
|
- <VideoPlay
|
|
|
- ref={(v: any) => (data.videoRefs[mIndex] = v)}
|
|
|
- item={m}
|
|
|
- isEmtry={isEmtry}
|
|
|
- onLoadedmetadata={(videoItem: any) => {
|
|
|
- m.videoEle = videoItem;
|
|
|
- m.isprepare = true;
|
|
|
- }}
|
|
|
- onTogglePlay={(paused: boolean) => {
|
|
|
- m.autoPlay = false;
|
|
|
- if (
|
|
|
- paused ||
|
|
|
- popupData.open ||
|
|
|
- popupData.guideOpen
|
|
|
- ) {
|
|
|
- clearTimeout(activeData.timer);
|
|
|
- } else {
|
|
|
- setModelOpen();
|
|
|
- }
|
|
|
- }}
|
|
|
- onEnded={() => {
|
|
|
- const _index = popupData.activeIndex + 1;
|
|
|
- if (_index < data.itemList.length) {
|
|
|
- handleSwipeChange(_index);
|
|
|
- }
|
|
|
- }}
|
|
|
- onReset={() => {
|
|
|
- if (!m.videoEle?.paused) {
|
|
|
- setModelOpen();
|
|
|
- }
|
|
|
- }}
|
|
|
- />
|
|
|
- <Transition name="van-fade">
|
|
|
- {!m.isprepare && (
|
|
|
- <div class={styles.loadWrap}>
|
|
|
- <Vue3Lottie
|
|
|
- animationData={playLoadData}></Vue3Lottie>
|
|
|
- </div>
|
|
|
- )}
|
|
|
- </Transition>
|
|
|
- </>
|
|
|
- ) : m.type === 'IMG' ? (
|
|
|
- <img src={m.content} />
|
|
|
- ) : m.type === 'SONG' ? (
|
|
|
+ {m.type === 'IMG' && <img src={m.content} />}
|
|
|
+ {m.type === 'VIDEO' && (
|
|
|
+ <VideoItem
|
|
|
+ item={m}
|
|
|
+ show={popupData.activeIndex === mIndex}
|
|
|
+ pageVisibility={pageVisibility.value}
|
|
|
+ showModel={activeData.model}
|
|
|
+ isEmtry={isEmtry}
|
|
|
+ onLoadedmetadata={() => {
|
|
|
+ m.isprepare = true;
|
|
|
+ }}
|
|
|
+ onEnded={() => {
|
|
|
+ const _index = popupData.activeIndex + 1;
|
|
|
+ if (_index < data.itemList.length) {
|
|
|
+ handleSwipeChange(_index);
|
|
|
+ }
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ )}
|
|
|
+ {m.type === 'SONG' && (
|
|
|
<AudioItem
|
|
|
item={m}
|
|
|
show={popupData.activeIndex === mIndex}
|
|
|
+ pageVisibility={pageVisibility.value}
|
|
|
showModel={activeData.model}
|
|
|
isEmtry={isEmtry}
|
|
|
onEnded={() => {
|
|
|
const _index = popupData.activeIndex + 1;
|
|
|
- console.log('🚀 ~ _index:', _index);
|
|
|
if (_index < data.itemList.length) {
|
|
|
handleSwipeChange(_index);
|
|
|
}
|
|
|
}}
|
|
|
/>
|
|
|
- ) : (
|
|
|
+ )}
|
|
|
+ {m.type === 'MUSIC' && (
|
|
|
<MusicScore
|
|
|
+ pageVisibility={pageVisibility.value}
|
|
|
+ show={popupData.activeIndex === mIndex}
|
|
|
activeModel={activeData.model}
|
|
|
data-vid={m.id}
|
|
|
music={m}
|
|
|
- onSetIframe={(el: any) => {
|
|
|
- m.iframeRef = el;
|
|
|
- }}
|
|
|
/>
|
|
|
)}
|
|
|
+
|
|
|
+ {m.type === 'VIDEO' && (
|
|
|
+ <Transition name="van-fade">
|
|
|
+ {!m.isprepare && (
|
|
|
+ <div class={styles.loadWrap}>
|
|
|
+ <Vue3Lottie
|
|
|
+ style={{ width: '100%', height: '100%' }}
|
|
|
+ animationData={playLoadData}></Vue3Lottie>
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+ </Transition>
|
|
|
+ )}
|
|
|
</div>
|
|
|
- ) : null;
|
|
|
+ ) : (
|
|
|
+ <div
|
|
|
+ key={'index' + mIndex}
|
|
|
+ class={[
|
|
|
+ styles.itemDiv,
|
|
|
+ popupData.activeIndex === mIndex && styles.itemActive,
|
|
|
+ activeData.isAnimation && styles.acitveAnimation,
|
|
|
+ Math.abs(popupData.activeIndex - mIndex) < 2
|
|
|
+ ? styles.show
|
|
|
+ : styles.hide
|
|
|
+ ]}
|
|
|
+ style={
|
|
|
+ mIndex < popupData.activeIndex
|
|
|
+ ? effects[effectIndex.value].prev
|
|
|
+ : mIndex > popupData.activeIndex
|
|
|
+ ? effects[effectIndex.value].next
|
|
|
+ : {}
|
|
|
+ }></div>
|
|
|
+ );
|
|
|
})}
|
|
|
</div>
|
|
|
<Transition name="right">
|