javascript - 如何仅对水平和垂直进行框过渡?
问题描述
我试图让一个盒子在箭头按下时水平和垂直移动。但是,例如up arrow
,当我按下它时,right arrow
它是对角线的。这是我的代码笔
.box {
background-color: gray;
height: 100px;
width: 100px;
transition: margin 0.5s cubic-bezier(0, .7, 0, 1);
}
const box = document.getElementsByClassName('box')[0];
document.addEventListener('keydown', function({keyCode, which}) {
const keycode = keyCode ? keyCode : which,
startValue = '0px',
shiftValue = '400px';
console.log(box.style.marginLeft, box.style.marginTop)
switch(keycode) {
case(40):
box.style.marginTop = shiftValue;
break;
case(39):
box.style.marginLeft = shiftValue;
break;
case(38):
box.style.marginTop = startValue;
break;
case(37):
box.style.marginLeft = startValue;
break;
}
});
解决方案
一种可能的解决方案:您可以跟踪已请求的移动并等待执行移动,直到前一个移动完成。例子:
const box = document.getElementsByClassName('box')[0];
const startValue = '0px';
const shiftValue = '400px';
function moveDown() {
// The move* functions only perform the move if is valid - i.e.,
// if it would actually cause a visible change.
if (box.style.marginTop !== shiftValue) {
box.style.marginTop = shiftValue;
return true;
}
// The move* functions return true iff the move was made.
return false;
}
function moveRight() {
if (box.style.marginLeft !== shiftValue) {
box.style.marginLeft = shiftValue;
return true;
}
return false;
}
function moveUp() {
if (box.style.marginTop !== startValue) {
box.style.marginTop = startValue;
return true;
}
return false;
}
function moveLeft() {
if (box.style.marginLeft !== startValue) {
box.style.marginLeft = startValue;
return true;
}
return false;
}
const moves = [];
let timeOfLastMoveInMilliseconds = null;
const animationDurationInSeconds = 0.5; // should match css transition duration
const animationDurationInMilliseconds = animationDurationInSeconds * 1000;
function onFrame() {
if (!timeOfLastMoveInMilliseconds) {
timeOfLastMoveInMilliseconds = performance.now();
}
const timeSinceLastMove = performance.now() - timeOfLastMoveInMilliseconds;
if (moves.length > 0 && timeSinceLastMove >= animationDurationInMilliseconds) {
const wasMoved = moves.pop()();
if (wasMoved) {
timeOfLastMoveInMilliseconds = performance.now();
}
}
window.requestAnimationFrame(onFrame);
}
window.requestAnimationFrame(onFrame);
document.addEventListener('keydown', function({keyCode, which}) {
const keycode = keyCode ? keyCode : which;
switch(keycode) {
case(40):
moves.unshift(moveDown);
break;
case(39):
moves.unshift(moveRight);
break;
case(38):
moves.unshift(moveUp);
break;
case(37):
moves.unshift(moveLeft);
break;
}
});
请注意,上面的代码会跟踪用户所做的每一个动作,因此,例如,如果您快速按下、上、下、上、下,该序列将播放。根据您的应用程序,您可能希望添加限制,例如,仅允许水平+对角线移动和/或仅允许在短时间内发生的按键移动。
推荐阅读
- php - 运行“php artisan migrate”但它抛出错误(Laravel,OpenServer)
- css - 我如何对齐图像下的文本(以及中间的所有内容)
- linux - Spring boot .jar to digital ocean droplet(Linux Ubuntu):Web服务器启动失败。80 端口已被使用
- jenkins - 无法使用 Jenkins 管道登录 Github
- jupyter-notebook - 云中的 Jupyter 入门
- android - Parcelable 接口
- javascript - 为什么我的 async/await 示例不起作用?
- three.js - 街道霓虹灯的发光效果
- reactjs - React 问题:“对象作为 React 子级无效。如果您要渲染一组子级,请改用数组。”
- asp.net-core - ASP.NET Core 自定义路由不适用于 web api 2.1