HTML:
<div id="pane">
<div id="box"></div>
</div>
CSS:
#pane {
position:relative;
width:300px; height:300px;
border:2px solid red;
}
#box {
position:absolute; top:140px; left:140px;
width:20px; height:20px;
background-color:black;
}
JavaScript:
var pane = $('#pane'),
box = $('#box'),
w = pane.width() - box.width(),
d = {},
x = 3;
function newv(v,a,b) {
var n = parseInt(v, 10) - (d[a] ? x : 0) + (d[b] ? x : 0);
return n < 0 ? 0 : n > w ? w : n;
}
$(window).keydown(function(e) { d[e.which] = true; });
$(window).keyup(function(e) { d[e.which] = false; });
setInterval(function() {
box.css({
left: function(i,v) { return newv(v, 37, 39); },
top: function(i,v) { return newv(v, 38, 40); }
});
}, 20);
Объяснения переменных:
w
- максимальное слева /верхнее значение, которое может иметь поле (чтобы оно оставалось в пределах)
x
- расстояние (в пикселях), которое поле перемещает в каждом интервале
d
- этот объект хранит информацию о том, какой ключ используетсянажат.Например, пока пользователь удерживает клавишу СТРЕЛКА ВЛЕВО, d['37']
равно true
.В противном случае это false
.Кстати, 37
- это код клавиши для клавиши СТРЕЛКА ВЛЕВО, и это значение сохраняется в свойстве e.which
объекта события.Объект d
обновляется при каждом событии keydown
и keyup
.
setInterval, который выполняется каждые 20 мс, обновляет левый и верхний свойства CSS элемента box.Новые значения вычисляются с помощью функции newv
.
Функция newv
вычисляет новое левое / верхнее значение на основе a) старого значения v
и b) объекта d
.
Выражение n < 0 ? 0 : n > w ? w : n
гарантирует, что новое значение будет в допустимых границах (которые 0 to w
).Если n <0, ноль будет возвращен.Если n> w, w будет возвращено.
Обновление: Этот код имеет ту же функциональность, что и исходный код выше.Разница лишь в том, что я использовал более значимые имена для своих переменных и аргументов.Как видите, выглядит ужасно - оригинальная версия явно лучше.:P
var pane = $('#pane'),
box = $('#box'),
maxValue = pane.width() - box.width(),
keysPressed = {},
distancePerIteration = 3;
function calculateNewValue(oldValue, keyCode1, keyCode2) {
var newValue = parseInt(oldValue, 10)
- (keysPressed[keyCode1] ? distancePerIteration : 0)
+ (keysPressed[keyCode2] ? distancePerIteration : 0);
return newValue < 0 ? 0 : newValue > maxValue ? maxValue : newValue;
}
$(window).keydown(function(event) { keysPressed[event.which] = true; });
$(window).keyup(function(event) { keysPressed[event.which] = false; });
setInterval(function() {
box.css({
left: function(index ,oldValue) {
return calculateNewValue(oldValue, 37, 39);
},
top: function(index, oldValue) {
return calculateNewValue(oldValue, 38, 40);
}
});
}, 20);