【问题标题】:How to move an object in svg path using keyboard如何使用键盘在 svg 路径中​​移动对象
【发布时间】:2019-03-18 23:46:27
【问题描述】:

我在下面给出了一个 SVG 路径。我需要使用键盘移动那个红点。如果转弯来了需要根据转弯使用向左或向右箭头按钮。如何使用 javascript 实现这一点?

【问题讨论】:

  • 请向我们提供您目前所获得的信息。

标签: javascript svg html5-canvas


【解决方案1】:

我不认为您可以使用向左或向右箭头按您想要的方式移动红点。事实上,我不明白其中的逻辑。请定义左右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。

【讨论】:

    【解决方案2】:

    也许你可以使用标志性字体?

    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>

    【讨论】:

      【解决方案3】:

      这是一个捕捉箭头键击的函数。与 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();
            }
        });
        

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-06-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-23
        • 2020-04-05
        • 2011-09-29
        相关资源
        最近更新 更多