Reputation: 5273
I have an SVG path given below. I need to move that red dot using the keyboard. If a turn coming need to use left or right arrow button based on the turn. How can I achieve this using javascript?
Upvotes: 0
Views: 741
Reputation: 3898
may be you can use iconic font?
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>
Upvotes: 1
Reputation: 21856
Here is a function that catches arrow keystrokes. The difference to enxaneta's solution is
event.key
instead of event.keyCode
, which is deprecated. Internet Explorer and Edge < v17 unfortunately use different identifier strings. A complete description of the current state of affairs is here. If you really want to stay with keyCode
, see here for compatibility lists.if an action is associated with a key, event.preventDefault()
is set. Otherwise the window might scroll. It is not used globally, as that would block all keyboard interactions with the window.
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();
}
});
Upvotes: 0
Reputation: 33054
I don't think you can use left or right arrow to move the red dot the way you intend. In fact I don't understand the logic. Please define right and left tun.
However you can move the dot forwards or backwards by using the right and left arrow.
In my code the starting value
is 0 and the red dot is at the beginning of the path. The value
increases or decreases depending on the arrow key you use.
The step is 1/100 of the path's length.
if(e.keyCode == 37){value ++;}
else if(e.keyCode == 39){value --;}
If the value is less than 0 or bigger than 100 I reset the value:
if(value > 100){value %= 100;}
if(value < 0){value += 100}
I get the position on the path using the getPointAtLength()
method. I hope this is what you need.
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>
Please do not forget to click the iframe before using the keys.
Upvotes: 3