- 将所有图片路径从绝对路径改为使用 process.env.PUBLIC_URL - 修复 HomePage.tsx 中所有图片引用 - 修复 CoursePage.tsx 中所有图片引用 - 确保图片在 GitHub Pages 上正确加载 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 line
14 KiB
JSON
1 line
14 KiB
JSON
{"ast":null,"code":"import{useEffect,useRef,useState}from'react';export const useSectionScroll=function(){let options=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};const{duration=1800,// 默认1.8秒\neasing='cubic-bezier(0.4, 0, 0.2, 1)'// Apple风格缓动\n}=options;const[currentSection,setCurrentSection]=useState(0);const[isScrolling,setIsScrolling]=useState(false);const sectionsRef=useRef([]);const touchStartY=useRef(0);// 平滑滚动到指定section\nconst scrollToSection=index=>{if(index<0||index>=sectionsRef.current.length||isScrolling){return;}setIsScrolling(true);const targetSection=sectionsRef.current[index];if(targetSection){// 使用scrollIntoView实现平滑滚动\ntargetSection.scrollIntoView({behavior:'smooth',block:'start'});setCurrentSection(index);// 滚动完成后重置状态\nsetTimeout(()=>{setIsScrolling(false);},duration);}};// 处理滚轮事件\nconst handleWheel=e=>{if(isScrolling){e.preventDefault();return;}const currentSectionElement=sectionsRef.current[currentSection];if(!currentSectionElement)return;// 检查滚动事件是否发生在当前section内\nconst target=e.target;if(!currentSectionElement.contains(target))return;const{scrollTop,scrollHeight,clientHeight}=currentSectionElement;const isAtTop=scrollTop===0;const isAtBottom=Math.abs(scrollHeight-clientHeight-scrollTop)<1;// 向下滚动\nif(e.deltaY>0){// 只有在section底部时才阻止默认行为并切换\nif(isAtBottom&¤tSection<sectionsRef.current.length-1){e.preventDefault();scrollToSection(currentSection+1);}// 否则允许section内部正常滚动\n}// 向上滚动\nelse if(e.deltaY<0){// 只有在section顶部时才阻止默认行为并切换\nif(isAtTop&¤tSection>0){e.preventDefault();scrollToSection(currentSection-1);}// 否则允许section内部正常滚动\n}};// 处理触摸事件(移动端)\nconst handleTouchStart=e=>{touchStartY.current=e.touches[0].clientY;};const handleTouchMove=e=>{if(isScrolling){e.preventDefault();return;}const currentSectionElement=sectionsRef.current[currentSection];if(!currentSectionElement)return;const touchEndY=e.touches[0].clientY;const deltaY=touchStartY.current-touchEndY;const{scrollTop,scrollHeight,clientHeight}=currentSectionElement;const isAtTop=scrollTop===0;const isAtBottom=Math.abs(scrollHeight-clientHeight-scrollTop)<1;// 向上滑动(手指向上移动)\nif(deltaY>50){if(isAtBottom&¤tSection<sectionsRef.current.length-1){e.preventDefault();scrollToSection(currentSection+1);touchStartY.current=touchEndY;}}// 向下滑动(手指向下移动)\nelse if(deltaY<-50){if(isAtTop&¤tSection>0){e.preventDefault();scrollToSection(currentSection-1);touchStartY.current=touchEndY;}}};// 处理键盘事件\nconst handleKeyDown=e=>{if(isScrolling)return;switch(e.key){case'ArrowDown':case'PageDown':if(currentSection<sectionsRef.current.length-1){e.preventDefault();scrollToSection(currentSection+1);}break;case'ArrowUp':case'PageUp':if(currentSection>0){e.preventDefault();scrollToSection(currentSection-1);}break;case'Home':e.preventDefault();scrollToSection(0);break;case'End':e.preventDefault();scrollToSection(sectionsRef.current.length-1);break;}};useEffect(()=>{// 绑定事件监听\nwindow.addEventListener('wheel',handleWheel,{passive:false});window.addEventListener('touchstart',handleTouchStart,{passive:false});window.addEventListener('touchmove',handleTouchMove,{passive:false});window.addEventListener('keydown',handleKeyDown);return()=>{window.removeEventListener('wheel',handleWheel);window.removeEventListener('touchstart',handleTouchStart);window.removeEventListener('touchmove',handleTouchMove);window.removeEventListener('keydown',handleKeyDown);};},[currentSection,isScrolling]);// 注册section元素\nconst registerSection=(element,index)=>{if(element){sectionsRef.current[index]=element;}};return{currentSection,scrollToSection,registerSection,isScrolling};};","map":{"version":3,"names":["useEffect","useRef","useState","useSectionScroll","options","arguments","length","undefined","duration","easing","currentSection","setCurrentSection","isScrolling","setIsScrolling","sectionsRef","touchStartY","scrollToSection","index","current","targetSection","scrollIntoView","behavior","block","setTimeout","handleWheel","e","preventDefault","currentSectionElement","target","contains","scrollTop","scrollHeight","clientHeight","isAtTop","isAtBottom","Math","abs","deltaY","handleTouchStart","touches","clientY","handleTouchMove","touchEndY","handleKeyDown","key","window","addEventListener","passive","removeEventListener","registerSection","element"],"sources":["/Users/apple/Documents/cursor/Web课件/AI课/education_web_多Agent协作系统/src/hooks/useSectionScroll.ts"],"sourcesContent":["import { useEffect, useRef, useState } from 'react';\n\ninterface UseSectionScrollOptions {\n duration?: number; // 滚动动画持续时间(毫秒)\n easing?: string; // 缓动函数\n}\n\nexport const useSectionScroll = (options: UseSectionScrollOptions = {}) => {\n const {\n duration = 1800, // 默认1.8秒\n easing = 'cubic-bezier(0.4, 0, 0.2, 1)' // Apple风格缓动\n } = options;\n\n const [currentSection, setCurrentSection] = useState(0);\n const [isScrolling, setIsScrolling] = useState(false);\n const sectionsRef = useRef<HTMLElement[]>([]);\n const touchStartY = useRef(0);\n\n // 平滑滚动到指定section\n const scrollToSection = (index: number) => {\n if (index < 0 || index >= sectionsRef.current.length || isScrolling) {\n return;\n }\n\n setIsScrolling(true);\n const targetSection = sectionsRef.current[index];\n\n if (targetSection) {\n // 使用scrollIntoView实现平滑滚动\n targetSection.scrollIntoView({\n behavior: 'smooth',\n block: 'start'\n });\n\n setCurrentSection(index);\n\n // 滚动完成后重置状态\n setTimeout(() => {\n setIsScrolling(false);\n }, duration);\n }\n };\n\n // 处理滚轮事件\n const handleWheel = (e: WheelEvent) => {\n if (isScrolling) {\n e.preventDefault();\n return;\n }\n\n const currentSectionElement = sectionsRef.current[currentSection];\n if (!currentSectionElement) return;\n\n // 检查滚动事件是否发生在当前section内\n const target = e.target as HTMLElement;\n if (!currentSectionElement.contains(target)) return;\n\n const { scrollTop, scrollHeight, clientHeight } = currentSectionElement;\n const isAtTop = scrollTop === 0;\n const isAtBottom = Math.abs(scrollHeight - clientHeight - scrollTop) < 1;\n\n // 向下滚动\n if (e.deltaY > 0) {\n // 只有在section底部时才阻止默认行为并切换\n if (isAtBottom && currentSection < sectionsRef.current.length - 1) {\n e.preventDefault();\n scrollToSection(currentSection + 1);\n }\n // 否则允许section内部正常滚动\n }\n // 向上滚动\n else if (e.deltaY < 0) {\n // 只有在section顶部时才阻止默认行为并切换\n if (isAtTop && currentSection > 0) {\n e.preventDefault();\n scrollToSection(currentSection - 1);\n }\n // 否则允许section内部正常滚动\n }\n };\n\n // 处理触摸事件(移动端)\n const handleTouchStart = (e: TouchEvent) => {\n touchStartY.current = e.touches[0].clientY;\n };\n\n const handleTouchMove = (e: TouchEvent) => {\n if (isScrolling) {\n e.preventDefault();\n return;\n }\n\n const currentSectionElement = sectionsRef.current[currentSection];\n if (!currentSectionElement) return;\n\n const touchEndY = e.touches[0].clientY;\n const deltaY = touchStartY.current - touchEndY;\n\n const { scrollTop, scrollHeight, clientHeight } = currentSectionElement;\n const isAtTop = scrollTop === 0;\n const isAtBottom = Math.abs(scrollHeight - clientHeight - scrollTop) < 1;\n\n // 向上滑动(手指向上移动)\n if (deltaY > 50) {\n if (isAtBottom && currentSection < sectionsRef.current.length - 1) {\n e.preventDefault();\n scrollToSection(currentSection + 1);\n touchStartY.current = touchEndY;\n }\n }\n // 向下滑动(手指向下移动)\n else if (deltaY < -50) {\n if (isAtTop && currentSection > 0) {\n e.preventDefault();\n scrollToSection(currentSection - 1);\n touchStartY.current = touchEndY;\n }\n }\n };\n\n // 处理键盘事件\n const handleKeyDown = (e: KeyboardEvent) => {\n if (isScrolling) return;\n\n switch (e.key) {\n case 'ArrowDown':\n case 'PageDown':\n if (currentSection < sectionsRef.current.length - 1) {\n e.preventDefault();\n scrollToSection(currentSection + 1);\n }\n break;\n case 'ArrowUp':\n case 'PageUp':\n if (currentSection > 0) {\n e.preventDefault();\n scrollToSection(currentSection - 1);\n }\n break;\n case 'Home':\n e.preventDefault();\n scrollToSection(0);\n break;\n case 'End':\n e.preventDefault();\n scrollToSection(sectionsRef.current.length - 1);\n break;\n }\n };\n\n useEffect(() => {\n // 绑定事件监听\n window.addEventListener('wheel', handleWheel, { passive: false });\n window.addEventListener('touchstart', handleTouchStart, { passive: false });\n window.addEventListener('touchmove', handleTouchMove, { passive: false });\n window.addEventListener('keydown', handleKeyDown);\n\n return () => {\n window.removeEventListener('wheel', handleWheel);\n window.removeEventListener('touchstart', handleTouchStart);\n window.removeEventListener('touchmove', handleTouchMove);\n window.removeEventListener('keydown', handleKeyDown);\n };\n }, [currentSection, isScrolling]);\n\n // 注册section元素\n const registerSection = (element: HTMLElement | null, index: number) => {\n if (element) {\n sectionsRef.current[index] = element;\n }\n };\n\n return {\n currentSection,\n scrollToSection,\n registerSection,\n isScrolling\n };\n};\n"],"mappings":"AAAA,OAASA,SAAS,CAAEC,MAAM,CAAEC,QAAQ,KAAQ,OAAO,CAOnD,MAAO,MAAM,CAAAC,gBAAgB,CAAG,QAAAA,CAAA,CAA2C,IAA1C,CAAAC,OAAgC,CAAAC,SAAA,CAAAC,MAAA,IAAAD,SAAA,MAAAE,SAAA,CAAAF,SAAA,IAAG,CAAC,CAAC,CACpE,KAAM,CACJG,QAAQ,CAAG,IAAI,CAAE;AACjBC,MAAM,CAAG,8BAA+B;AAC1C,CAAC,CAAGL,OAAO,CAEX,KAAM,CAACM,cAAc,CAAEC,iBAAiB,CAAC,CAAGT,QAAQ,CAAC,CAAC,CAAC,CACvD,KAAM,CAACU,WAAW,CAAEC,cAAc,CAAC,CAAGX,QAAQ,CAAC,KAAK,CAAC,CACrD,KAAM,CAAAY,WAAW,CAAGb,MAAM,CAAgB,EAAE,CAAC,CAC7C,KAAM,CAAAc,WAAW,CAAGd,MAAM,CAAC,CAAC,CAAC,CAE7B;AACA,KAAM,CAAAe,eAAe,CAAIC,KAAa,EAAK,CACzC,GAAIA,KAAK,CAAG,CAAC,EAAIA,KAAK,EAAIH,WAAW,CAACI,OAAO,CAACZ,MAAM,EAAIM,WAAW,CAAE,CACnE,OACF,CAEAC,cAAc,CAAC,IAAI,CAAC,CACpB,KAAM,CAAAM,aAAa,CAAGL,WAAW,CAACI,OAAO,CAACD,KAAK,CAAC,CAEhD,GAAIE,aAAa,CAAE,CACjB;AACAA,aAAa,CAACC,cAAc,CAAC,CAC3BC,QAAQ,CAAE,QAAQ,CAClBC,KAAK,CAAE,OACT,CAAC,CAAC,CAEFX,iBAAiB,CAACM,KAAK,CAAC,CAExB;AACAM,UAAU,CAAC,IAAM,CACfV,cAAc,CAAC,KAAK,CAAC,CACvB,CAAC,CAAEL,QAAQ,CAAC,CACd,CACF,CAAC,CAED;AACA,KAAM,CAAAgB,WAAW,CAAIC,CAAa,EAAK,CACrC,GAAIb,WAAW,CAAE,CACfa,CAAC,CAACC,cAAc,CAAC,CAAC,CAClB,OACF,CAEA,KAAM,CAAAC,qBAAqB,CAAGb,WAAW,CAACI,OAAO,CAACR,cAAc,CAAC,CACjE,GAAI,CAACiB,qBAAqB,CAAE,OAE5B;AACA,KAAM,CAAAC,MAAM,CAAGH,CAAC,CAACG,MAAqB,CACtC,GAAI,CAACD,qBAAqB,CAACE,QAAQ,CAACD,MAAM,CAAC,CAAE,OAE7C,KAAM,CAAEE,SAAS,CAAEC,YAAY,CAAEC,YAAa,CAAC,CAAGL,qBAAqB,CACvE,KAAM,CAAAM,OAAO,CAAGH,SAAS,GAAK,CAAC,CAC/B,KAAM,CAAAI,UAAU,CAAGC,IAAI,CAACC,GAAG,CAACL,YAAY,CAAGC,YAAY,CAAGF,SAAS,CAAC,CAAG,CAAC,CAExE;AACA,GAAIL,CAAC,CAACY,MAAM,CAAG,CAAC,CAAE,CAChB;AACA,GAAIH,UAAU,EAAIxB,cAAc,CAAGI,WAAW,CAACI,OAAO,CAACZ,MAAM,CAAG,CAAC,CAAE,CACjEmB,CAAC,CAACC,cAAc,CAAC,CAAC,CAClBV,eAAe,CAACN,cAAc,CAAG,CAAC,CAAC,CACrC,CACA;AACF,CACA;AAAA,IACK,IAAIe,CAAC,CAACY,MAAM,CAAG,CAAC,CAAE,CACrB;AACA,GAAIJ,OAAO,EAAIvB,cAAc,CAAG,CAAC,CAAE,CACjCe,CAAC,CAACC,cAAc,CAAC,CAAC,CAClBV,eAAe,CAACN,cAAc,CAAG,CAAC,CAAC,CACrC,CACA;AACF,CACF,CAAC,CAED;AACA,KAAM,CAAA4B,gBAAgB,CAAIb,CAAa,EAAK,CAC1CV,WAAW,CAACG,OAAO,CAAGO,CAAC,CAACc,OAAO,CAAC,CAAC,CAAC,CAACC,OAAO,CAC5C,CAAC,CAED,KAAM,CAAAC,eAAe,CAAIhB,CAAa,EAAK,CACzC,GAAIb,WAAW,CAAE,CACfa,CAAC,CAACC,cAAc,CAAC,CAAC,CAClB,OACF,CAEA,KAAM,CAAAC,qBAAqB,CAAGb,WAAW,CAACI,OAAO,CAACR,cAAc,CAAC,CACjE,GAAI,CAACiB,qBAAqB,CAAE,OAE5B,KAAM,CAAAe,SAAS,CAAGjB,CAAC,CAACc,OAAO,CAAC,CAAC,CAAC,CAACC,OAAO,CACtC,KAAM,CAAAH,MAAM,CAAGtB,WAAW,CAACG,OAAO,CAAGwB,SAAS,CAE9C,KAAM,CAAEZ,SAAS,CAAEC,YAAY,CAAEC,YAAa,CAAC,CAAGL,qBAAqB,CACvE,KAAM,CAAAM,OAAO,CAAGH,SAAS,GAAK,CAAC,CAC/B,KAAM,CAAAI,UAAU,CAAGC,IAAI,CAACC,GAAG,CAACL,YAAY,CAAGC,YAAY,CAAGF,SAAS,CAAC,CAAG,CAAC,CAExE;AACA,GAAIO,MAAM,CAAG,EAAE,CAAE,CACf,GAAIH,UAAU,EAAIxB,cAAc,CAAGI,WAAW,CAACI,OAAO,CAACZ,MAAM,CAAG,CAAC,CAAE,CACjEmB,CAAC,CAACC,cAAc,CAAC,CAAC,CAClBV,eAAe,CAACN,cAAc,CAAG,CAAC,CAAC,CACnCK,WAAW,CAACG,OAAO,CAAGwB,SAAS,CACjC,CACF,CACA;AAAA,IACK,IAAIL,MAAM,CAAG,CAAC,EAAE,CAAE,CACrB,GAAIJ,OAAO,EAAIvB,cAAc,CAAG,CAAC,CAAE,CACjCe,CAAC,CAACC,cAAc,CAAC,CAAC,CAClBV,eAAe,CAACN,cAAc,CAAG,CAAC,CAAC,CACnCK,WAAW,CAACG,OAAO,CAAGwB,SAAS,CACjC,CACF,CACF,CAAC,CAED;AACA,KAAM,CAAAC,aAAa,CAAIlB,CAAgB,EAAK,CAC1C,GAAIb,WAAW,CAAE,OAEjB,OAAQa,CAAC,CAACmB,GAAG,EACX,IAAK,WAAW,CAChB,IAAK,UAAU,CACb,GAAIlC,cAAc,CAAGI,WAAW,CAACI,OAAO,CAACZ,MAAM,CAAG,CAAC,CAAE,CACnDmB,CAAC,CAACC,cAAc,CAAC,CAAC,CAClBV,eAAe,CAACN,cAAc,CAAG,CAAC,CAAC,CACrC,CACA,MACF,IAAK,SAAS,CACd,IAAK,QAAQ,CACX,GAAIA,cAAc,CAAG,CAAC,CAAE,CACtBe,CAAC,CAACC,cAAc,CAAC,CAAC,CAClBV,eAAe,CAACN,cAAc,CAAG,CAAC,CAAC,CACrC,CACA,MACF,IAAK,MAAM,CACTe,CAAC,CAACC,cAAc,CAAC,CAAC,CAClBV,eAAe,CAAC,CAAC,CAAC,CAClB,MACF,IAAK,KAAK,CACRS,CAAC,CAACC,cAAc,CAAC,CAAC,CAClBV,eAAe,CAACF,WAAW,CAACI,OAAO,CAACZ,MAAM,CAAG,CAAC,CAAC,CAC/C,MACJ,CACF,CAAC,CAEDN,SAAS,CAAC,IAAM,CACd;AACA6C,MAAM,CAACC,gBAAgB,CAAC,OAAO,CAAEtB,WAAW,CAAE,CAAEuB,OAAO,CAAE,KAAM,CAAC,CAAC,CACjEF,MAAM,CAACC,gBAAgB,CAAC,YAAY,CAAER,gBAAgB,CAAE,CAAES,OAAO,CAAE,KAAM,CAAC,CAAC,CAC3EF,MAAM,CAACC,gBAAgB,CAAC,WAAW,CAAEL,eAAe,CAAE,CAAEM,OAAO,CAAE,KAAM,CAAC,CAAC,CACzEF,MAAM,CAACC,gBAAgB,CAAC,SAAS,CAAEH,aAAa,CAAC,CAEjD,MAAO,IAAM,CACXE,MAAM,CAACG,mBAAmB,CAAC,OAAO,CAAExB,WAAW,CAAC,CAChDqB,MAAM,CAACG,mBAAmB,CAAC,YAAY,CAAEV,gBAAgB,CAAC,CAC1DO,MAAM,CAACG,mBAAmB,CAAC,WAAW,CAAEP,eAAe,CAAC,CACxDI,MAAM,CAACG,mBAAmB,CAAC,SAAS,CAAEL,aAAa,CAAC,CACtD,CAAC,CACH,CAAC,CAAE,CAACjC,cAAc,CAAEE,WAAW,CAAC,CAAC,CAEjC;AACA,KAAM,CAAAqC,eAAe,CAAGA,CAACC,OAA2B,CAAEjC,KAAa,GAAK,CACtE,GAAIiC,OAAO,CAAE,CACXpC,WAAW,CAACI,OAAO,CAACD,KAAK,CAAC,CAAGiC,OAAO,CACtC,CACF,CAAC,CAED,MAAO,CACLxC,cAAc,CACdM,eAAe,CACfiC,eAAe,CACfrC,WACF,CAAC,CACH,CAAC","ignoreList":[]},"metadata":{},"sourceType":"module","externalDependencies":[]} |