在按键上应用滚动动画,使其与单击鼠标相同

时间:2019-11-18 10:20:39

标签: javascript css ecmascript-6 keyboard-events animateplus

我有一个水平分布的页面,可以通过单击鼠标或按空格键向上翻页/向下翻页向左箭头/向右滚动箭头 Home / End 键。

使用Animate Plus对通过鼠标单击激活的滚动进行动画处理。

用按键滚动时,我如何拥有完全相同的动画?

由于我的代码无法在Stack Overflow的代码段中运行,因此我将其发布到了Codepen。

  

这是我完整的代码:

     

https://codepen.io/boletrone/pen/MWWZrPQ

下面是我的JavaScript代码:

import animate from "https://cdn.jsdelivr.net/npm/animateplus@2/animateplus.js"

// Scroll on key presses
// =====================

let scrollPosition = 0
const maxScrollPosition = document.body.scrollWidth - window.innerWidth
const container = document.scrollingElement

window.onload = () => {
  document.body.onkeydown = event => {
    switch (event.code) {
      case "Space":
      case "PageDown":
      case "ArrowRight":
      case "ArrowDown": {
        event.preventDefault()

        if (scrollPosition === maxScrollPosition) return // If at the end, return
        scrollPosition += window.innerWidth
        break
      }
      case "PageUp":
      case "ArrowLeft":
      case "ArrowUp": {
        event.preventDefault()

        if (scrollPosition === 0) return // If at the beginning, return
        scrollPosition -= window.innerWidth
        break
      }
      case "Home": {
        scrollPosition = 0
        break
      }
      case "End": {
        scrollPosition = container.scrollWidth
        break
      }
    }

    container.scrollTo({
      top: 0,
      left: scrollPosition
    })
  }
}

// Scroll on mouse clicks
// ======================

const goToPreviousSectionButton = document.createElement("button")
const goToNextSectionButton = document.createElement("button")

document.body.appendChild(goToPreviousSectionButton)
document.body.appendChild(goToNextSectionButton)

const sections = Array.from(document.querySelectorAll("section")).sort(
  (s1, s2) => {
    return s1.getBoundingClientRect().left - s2.getBoundingClientRect().left
  }
)

const getSectionInView = () => {
  const halfWidth = window.innerWidth / 2
  const index = sections.findIndex(
    section =>
      section.getBoundingClientRect().left <= halfWidth &&
      section.getBoundingClientRect().right > halfWidth
  )
  return index
}

const getNextSection = dir => {
  const sectionInViewIndex = getSectionInView()
  const nextIndex = sectionInViewIndex + dir
  const numSections = sections.length
  const nextSectionIndex =
    nextIndex < 0 || nextIndex >= numSections ? sectionInViewIndex : nextIndex
  return sections[nextSectionIndex]
}

const animateScroll = dir => {
  const from = container.scrollLeft
  const { left } = getNextSection(dir).getBoundingClientRect()
  return progress => (container.scrollLeft = from + progress * left)
}

goToPreviousSectionButton.addEventListener("click", () => {
  animate({
    easing: "out-quintic",
    change: animateScroll(-1)
  })
})

goToNextSectionButton.addEventListener("click", () => {
  animate({
    easing: "out-quintic",
    change: animateScroll(1)
  })
})

1 个答案:

答案 0 :(得分:1)

您可以在“开关”中使用 ArrowRight ArrowLeft 大小写。 以下用法将解决此问题。

import animate from "https://cdn.jsdelivr.net/npm/animateplus@2/animateplus.js"

// Scroll on key presses
// =====================

let scrollPosition = 0
const maxScrollPosition = document.body.scrollWidth - window.innerWidth
const container = document.scrollingElement

window.onload = () => {
  document.body.onkeydown = event => {
    switch (event.code) {
      case "Space":
      case "PageDown":
      case "ArrowRight":
        {
          scrollPosition++;
           if (scrollPosition === 3) return 
            event.preventDefault()
            animate({
              easing: "out-quintic",
              change: animateScroll(1)
            })
            break
        }
      case "ArrowLeft":
        {
            scrollPosition--;
           if (scrollPosition === 0) return 
            event.preventDefault()
            animate({
              easing: "out-quintic",
              change: animateScroll(-1)
            })
            break
        }
      case "PageUp": 
      case "Home": { 
        if(scrollPosition === 1)
         {
             animate({
              easing: "out-quintic",
              change: animateScroll(-1)
            }) 
         }else
         {
           animate({
             easing: "out-quintic",
             change: animateScroll(-2)
           })
         } 
        scrollPosition = 0;
        break
      }
      case "End": { 
         if(scrollPosition === 1)
         {
             animate({
              easing: "out-quintic",
              change: animateScroll(1)
            })  
         }else
           {
               animate({
                easing: "out-quintic",
                change: animateScroll(2)
              })
           }

        scrollPosition = 2;
        break
      }
    }


  }
}

// Scroll on mouse clicks
// ======================

const goToPreviousSectionButton = document.createElement("button")
const goToNextSectionButton = document.createElement("button")

document.body.appendChild(goToPreviousSectionButton)
document.body.appendChild(goToNextSectionButton)

const sections = Array.from(document.querySelectorAll("section")).sort(
  (s1, s2) => {
    return s1.getBoundingClientRect().left - s2.getBoundingClientRect().left
  }
)

const getSectionInView = () => {
  const halfWidth = window.innerWidth / 2
  const index = sections.findIndex(
    section =>
      section.getBoundingClientRect().left <= halfWidth &&
      section.getBoundingClientRect().right > halfWidth
  )
  return index
}

const getNextSection = dir => {
  const sectionInViewIndex = getSectionInView()
  const nextIndex = sectionInViewIndex + dir
  const numSections = sections.length
  const nextSectionIndex =
    nextIndex < 0 || nextIndex >= numSections ? sectionInViewIndex : nextIndex
  return sections[nextSectionIndex]
}

const animateScroll = dir => {
  const from = container.scrollLeft
  const { left } = getNextSection(dir).getBoundingClientRect()
  return progress => (container.scrollLeft = from + progress * left)
}

goToPreviousSectionButton.addEventListener("click", () => {
  animate({
    easing: "out-quintic",
    change: animateScroll(-1)
  })
})

goToNextSectionButton.addEventListener("click", () => {
  animate({
    easing: "out-quintic",
    change: animateScroll(1)
  })
})