|
@@ -1,8 +1,636 @@
|
|
|
-import { defineComponent } from "vue";
|
|
|
+import { closeToast, Icon, Popup, showDialog, showToast } 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 { useRoute, useRouter } from 'vue-router';
|
|
|
+import {
|
|
|
+ listenerMessage,
|
|
|
+ postMessage,
|
|
|
+ promisefiyPostMessage
|
|
|
+} from '@/helpers/native-message';
|
|
|
+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 iconDown from './image/icon-down.svg';
|
|
|
+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 VideoPlay from './component/video-play';
|
|
|
+import Tool, { ToolItem, ToolType } from './component/tool';
|
|
|
|
|
|
export default defineComponent({
|
|
|
- name: 'CoursewarePlay',
|
|
|
- setup() {
|
|
|
- return () => <div></div>
|
|
|
- }
|
|
|
-})
|
|
|
+ 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'
|
|
|
+ });
|
|
|
+ const setContainer = () => {
|
|
|
+ let min = Math.min(screen.width, screen.height);
|
|
|
+ let max = Math.max(screen.width, screen.height);
|
|
|
+ let width = min * (16 / 9);
|
|
|
+ if (width > max) {
|
|
|
+ parentContainer.width = '100vw';
|
|
|
+ return;
|
|
|
+ } else {
|
|
|
+ parentContainer.width = width + 'px';
|
|
|
+ }
|
|
|
+ };
|
|
|
+ const handleInit = (type = 0) => {
|
|
|
+ //设置容器16:9
|
|
|
+ setContainer();
|
|
|
+ // 横屏
|
|
|
+ postMessage(
|
|
|
+ {
|
|
|
+ api: 'setRequestedOrientation',
|
|
|
+ content: {
|
|
|
+ orientation: type
|
|
|
+ }
|
|
|
+ },
|
|
|
+ () => {
|
|
|
+ console.log(234);
|
|
|
+ }
|
|
|
+ );
|
|
|
+ // 头,包括返回箭头
|
|
|
+ // postMessage({
|
|
|
+ // api: 'setTitleBarVisibility',
|
|
|
+ // content: {
|
|
|
+ // status: type
|
|
|
+ // }
|
|
|
+ // })
|
|
|
+ // 安卓的状态栏
|
|
|
+ postMessage({
|
|
|
+ api: 'setStatusBarVisibility',
|
|
|
+ content: {
|
|
|
+ isVisibility: type
|
|
|
+ }
|
|
|
+ });
|
|
|
+ // 进入页面设置常量
|
|
|
+ postMessage({
|
|
|
+ api: 'keepScreenLongLight',
|
|
|
+ content: {
|
|
|
+ isOpenLight: type ? true : false
|
|
|
+ }
|
|
|
+ });
|
|
|
+ };
|
|
|
+ handleInit();
|
|
|
+ onUnmounted(() => {
|
|
|
+ handleInit(1);
|
|
|
+ window.removeEventListener('message', iframeHandle);
|
|
|
+ });
|
|
|
+
|
|
|
+ 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: '1',
|
|
|
+ name: '歌曲表演 大鹿',
|
|
|
+ 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'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: '2',
|
|
|
+ name: '知识 音的高低',
|
|
|
+ type: 'IMG',
|
|
|
+ content: 'https://gyt.ks3-cn-beijing.ksyuncs.com/courseware/1686815979899.png'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: '3',
|
|
|
+ name: '欣赏 永远在童话里',
|
|
|
+ type: 'IMG',
|
|
|
+ content: 'https://gyt.ks3-cn-beijing.ksyuncs.com/courseware/1686815979899.png'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: '4',
|
|
|
+ name: '唱歌 小红帽',
|
|
|
+ type: 'SONG',
|
|
|
+ content: '11707'
|
|
|
+ }
|
|
|
+ ];
|
|
|
+ data.itemList = data.knowledgePointList.map((m: any) => {
|
|
|
+ return {
|
|
|
+ ...m,
|
|
|
+ iframeRef: null,
|
|
|
+ videoEle: null,
|
|
|
+ autoPlay: false, //加载完成是否自动播放
|
|
|
+ isprepare: false, // 视频是否加载完成
|
|
|
+ isRender: false // 是否渲染了
|
|
|
+ };
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ // ifram事件处理
|
|
|
+ const iframeHandle = (ev: MessageEvent) => {
|
|
|
+ if (ev.data?.api === 'headerTogge') {
|
|
|
+ activeData.model =
|
|
|
+ ev.data.show || (ev.data.playState == 'play' ? false : true);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ onMounted(() => {
|
|
|
+ postMessage({
|
|
|
+ api: 'courseLoading',
|
|
|
+ content: {
|
|
|
+ show: false,
|
|
|
+ type: 'fullscreen'
|
|
|
+ }
|
|
|
+ });
|
|
|
+ getDetail();
|
|
|
+ window.addEventListener('message', iframeHandle);
|
|
|
+ });
|
|
|
+
|
|
|
+ const playRef = ref();
|
|
|
+ // 返回
|
|
|
+ const goback = () => {
|
|
|
+ try {
|
|
|
+ playRef.value?.handleOut();
|
|
|
+ } catch (error) {}
|
|
|
+ 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);
|
|
|
+ closeToast();
|
|
|
+ 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();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // 切换播放
|
|
|
+ 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);
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // 上一个知识点, 下一个知识点
|
|
|
+ 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();
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ 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 ||
|
|
|
+ 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} />
|
|
|
+ ) : (
|
|
|
+ <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} />
|
|
|
+ <span>课件</span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div
|
|
|
+ class={[
|
|
|
+ styles.fullBtn,
|
|
|
+ popupData.activeIndex == 0 && styles.btnsDisabled
|
|
|
+ ]}
|
|
|
+ onClick={() => handlePreAndNext('up')}>
|
|
|
+ <img src={iconUp} />
|
|
|
+ <span style={{ textAlign: 'center' }}>上一个</span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div
|
|
|
+ class={[
|
|
|
+ styles.fullBtn,
|
|
|
+ popupData.activeIndex == data.itemList.length - 1 &&
|
|
|
+ styles.btnsDisabled
|
|
|
+ ]}
|
|
|
+ onClick={() => handlePreAndNext('down')}>
|
|
|
+ <span style={{ textAlign: 'center' }}>下一个</span>
|
|
|
+ <img src={iconDown} />
|
|
|
+ </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>
|
|
|
+
|
|
|
+ <Popup
|
|
|
+ class={styles.popup}
|
|
|
+ style={{ background: 'rgba(0,0,0, 0.75)' }}
|
|
|
+ overlayClass={styles.overlayClass}
|
|
|
+ position="right"
|
|
|
+ round
|
|
|
+ v-model:show={popupData.open}
|
|
|
+ onClose={handleClosePopup}>
|
|
|
+ <Points
|
|
|
+ data={data.knowledgePointList}
|
|
|
+ tabActive={popupData.tabActive}
|
|
|
+ itemActive={popupData.itemActive}
|
|
|
+ onHandleSelect={(res: any) => {
|
|
|
+ popupData.open = false;
|
|
|
+ toggleMaterial(res.itemActive);
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ </Popup>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ }
|
|
|
+});
|