|
@@ -0,0 +1,693 @@
|
|
|
+// import { Popup } from 'vant';
|
|
|
+import {
|
|
|
+ defineComponent,
|
|
|
+ onMounted,
|
|
|
+ reactive,
|
|
|
+ nextTick,
|
|
|
+ onUnmounted,
|
|
|
+ ref,
|
|
|
+ watch,
|
|
|
+ Transition
|
|
|
+} from 'vue';
|
|
|
+// import iconBack from './image/back.svg';
|
|
|
+import styles from './index.module.less';
|
|
|
+import 'plyr/dist/plyr.css';
|
|
|
+import MusicScore from './component/musicScore';
|
|
|
+import iconMenu from './image/icon-menu.svg';
|
|
|
+// import iconDian from './image/icon-dian.svg';
|
|
|
+// import iconPoint from './image/icon-point.svg';
|
|
|
+import iconUp from './image/icon-up.svg';
|
|
|
+import iconUpDisabled from './image/icon-up-disabled.svg';
|
|
|
+import iconDown from './image/icon-down.svg';
|
|
|
+import iconDownDisabled from './image/icon-down-disabled.svg';
|
|
|
+import iconWhiteboard from './image/icon-whiteboard.svg';
|
|
|
+// import Points from './component/points';
|
|
|
+import iconAssignHomework from './image/icon-assignHomework.svg';
|
|
|
+import { Vue3Lottie } from 'vue3-lottie';
|
|
|
+import playLoadData from './datas/data.json';
|
|
|
+import { usePageVisibility } from '@vant/use';
|
|
|
+import VideoPlay from './component/video-play';
|
|
|
+import { useMessage, NDrawer, NDrawerContent } from 'naive-ui';
|
|
|
+import CardType from '@/components/card-type';
|
|
|
+import { ToolItem, ToolType } from './component/tool';
|
|
|
+import Pen from './component/tools/pen';
|
|
|
+import AudioPay from './component/audio-pay';
|
|
|
+
|
|
|
+export default defineComponent({
|
|
|
+ name: 'CoursewarePlay',
|
|
|
+ setup() {
|
|
|
+ const message = useMessage();
|
|
|
+ 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'
|
|
|
+ });
|
|
|
+ const setContainer = () => {
|
|
|
+ const min = Math.min(screen.width, screen.height);
|
|
|
+ const max = Math.max(screen.width, screen.height);
|
|
|
+ const width = min * (16 / 9);
|
|
|
+ if (width > max) {
|
|
|
+ parentContainer.width = '100vw';
|
|
|
+ return;
|
|
|
+ } else {
|
|
|
+ parentContainer.width = width + 'px';
|
|
|
+ }
|
|
|
+ };
|
|
|
+ const handleInit = (type = 0) => {
|
|
|
+ //设置容器16:9
|
|
|
+ setContainer();
|
|
|
+ };
|
|
|
+ handleInit();
|
|
|
+ onUnmounted(() => {
|
|
|
+ handleInit(1);
|
|
|
+ });
|
|
|
+
|
|
|
+ // 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({
|
|
|
+ isAutoPlay: true, // 是否自动播放
|
|
|
+ nowTime: 0,
|
|
|
+ model: true, // 遮罩
|
|
|
+ isAnimation: true, // 是否动画
|
|
|
+ videoBtns: true, // 视频
|
|
|
+ currentTime: 0,
|
|
|
+ duration: 0,
|
|
|
+ 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 () => {
|
|
|
+ data.knowledgePointList = [
|
|
|
+ {
|
|
|
+ id: '5',
|
|
|
+ name: '歌曲表演 大鹿',
|
|
|
+ title: '歌曲表演 大鹿',
|
|
|
+ type: 'AUDIO',
|
|
|
+ content:
|
|
|
+ 'https://cloud-coach.ks3-cn-beijing.ksyuncs.com/1686819360752.mp3',
|
|
|
+ url: 'https://lanhu-dds-backend.oss-cn-beijing.aliyuncs.com/merge_image/imgs/23cc71b5d7874dcf8752cd257483e687_mergeImage.png'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: '1',
|
|
|
+ name: '歌曲表演 大鹿',
|
|
|
+ title: '歌曲表演 大鹿',
|
|
|
+ type: 'VIDEO',
|
|
|
+ content:
|
|
|
+ 'https://courseware.lexiaoya.cn/%E5%BF%85%E5%AD%A6%E5%BF%85%E7%9C%8B-%E8%90%A8%E5%85%8B%E6%96%AF-1-C4-4.mp4',
|
|
|
+ url: 'https://lanhu-dds-backend.oss-cn-beijing.aliyuncs.com/merge_image/imgs/23cc71b5d7874dcf8752cd257483e687_mergeImage.png'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: '2',
|
|
|
+ name: '知识 音的高低',
|
|
|
+ title: '知识 音的高低',
|
|
|
+ type: 'IMG',
|
|
|
+ content:
|
|
|
+ 'https://gyt.ks3-cn-beijing.ksyuncs.com/courseware/1686815979899.png',
|
|
|
+ url: 'https://gyt.ks3-cn-beijing.ksyuncs.com/courseware/1686815979899.png'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: '3',
|
|
|
+ name: '欣赏 永远在童话里',
|
|
|
+ title: '欣赏 永远在童话里',
|
|
|
+ type: 'IMG',
|
|
|
+ content:
|
|
|
+ 'https://gyt.ks3-cn-beijing.ksyuncs.com/courseware/1686815979899.png',
|
|
|
+ url: 'https://gyt.ks3-cn-beijing.ksyuncs.com/courseware/1686815979899.png'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: '4',
|
|
|
+ name: '唱歌 小红帽',
|
|
|
+ title: '唱歌 小红帽',
|
|
|
+ type: 'SONG',
|
|
|
+ content: '11707',
|
|
|
+ url: 'https://lanhu.oss-cn-beijing.aliyuncs.com/SketchPngd1f4e00a00bc8134db4ec43e51a66442f778756e2caf01d10a1ffdd51fc7c6cb'
|
|
|
+ }
|
|
|
+ ];
|
|
|
+ data.itemList = data.knowledgePointList.map((m: any) => {
|
|
|
+ return {
|
|
|
+ ...m,
|
|
|
+ iframeRef: null,
|
|
|
+ videoEle: null,
|
|
|
+ autoPlay: false, //加载完成是否自动播放
|
|
|
+ isprepare: false, // 视频是否加载完成
|
|
|
+ isRender: false // 是否渲染了
|
|
|
+ };
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ onMounted(() => {
|
|
|
+ getDetail();
|
|
|
+ });
|
|
|
+
|
|
|
+ // const playRef = ref();
|
|
|
+ // 返回
|
|
|
+ // const goback = () => {
|
|
|
+ // try {
|
|
|
+ // playRef.value?.handleOut();
|
|
|
+ // } catch {
|
|
|
+ // //
|
|
|
+ // }
|
|
|
+ // postMessage({ api: 'goBack' });
|
|
|
+ // };
|
|
|
+
|
|
|
+ const popupData = reactive({
|
|
|
+ open: false,
|
|
|
+ activeIndex: 0,
|
|
|
+ // tabActive: '',
|
|
|
+ // tabName: '',
|
|
|
+ // itemActive: '',
|
|
|
+ // itemName: ''
|
|
|
+ // guideOpen: false,
|
|
|
+ toolOpen: false // 工具弹窗控制
|
|
|
+ });
|
|
|
+
|
|
|
+ /**停止所有的播放 */
|
|
|
+ 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);
|
|
|
+ if (index > -1) {
|
|
|
+ handleSwipeChange(index);
|
|
|
+ }
|
|
|
+ };
|
|
|
+ /** 延迟收起模态框 */
|
|
|
+ const setModelOpen = () => {
|
|
|
+ clearTimeout(activeData.timer);
|
|
|
+ message.destroyAll();
|
|
|
+ activeData.timer = setTimeout(() => {
|
|
|
+ activeData.model = false;
|
|
|
+ Object.values(data.videoRefs).map((n: any) =>
|
|
|
+ n.toggleHideControl(false)
|
|
|
+ );
|
|
|
+ }, 4000);
|
|
|
+ };
|
|
|
+
|
|
|
+ /** 立即收起所有的模态框 */
|
|
|
+ const clearModel = () => {
|
|
|
+ clearTimeout(activeData.timer);
|
|
|
+ message.destroyAll();
|
|
|
+ activeData.model = false;
|
|
|
+ Object.values(data.videoRefs).map((n: any) => n.toggleHideControl(false));
|
|
|
+ };
|
|
|
+ const toggleModel = (type = 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) {
|
|
|
+ message.destroyAll();
|
|
|
+ videoEle.play();
|
|
|
+ } else {
|
|
|
+ message.warning('已暂停');
|
|
|
+ videoEle.pause();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // 切换播放
|
|
|
+ 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 = [
|
|
|
+ {
|
|
|
+ prev: {
|
|
|
+ transform: 'translate3d(0, 0, -800px) rotateX(180deg)'
|
|
|
+ },
|
|
|
+ next: {
|
|
|
+ transform: 'translate3d(0, 0, -800px) rotateX(-180deg)'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prev: {
|
|
|
+ transform: 'translate3d(-100%, 0, -800px)'
|
|
|
+ },
|
|
|
+ next: {
|
|
|
+ transform: 'translate3d(100%, 0, -800px)'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prev: {
|
|
|
+ transform: 'translate3d(-50%, 0, -800px) rotateY(80deg)'
|
|
|
+ },
|
|
|
+ next: {
|
|
|
+ transform: 'translate3d(50%, 0, -800px) rotateY(-80deg)'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prev: {
|
|
|
+ transform: 'translate3d(-100%, 0, -800px) rotateY(-120deg)'
|
|
|
+ },
|
|
|
+ next: {
|
|
|
+ transform: 'translate3d(100%, 0, -800px) rotateY(120deg)'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 风车4
|
|
|
+ {
|
|
|
+ prev: {
|
|
|
+ transform: 'translate3d(-50%, 50%, -800px) rotateZ(-14deg)',
|
|
|
+ opacity: 0
|
|
|
+ },
|
|
|
+ next: {
|
|
|
+ transform: 'translate3d(50%, 50%, -800px) rotateZ(14deg)',
|
|
|
+ opacity: 0
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 翻页5
|
|
|
+ {
|
|
|
+ prev: {
|
|
|
+ transform: 'translateZ(-800px) rotate3d(0, -1, 0, 90deg)',
|
|
|
+ opacity: 0
|
|
|
+ },
|
|
|
+ next: {
|
|
|
+ transform: 'translateZ(-800px) rotate3d(0, 1, 0, 90deg)',
|
|
|
+ opacity: 0
|
|
|
+ },
|
|
|
+ current: { transitionDelay: '700ms' }
|
|
|
+ }
|
|
|
+ ];
|
|
|
+
|
|
|
+ const acitveTimer = ref();
|
|
|
+ // 轮播切换
|
|
|
+ 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);
|
|
|
+ message.destroyAll();
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // 上一个知识点, 下一个知识点
|
|
|
+ const handlePreAndNext = (type: string) => {
|
|
|
+ if (type === 'up') {
|
|
|
+ handleSwipeChange(popupData.activeIndex - 1);
|
|
|
+ } else {
|
|
|
+ handleSwipeChange(popupData.activeIndex + 1);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ /** 弹窗关闭 */
|
|
|
+ const handleClosePopup = () => {
|
|
|
+ const item = data.itemList[popupData.activeIndex];
|
|
|
+ if (item?.type == 'VIDEO' && !item.videoEle?.paused) {
|
|
|
+ setModelOpen();
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // 监听页面键盘事件 - 上下切换
|
|
|
+ document.body.addEventListener('keyup', (e: KeyboardEvent) => {
|
|
|
+ if (e.key === 'ArrowUp') {
|
|
|
+ if (popupData.activeIndex === 0) return;
|
|
|
+ handlePreAndNext('up');
|
|
|
+ } else if (e.key === 'ArrowDown') {
|
|
|
+ if (popupData.activeIndex === data.itemList.length - 1) return;
|
|
|
+ handlePreAndNext('down');
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ /** 教学数据 */
|
|
|
+ const studyData = reactive({
|
|
|
+ type: '' as ToolType,
|
|
|
+ penShow: false
|
|
|
+ });
|
|
|
+
|
|
|
+ /** 打开教学工具 */
|
|
|
+ const openStudyTool = (item: ToolItem) => {
|
|
|
+ const activeItem = data.itemList[popupData.activeIndex];
|
|
|
+ // 暂停视频和曲谱的播放
|
|
|
+ if (activeItem.type === 'VIDEO' && activeItem.videoEle) {
|
|
|
+ activeItem.videoEle.pause();
|
|
|
+ }
|
|
|
+ if (activeItem.type === 'SONG') {
|
|
|
+ activeItem.iframeRef?.contentWindow?.postMessage(
|
|
|
+ { api: 'setPlayState' },
|
|
|
+ '*'
|
|
|
+ );
|
|
|
+ }
|
|
|
+ clearModel();
|
|
|
+ popupData.toolOpen = false;
|
|
|
+ studyData.type = item.type;
|
|
|
+
|
|
|
+ switch (item.type) {
|
|
|
+ case 'pen':
|
|
|
+ studyData.penShow = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ /** 关闭教学工具 */
|
|
|
+ const closeStudyTool = () => {
|
|
|
+ studyData.type = 'init';
|
|
|
+ toggleModel();
|
|
|
+ };
|
|
|
+
|
|
|
+ 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
|
|
|
+ class={styles.coursewarePlay}
|
|
|
+ style={{ width: parentContainer.width }}
|
|
|
+ onClick={(e: Event) => {
|
|
|
+ e.stopPropagation();
|
|
|
+ setModelOpen();
|
|
|
+ }}>
|
|
|
+ <div class={styles.wraps}>
|
|
|
+ {data.itemList.map((m: any, mIndex: number) => {
|
|
|
+ const isRender =
|
|
|
+ m.isRender || Math.abs(popupData.activeIndex - mIndex) < 2;
|
|
|
+ const isEmtry = Math.abs(popupData.activeIndex - mIndex) > 4;
|
|
|
+ if (isRender) {
|
|
|
+ m.isRender = true;
|
|
|
+ }
|
|
|
+ return isRender ? (
|
|
|
+ <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
|
|
|
+ : {}
|
|
|
+ }
|
|
|
+ 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) {
|
|
|
+ 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 === 'AUDIO' ? (
|
|
|
+ <AudioPay item={m} />
|
|
|
+ ) : (
|
|
|
+ <MusicScore
|
|
|
+ activeModel={activeData.model}
|
|
|
+ data-vid={m.id}
|
|
|
+ music={m}
|
|
|
+ onSetIframe={(el: any) => {
|
|
|
+ m.iframeRef = el;
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ ) : null;
|
|
|
+ })}
|
|
|
+ </div>
|
|
|
+ <Transition name="right">
|
|
|
+ {activeData.model && (
|
|
|
+ <div
|
|
|
+ class={styles.rightFixedBtns}
|
|
|
+ onClick={(e: Event) => {
|
|
|
+ e.stopPropagation();
|
|
|
+ clearTimeout(activeData.timer);
|
|
|
+ }}>
|
|
|
+ <div
|
|
|
+ class={[styles.fullBtn, styles.point]}
|
|
|
+ onClick={() => (popupData.open = true)}>
|
|
|
+ <img src={iconMenu} />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+ </Transition>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* <div
|
|
|
+ style={{ transform: activeData.model ? '' : 'translateY(-100%)' }}
|
|
|
+ class={styles.headerContainer}
|
|
|
+ ref={headeRef}>
|
|
|
+ <div class={styles.backBtn} onClick={() => goback()}>
|
|
|
+ <Icon name={iconBack} />
|
|
|
+ 返回
|
|
|
+ </div>
|
|
|
+ <div class={styles.menu}>{popupData.itemName}</div>
|
|
|
+ </div> */}
|
|
|
+ {/* 布置作业按钮 */}
|
|
|
+ <div class={styles.assignHomework}>
|
|
|
+ <img src={iconAssignHomework} />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* 上下切换 */}
|
|
|
+ <div
|
|
|
+ class={[
|
|
|
+ styles.switchChangeSection,
|
|
|
+ activeData.model ? '' : styles.sectionAnimate
|
|
|
+ ]}>
|
|
|
+ <div
|
|
|
+ class={[styles.switchBtn]}
|
|
|
+ onClick={() => {
|
|
|
+ if (popupData.activeIndex === 0) return;
|
|
|
+ handlePreAndNext('up');
|
|
|
+ }}>
|
|
|
+ <img src={popupData.activeIndex === 0 ? iconUpDisabled : iconUp} />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div
|
|
|
+ class={[styles.switchBtn]}
|
|
|
+ onClick={() => {
|
|
|
+ if (popupData.activeIndex === data.itemList.length - 1) return;
|
|
|
+ handlePreAndNext('down');
|
|
|
+ }}>
|
|
|
+ <img
|
|
|
+ src={
|
|
|
+ popupData.activeIndex === data.itemList.length - 1
|
|
|
+ ? iconDownDisabled
|
|
|
+ : iconDown
|
|
|
+ }
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* 白板 */}
|
|
|
+ <div
|
|
|
+ class={[
|
|
|
+ styles.switchDisplaySection,
|
|
|
+ activeData.model ? '' : styles.sectionAnimate
|
|
|
+ ]}>
|
|
|
+ <div
|
|
|
+ class={styles.displayBtn}
|
|
|
+ onClick={() =>
|
|
|
+ openStudyTool({
|
|
|
+ type: 'pen',
|
|
|
+ icon: iconWhiteboard,
|
|
|
+ name: '白板'
|
|
|
+ })
|
|
|
+ }>
|
|
|
+ <img src={iconWhiteboard} />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <NDrawer
|
|
|
+ v-model:show={popupData.open}
|
|
|
+ class={styles.drawerContainer}
|
|
|
+ onAfterLeave={handleClosePopup}
|
|
|
+ showMask={false}>
|
|
|
+ <NDrawerContent title="资源列表" closable>
|
|
|
+ {data.knowledgePointList.map((item: any, index: number) => (
|
|
|
+ <CardType
|
|
|
+ item={item}
|
|
|
+ isActive={popupData.activeIndex === index}
|
|
|
+ isCollect={false}
|
|
|
+ onClick={(item: any) => {
|
|
|
+ popupData.open = false;
|
|
|
+ toggleMaterial(item.id);
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ ))}
|
|
|
+ </NDrawerContent>
|
|
|
+ </NDrawer>
|
|
|
+
|
|
|
+ {studyData.penShow && (
|
|
|
+ <Pen show={studyData.type === 'pen'} close={() => closeStudyTool()} />
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ }
|
|
|
+});
|