From eb593ef59099c37e14dcbe54a716678c099a4b25 Mon Sep 17 00:00:00 2001 From: mozzie Date: Wed, 1 Mar 2023 11:18:24 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=97=B6=E9=97=B4=E7=BA=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Course/components/Recommand/index.less | 5 + .../Course/components/Recommand/index.tsx | 47 +++++++ .../Course/components/Timeline}/index.less | 3 +- .../Course/components/Timeline}/index.tsx | 9 +- apps/web-main/src/view/Course/index.less | 47 ++++--- apps/web-main/src/view/Course/index.tsx | 116 +++++++++--------- apps/web-main/src/view/Course/mock.ts | 24 ---- 7 files changed, 146 insertions(+), 105 deletions(-) create mode 100644 apps/web-main/src/view/Course/components/Recommand/index.less create mode 100644 apps/web-main/src/view/Course/components/Recommand/index.tsx rename apps/web-main/src/{components/TimeScroll => view/Course/components/Timeline}/index.less (97%) rename apps/web-main/src/{components/TimeScroll => view/Course/components/Timeline}/index.tsx (97%) diff --git a/apps/web-main/src/view/Course/components/Recommand/index.less b/apps/web-main/src/view/Course/components/Recommand/index.less new file mode 100644 index 0000000..2eead3b --- /dev/null +++ b/apps/web-main/src/view/Course/components/Recommand/index.less @@ -0,0 +1,5 @@ +.recommends { + display: grid; + grid-template-columns: 1fr 1.5fr 1fr; + grid-column-gap: 20px; +} diff --git a/apps/web-main/src/view/Course/components/Recommand/index.tsx b/apps/web-main/src/view/Course/components/Recommand/index.tsx new file mode 100644 index 0000000..eef235b --- /dev/null +++ b/apps/web-main/src/view/Course/components/Recommand/index.tsx @@ -0,0 +1,47 @@ +import { useState } from "react"; +import BsCard from "../../../../components/Card"; +import "./index.less"; + +export const recommendListDefault = [ + { + imgUrl: + "https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/a8c8cdb109cb051163646151a4a5083b.png~tplv-uwbnlip3yd-webp.webp", + title: "这个非常OK啊", + meta: { + desc: "推荐内容推荐内容推荐内容推荐内容推荐内容推荐内容推荐内容", + action: "Learn", + }, + }, + { + imgUrl: + "https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/e278888093bef8910e829486fb45dd69.png~tplv-uwbnlip3yd-webp.webp", + title: "这个非常OK啊", + meta: { + desc: "推荐内容推荐内容推荐内容推荐内容推荐内容推荐内容推荐内容", + action: "Learn", + }, + }, + { + imgUrl: + "https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/a8c8cdb109cb051163646151a4a5083b.png~tplv-uwbnlip3yd-webp.webp", + title: "这个非常OK啊", + meta: { + desc: "推荐内容推荐内容推荐内容推荐内容推荐内容推荐内容推荐内容", + action: "Learn", + }, + }, +]; + +function Recommends() { + const [recommendList, setRecommendList] = useState(recommendListDefault); + + return ( +
+ {recommendList.map((item, index) => ( + + ))} +
+ ); +} + +export default Recommends; diff --git a/apps/web-main/src/components/TimeScroll/index.less b/apps/web-main/src/view/Course/components/Timeline/index.less similarity index 97% rename from apps/web-main/src/components/TimeScroll/index.less rename to apps/web-main/src/view/Course/components/Timeline/index.less index eb66a7b..782f5ba 100644 --- a/apps/web-main/src/components/TimeScroll/index.less +++ b/apps/web-main/src/view/Course/components/Timeline/index.less @@ -1,5 +1,4 @@ -.timescroll { - position: relative; +.timeline { width: 40px; .caret { diff --git a/apps/web-main/src/components/TimeScroll/index.tsx b/apps/web-main/src/view/Course/components/Timeline/index.tsx similarity index 97% rename from apps/web-main/src/components/TimeScroll/index.tsx rename to apps/web-main/src/view/Course/components/Timeline/index.tsx index 233310b..f105571 100644 --- a/apps/web-main/src/components/TimeScroll/index.tsx +++ b/apps/web-main/src/view/Course/components/Timeline/index.tsx @@ -33,7 +33,7 @@ const filterYearOnce = (data: any[]) => { }); }; -function TimeScroll(props: IProps) { +function Timeline(props: IProps) { const [cursorStatic, setCursorStatic] = useState({ top: -4, color: "var(--color-fill-4)", @@ -43,6 +43,7 @@ function TimeScroll(props: IProps) { color: "var(--color-border-3)", }); const [intervalPixel, setIntervalPixel] = useState(1); + const [timelineData, setTimelineData] = useState(filterYearOnce(props.data)); const cursorActiveRef = useRef(null); const cursorStaticRef = useRef(null); const orbitRef = useRef(null); @@ -79,8 +80,6 @@ function TimeScroll(props: IProps) { }); }, [cursorStatic.top]); - const [timelineData, setTimelineData] = useState(filterYearOnce(props.data)); - useEffect(() => { if (props.data) { setTimelineData(filterYearOnce(props.data)); @@ -104,7 +103,7 @@ function TimeScroll(props: IProps) { return (
@@ -157,4 +156,4 @@ function TimeScroll(props: IProps) { ); } -export default TimeScroll; +export default Timeline; diff --git a/apps/web-main/src/view/Course/index.less b/apps/web-main/src/view/Course/index.less index 18d408d..c6ef5b5 100644 --- a/apps/web-main/src/view/Course/index.less +++ b/apps/web-main/src/view/Course/index.less @@ -3,30 +3,21 @@ flex-direction: column; padding: 100px 0 0 0; height: 100vh; - .recommends { - display: grid; - grid-template-columns: 1fr 1.5fr 1fr; - grid-column-gap: 20px; - } .action-bar { - padding: 40px 0 20px 0; - display: flex; - align-items: center; - justify-content: flex-end; - .table-action { - line-height: 1; - color: var(--color-text-2); - .xicon { - display: initial; - } + margin-bottom: 20px; + text-align: right; + line-height: 1; + color: var(--color-text-2); + .xicon { + display: initial; } } - .timeline { + .thumbnail-timeline { flex: 1; position: relative; - .thumbnail { + .thumbnail-container { position: absolute; top: 0; left: 0; @@ -52,7 +43,7 @@ display: grid; grid-column-gap: 10px; grid-row-gap: 10px; - grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); + .bs-card { border-radius: 3px; .cover { @@ -64,11 +55,29 @@ } } } + + &.table { + grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); + } + &.tab { + grid-template-columns: 1fr; + .bs-card { + border-radius: 3px; + .cover { + height: 330px; + } + .mask { + p { + font-size: 15px; + } + } + } + } } } } } - .timescroll { + .timeline-container { position: absolute; right: 0; top: 0; diff --git a/apps/web-main/src/view/Course/index.tsx b/apps/web-main/src/view/Course/index.tsx index 00b8031..b713e58 100644 --- a/apps/web-main/src/view/Course/index.tsx +++ b/apps/web-main/src/view/Course/index.tsx @@ -11,25 +11,25 @@ import { Menu, } from "@arco-design/web-react"; import BsCard from "../../components/Card"; -import TimeScroll, { IOnScrollParam } from "../../components/TimeScroll"; +import Timeline, { IOnScrollParam } from "./components/Timeline"; import Tab20Regular from "@ricons/fluent/Tab20Regular"; import Table20Regular from "@ricons/fluent/Table20Regular"; import Filter20Regular from "@ricons/fluent/Filter20Regular"; import { useRef, useState } from "react"; -import { recommendListDefault, courseTimeListDefault } from "./mock"; +import { courseTimeListDefault } from "./mock"; import { Icon } from "@ricons/utils"; export default function Index() { - const scrollContainerRef = useRef(null); - const ratioRef = useRef(1); - const [timescroll, setTimescroll] = useState({ + const thumbnailRef = useRef(null); + const scale = useRef(1); // thumbnail / timeline 高度比例 + const [timeline, setTimeline] = useState({ top: -4, }); const dropList = ( - 全部 - 最新的 + 升序 + 降序 ); @@ -38,88 +38,94 @@ export default function Index() { key: "tab", icon: , active: false, - tip: "单格排列", + tip: "使用大缩略图显示单个项目", + gridClass: "tab", }, { key: "table", icon: , active: true, - tip: "缩略", + tip: "列出更多项目", + gridClass: "table", }, ]); - const [recommendList, setRecommendList] = useState(recommendListDefault); - const [courseTimeList, setCourseTimeList] = useState(courseTimeListDefault); const onClickActionItem = (action: any) => { setActions((p) => p.map((a) => ({ ...a, active: a.key === action.key }))); }; - const onTimeScroll = (p: IOnScrollParam) => { + /** + * 右侧时间线滚动 + */ + const onTimelineScroll = (p: IOnScrollParam) => { const { top, height } = p; //左侧区域高度 - const { scrollHeight, clientHeight } = scrollContainerRef.current!; - ratioRef.current = (scrollHeight - clientHeight) / height; - scrollContainerRef.current!.scrollTop = top * ratioRef.current; + const { scrollHeight, clientHeight } = thumbnailRef.current!; + scale.current = (scrollHeight - clientHeight) / height; + thumbnailRef.current!.scrollTop = top * scale.current; }; - const onScroll = () => { - const { scrollHeight, scrollTop } = scrollContainerRef.current!; + /** + * 左侧缩略图预览区域滚动 + */ + const onThumbnailScroll = () => { + const { scrollHeight, scrollTop } = thumbnailRef.current!; const isTop = scrollTop === 0; const isBottom = scrollTop === scrollHeight; - const top = scrollTop / ratioRef.current; - setTimescroll({ top: isTop ? -4 : top }); + const top = isTop ? -4 : scrollTop / scale.current; // 修正顶部 + setTimeline({ top }); }; return (
-
- {recommendList.map((item, index) => ( - - ))} -
-
-
- - {actions.map((action) => ( - -
+ + ))} + +
-
-
-
+
+
+
{courseTimeList.map((item, index) => (
{item.year}年{item.month}月
{item.data.length} 个视频
-
+
a.active)?.gridClass}`} + > {item.data.map((d: any) => ( ))} @@ -128,11 +134,11 @@ export default function Index() { ))}
-
diff --git a/apps/web-main/src/view/Course/mock.ts b/apps/web-main/src/view/Course/mock.ts index 63e7af0..21464c7 100644 --- a/apps/web-main/src/view/Course/mock.ts +++ b/apps/web-main/src/view/Course/mock.ts @@ -1,29 +1,5 @@ import dayjs from "dayjs"; -export const recommendListDefault = [ - { - imgUrl: - "https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/a8c8cdb109cb051163646151a4a5083b.png~tplv-uwbnlip3yd-webp.webp", - title: "这个非常OK啊", - desc: "推荐内容推荐内容推荐内容推荐内容推荐内容推荐内容推荐内容", - action: "开始学习", - }, - { - imgUrl: - "https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/e278888093bef8910e829486fb45dd69.png~tplv-uwbnlip3yd-webp.webp", - title: "这个非常OK啊", - desc: "推荐内容推荐内容推荐内容推荐内容推荐内容推荐内容推荐内容", - action: "开始学习", - }, - { - imgUrl: - "https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/a8c8cdb109cb051163646151a4a5083b.png~tplv-uwbnlip3yd-webp.webp", - title: "这个非常OK啊", - desc: "推荐内容推荐内容推荐内容推荐内容推荐内容推荐内容推荐内容", - action: "开始学习", - }, -]; - export const courseTimeList = [ { title: "这个非常OK啊1",