如何使用键盘在svg路径中移动对象

时间:2018-10-14 10:15:19

标签: javascript svg html5-canvas

我在下面给出了SVG路径。我需要使用键盘移动该红点。如果要转弯,则需要根据转弯使用向左或向右箭头按钮。如何使用javascript实现此目标?

enter image description here

3 个答案:

答案 0 :(得分:2)

我认为您不能使用向左或向右箭头按预期方式移动红点。实际上我不理解逻辑。请定义左右tun。

但是,您可以使用左右箭头将点向前或向后移动。

在我的代码中,起始value为0,红点位于路径的开头。 value根据您使用的箭头键增加或减少。

步长为路径长度的1/100。

if(e.keyCode == 37){value ++;}
else if(e.keyCode == 39){value --;}

如果该值小于0或大于100,我将重置该值:

if(value > 100){value %= 100;}
if(value < 0){value += 100}

我使用getPointAtLength()方法获得了路径上的位置。我希望这就是您所需要的。

let position = circuit.getPointAtLength(totalLength*value/100);

let totalLength = circuit.getTotalLength();


let value = 0;

window.addEventListener("keydown",(e)=>{
  
  if(e.keyCode == 37){value ++;}
  else if(e.keyCode == 39){value --;}
  
  if(value > 100){value %= 100;}
  if(value < 0){value += 100}
  
  let position = circuit.getPointAtLength(totalLength*value/100);
   updateElement({cx:position.x, cy:position.y}, thumb)
  
})



function updateElement(o, element) {
  for (var name in o) {
    if (o.hasOwnProperty(name)) {
      element.setAttributeNS(null, name, o[name]);
    }
  }
  return element;
}
svg{border:1px solid #d9d9d9; max-width:100vh}


#circuit{
  stroke:black;
  fill:none;
  stroke-width: 5px;
  stroke-linejoin:round;
  stroke-linecap:round;
  fill-opacity:.85
}

circle{fill:red}
<svg id="svg" viewBox="30 30 300 300">

	<path id="circuit" d="M187.476,214.443c-2.566,11.574-4.541,22.658-7.542,33.456
		c-3.558,12.8-7.14,25.713-12.242,37.938c-10.223,24.495-41.321,29.239-58.824,9.548c-9.592-10.792-11.295-26.9-3.539-40.556
		c11.233-19.778,25.391-37.46,40.447-54.438c1.07-1.207,2.116-2.436,3.893-4.484c-7.212,0.9-13.349,1.988-19.529,2.374
		c-16.283,1.018-32.578,2.21-48.881,2.437c-18.686,0.261-32.846-10.154-37.071-26.055c-6.762-25.449,15.666-48.973,41.418-43.338
		c23.645,5.175,46.447,12.901,68.424,23.051c1.033,0.478,2.083,0.918,3.933,1.731c-0.83-1.947-1.341-3.225-1.911-4.475
		c-9.896-21.701-18.159-43.986-23.192-67.337c-4.587-21.28,8.933-40.56,29.946-43.257c20.134-2.585,38.124,12.991,39.091,34.294
		c1.029,22.682-0.049,45.292-3.58,67.755c-0.17,1.079-0.152,2.188-0.246,3.659c8.05-6.831,15.471-13.737,23.52-19.811
		c11.147-8.412,22.398-16.795,34.27-24.113c18.35-11.312,40.821-4.481,50.028,14.385c9.091,18.628,0.131,40.586-20.065,48.198
		c-11.034,4.158-22.248,7.944-33.594,11.143c-11.321,3.191-22.908,5.438-34.866,8.212c1.189,0.81,2.19,1.504,3.205,2.18
		c18.402,12.261,37.157,24.032,55.101,36.932c14.769,10.616,18.619,29.317,10.675,44.578c-7.537,14.477-25.151,22.136-40.767,17.583
		c-7.583-2.212-14.022-6.469-18.523-12.919c-12.463-17.86-24.638-35.924-36.898-53.925
		C189.24,217.849,188.547,216.357,187.476,214.443z"/>

  
  <circle id="thumb" cx="187.476" cy="214.443" r="5" fill="black" />
  
 
</svg>

在使用这些键之前,请不要忘记单击iframe。

答案 1 :(得分:0)

这是捕获箭头键的功能。与enxaneta解决方案的区别是

  • 不推荐使用event.key而不是event.keyCode。不幸的是,Internet Explorer和Edge here是当前状态的完整描述。如果您真的想呆在keyCode上,请参阅here以获得兼容性列表。
  • 如果某个操作与某个键相关联,则设置event.preventDefault()。否则,窗口可能会滚动。它不是全局使用的,因为那样会阻止所有键盘与窗口的交互。

    document.addEventListener('keydown', function (event) {
        switch (event.key) {
        case 'Left':
        case 'ArrowLeft':
            // game action
            return event.preventDefault();
        case 'Up':
        case 'ArrowUp':
            // game action
            return event.preventDefault();
        case 'Right':
        case 'ArrowRight':
            // game action
            return event.preventDefault();
        case 'Down':
        case 'ArrowDown':
            // game action
            return event.preventDefault();
        }
    });
    

答案 2 :(得分:0)

也许您可以使用图标字体?

window.focus();
document.addEventListener('keydown', e => {
  let direction = e.keyCode - 38;
  if (Math.abs(direction) !== 1) return;
  let offset = parseFloat(player.getAttribute('startOffset'));
  offset = (offset + direction + 98)%98;
  player.setAttribute('startOffset', offset + '%');
})
<svg viewbox=0,0,300,200 width=90vw height=90vh>
    <path id="route" stroke="red" fill="none" d="M75,120L100,0l100,30q110,100,10,150z"/>
    <text><textPath xlink:href="#route" id="player" startOffset="0%">?</textPath></text>  
</svg>