使用箭头键反应自定义滚动
React custom scrolling with ArrowKeys
我想为我的漫画查看器创建自定义滚动动画。我在 codesandbox 中重新创建了示例代码:https://codesandbox.io/s/hardcore-microservice-kfe1q
我面临的问题是,滚动动画开始“滞后”。而且真的不可能改变滚动速度和间隔。
我正在尝试重现与此漫画查看器类似的感觉:Example
任何帮助将不胜感激,我什至不太确定当前示例是否是解决此问题的正确方法。
所以这里有一个可能的解决方案来解决这个问题
function useKeyPress(targetKey) {
// State for keeping track of whether key is pressed
const [keyPressed, setKeyPressed] = useState(false);
// If pressed key is our target key then set to true
function downHandler(e) {
if (e.key === targetKey) {
setKeyPressed(true);
e.preventDefault();
}
}
// If released key is our target key then set to false
const upHandler = (e) => {
if (e.key === targetKey) {
setKeyPressed(false);
}
};
// Add event listeners
useEffect(() => {
window.addEventListener("keydown", downHandler);
window.addEventListener("keyup", upHandler);
// Remove event listeners on cleanup
return () => {
window.removeEventListener("keydown", downHandler);
window.removeEventListener("keyup", upHandler);
};
}, []); // Empty array ensures that effect is only run on mount and unmount
return keyPressed;
}
export function useUI() {
const scrollDistance = 15;
const ArrowUp = useKeyPress("ArrowUp");
const ArrowDown = useKeyPress("ArrowDown");
const k = useKeyPress("k"); // up
const j = useKeyPress("j"); // down
const w = useKeyPress("w"); // up
const s = useKeyPress("s"); // down
useEffect(() => {
if (!(ArrowUp || ArrowDown || k || j || w || s)) {
return null;
}
const scrollDirection = ArrowUp || k || w ? 1 : -1;
let animationFrame = 0;
let callback = () => {
const pos = window.pageYOffset;
window.scroll(0, pos - scrollDistance * scrollDirection);
animationFrame = requestAnimationFrame(callback);
};
animationFrame = requestAnimationFrame(callback);
return () => {
cancelAnimationFrame(animationFrame);
};
}, [ArrowUp, ArrowDown, k, j, w, s]);
return null;
}
我想为我的漫画查看器创建自定义滚动动画。我在 codesandbox 中重新创建了示例代码:https://codesandbox.io/s/hardcore-microservice-kfe1q
我面临的问题是,滚动动画开始“滞后”。而且真的不可能改变滚动速度和间隔。
我正在尝试重现与此漫画查看器类似的感觉:Example
任何帮助将不胜感激,我什至不太确定当前示例是否是解决此问题的正确方法。
所以这里有一个可能的解决方案来解决这个问题
function useKeyPress(targetKey) {
// State for keeping track of whether key is pressed
const [keyPressed, setKeyPressed] = useState(false);
// If pressed key is our target key then set to true
function downHandler(e) {
if (e.key === targetKey) {
setKeyPressed(true);
e.preventDefault();
}
}
// If released key is our target key then set to false
const upHandler = (e) => {
if (e.key === targetKey) {
setKeyPressed(false);
}
};
// Add event listeners
useEffect(() => {
window.addEventListener("keydown", downHandler);
window.addEventListener("keyup", upHandler);
// Remove event listeners on cleanup
return () => {
window.removeEventListener("keydown", downHandler);
window.removeEventListener("keyup", upHandler);
};
}, []); // Empty array ensures that effect is only run on mount and unmount
return keyPressed;
}
export function useUI() {
const scrollDistance = 15;
const ArrowUp = useKeyPress("ArrowUp");
const ArrowDown = useKeyPress("ArrowDown");
const k = useKeyPress("k"); // up
const j = useKeyPress("j"); // down
const w = useKeyPress("w"); // up
const s = useKeyPress("s"); // down
useEffect(() => {
if (!(ArrowUp || ArrowDown || k || j || w || s)) {
return null;
}
const scrollDirection = ArrowUp || k || w ? 1 : -1;
let animationFrame = 0;
let callback = () => {
const pos = window.pageYOffset;
window.scroll(0, pos - scrollDistance * scrollDirection);
animationFrame = requestAnimationFrame(callback);
};
animationFrame = requestAnimationFrame(callback);
return () => {
cancelAnimationFrame(animationFrame);
};
}, [ArrowUp, ArrowDown, k, j, w, s]);
return null;
}