Больше вопросов о SVG (и Javascript) - Интерактивность [перемещение прямоугольника] - PullRequest
0 голосов
/ 27 марта 2011

Следующий код должен заставить прямоугольник двигаться при нажатии клавиш WASD на клавиатуре.Не работаетПрямоугольник не двигается, но ошибки не генерируются.Как я могу сделать эту работу?

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg width="90%" height="90%" version="1.1"
xmlns="http://www.w3.org/2000/svg">

<script type="text/javascript">
    <![CDATA[
    var x;
    var y;
    function move()
    {
        x = new Number(document.getElementById("player").x);
        y = new Number(document.getElementById("player").y);
        switch (event.keyCode)
        {
            case 119:
            y--;
            document.getElementById("player").y=y;
            break;
            case 115:
            y++;
            document.getElementById("player").y=y;
            break;
            case 97:
            x--;
            document.getElementById("player").x=x;
            break;
            case 100:
            x++;
            document.getElementById("player").x=x;
            break;
            default:
        }
    }
    document.documentElement.addEventListener("keypress", move, true);
    ]]>
</script>

<rect x="0" y="0" height="100%" width="100%" style="stroke-width:5; stroke:black; fill:white"></rect>
<rect x="250" y="250" id="player" height="50" width="50" style="stroke-width:1; stroke:red; fill:red"></rect>

</svg>

1 Ответ

4 голосов
/ 28 марта 2011

Ваш код выше не работает, потому что x и y свойства SVGRectElement являются SVGAnimatedLength объектами, представляющими значения, которые могут изменяться со временем.

Простейшие изменения, которые сделают ваш код «работающим»:

  1. Изменение
    x = new Number(document.getElementById("player").x);
    до
    x = new Number(document.getElementById("player").x.baseVal.value);
    (и аналогично для y) .

  2. Изменение
    document.getElementById("player").x=x;
    до
    document.getElementById("player").x.baseVal.value=x;
    (и аналогично для y) .

Это заставит ваш код работать так, как вам нужно. Тем не менее, ваш код, как правило, может быть улучшен за мой ответ на ваш предыдущий вопрос .

Вот как я мог бы написать это (если вы действительно хотите перемещать только одну единицу за раз):

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="90%" height="90%" version="1.1"
 xmlns="http://www.w3.org/2000/svg">
<style>
    #player { stroke-width:1; stroke:red; fill:red }
</style>
<rect x="250" y="250" id="player" height="50" width="50" />
<script type="text/javascript"><![CDATA[
  var KEY = { w:87, a:65, s:83, d:68 };
  var rect = document.getElementById('player');
  var x = rect.getAttribute('x')*1,
      y = rect.getAttribute('y')*1;
  document.documentElement.addEventListener("keydown", function(evt){
    switch (evt.keyCode){
      case KEY.w: rect.y.baseVal.value = --y; break;
      case KEY.s: rect.y.baseVal.value = ++y; break;
      case KEY.a: rect.x.baseVal.value = --x; break;
      case KEY.d: rect.x.baseVal.value = ++x; break;
    }
  }, false);
]]></script>
</svg>

Обратите внимание, что я переместил <rect> над блоком <script> так, чтобы а) пользователь увидел прямоугольник до начала загрузки скрипта, но, что более важно, б) так, чтобы прямоугольник существует до вызова getElementById(). Если ваш сценарий блокируется до того, как ваши элементы были определены, вы должны вместо этого установить ссылки на код в ответ на onload или подобный обработчик событий.

...