فهرست منبع

同步 部分浏览器 播放进度 回退问题

黄琪勇 9 ماه پیش
والد
کامیت
634e6d945d
2فایلهای تغییر یافته به همراه22 افزوده شده و 9 حذف شده
  1. 20 9
      src/page-instrument/view-detail/smoothAnimation/index.ts
  2. 2 0
      src/state.ts

+ 20 - 9
src/page-instrument/view-detail/smoothAnimation/index.ts

@@ -26,7 +26,9 @@ type smoothAnimationType = {
    batePos: pointsPosType
    pointsPos: pointsPosType
    translateXNum: number
-   aveSpeed: number
+   aveSpeed: number,
+   pageTurnLock: boolean
+   oldCurrentTime: number
 }
 
 let _numberOfSegments = 56 // 中间切割线的个数
@@ -50,7 +52,9 @@ export const smoothAnimationState = {
    batePos: [], // times 直接转换的数组
    pointsPos: [], // 筛选之后的点坐标数组
    translateXNum: 0, // 当前谱面的translateX的距离   谱面的位置信息 由translateX和scrollLeft的偏移一起决定
-   aveSpeed: 0 // 谱面的一帧的平均速度
+   aveSpeed: 0, // 谱面的一帧的平均速度
+   pageTurnLock: false,
+   oldCurrentTime: 0
 } as smoothAnimationType
 
 // 监听显示与隐藏
@@ -151,19 +155,27 @@ export function destroySmoothAnimation() {
       batePos: [],
       pointsPos: [],
       translateXNum: 0,
-      aveSpeed: 0
+      aveSpeed: 0,
+      pageTurnLock: false,
+      oldCurrentTime: 0
    })
 }
 
 /**
  * 根据播放时间进度移动处理
+ * isIgnoreFilter  忽略这种 判断,因为有些只需要谱面移动
  */
-export function moveSmoothAnimationByPlayTime(time?: number) {
+export function moveSmoothAnimationByPlayTime(time?: number, isIgnoreFilter = false) {
    // 暂停之后不进行移动了
    if (state.playState === "paused") {
       return
    }
    const currentTime = time || getAudioCurrentTime()
+   // 某些浏览器 音频暂停后返回的时间会倒退,把这种时间过滤掉
+   if(currentTime < smoothAnimationState.oldCurrentTime && !isIgnoreFilter) {
+      return
+   }
+   smoothAnimationState.oldCurrentTime = currentTime
    if (currentTime <= state.fixtime) return
    if (currentTime > state.times.last()?.endtime) return
    // 当休止小节,可能当前音符在谱面上没有实际的音符(没有bbox),所以往后找谱面上有的音符
@@ -221,9 +233,8 @@ export function moveSmoothAnimation(progress: number, activeIndex: number, isMov
 /**
  * 谱面翻页逻辑
  */
-let pageTurnLock = false
 function pageTurn_osmd(nowPointsPos: pointsPosType[0]) {
-   if (pageTurnLock) return
+   if (smoothAnimationState.pageTurnLock) return
    // 视口宽度
    const clientWidth = smoothAnimationState.osdmScrollDomWith
    let { left, right } = smoothAnimationState.smoothBotDom!.getBoundingClientRect()
@@ -243,7 +254,7 @@ function pageTurn_osmd(nowPointsPos: pointsPosType[0]) {
          if (smoothAnimationState.translateXNum > maxTranslateXNum) {
             smoothAnimationState.translateXNum = maxTranslateXNum
          }
-         pageTurnLock = true
+         smoothAnimationState.pageTurnLock = true
          moveTranslateXNum(smoothAnimationState.translateXNum)
       }
    }
@@ -330,7 +341,7 @@ export function moveTranslateXNum(translateXNum: number) {
       smoothAnimationState.osmdCanvasPageDom && (smoothAnimationState.osmdCanvasPageDom.style.transition = "")
       smoothAnimationState.selectionBoxDom && (smoothAnimationState.selectionBoxDom.style.transition = "")
       smoothAnimationState.selectionBgBoxDom && (smoothAnimationState.selectionBgBoxDom.style.transition = "")
-      pageTurnLock = false
+      smoothAnimationState.pageTurnLock = false
    } else {
       smoothAnimationState.osmdCanvasPageDom && (smoothAnimationState.osmdCanvasPageDom.style.transform = `translateX(-${translateXNum}px)`)
       smoothAnimationState.selectionBoxDom && (smoothAnimationState.selectionBoxDom.style.transform = `translateX(-${translateXNum}px)`)
@@ -357,7 +368,7 @@ function createSmoothAnimation() {
    const osmdCanvasPageDom = document.querySelector("#osmdCanvasPage1") as HTMLElement
    smoothAnimationState.osmdCanvasPageDom = osmdCanvasPageDom
    smoothAnimationState.osmdCanvasPageDom.addEventListener("transitionend", () => {
-      pageTurnLock = false
+      smoothAnimationState.pageTurnLock = false
    })
    // selectionBox
    setTimeout(() => {

+ 2 - 0
src/state.ts

@@ -779,6 +779,8 @@ const handlePlaying = () => {
 export const skipNotePlay = async (itemIndex: number, isStart = false, handType?: string) => {
   // 纯预览模式,练习、评测作业模式,禁止手动点击跳转音符
   if (state.isPreView) return;
+  // 点击或者重播的时候清除一行谱的时间信息
+  state.isSingleLine && (smoothAnimationState.oldCurrentTime = 0)
   if (handType === 'manual' && (query.workRecord || query.evaluatingRecord)) return;
   const item = state.times[itemIndex];
   // 如果是选段状态,可以点击段落范围内的音符,从当前音符开始播放,如果不是段落内的音符,直接return