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



我有一个水平展开的页面,可以通过鼠标单击或按空格键page Up/page Down箭头/右箭头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)
})
})

您可以在"switch"中使用ArrowRightArrowLeft大小写。以下用法将解决问题。

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)
})
})

最新更新