Tengo un pequeño programa que cuando presionas ArrowDown, el círculo debe moverse hacia abajo desde su posición en la pantalla. El problema que tengo es que mi posicionamiento inicial para mi objeto de círculo svg establecido por cx: 5% y cy:5% es diferente a mi 5 * xshift y 5 * yshift que se derivan de document.getElementById("test").clientWidth /100 y document.getElementById("test").clientHeight/100 que creo que es una buena conversión a porcentaje. Sin embargo, cuando se ejecuta el programa, la flecha hacia abajo inicial corrige la ubicación inicial y crea una diferencia desplazada notable.
var goal = {x: window.innerWidth, y: window.innerHeight} var xshift = document.getElementById("test").clientWidth/100 var yshift = document.getElementById("test").clientHeight/100 var player= {type:"Player", x:5 * xshift, y: 5 * yshift} document.addEventListener('keydown', function(event) { if (event.key === 'ArrowDown'){ player.y += yshift; if(player.y > (100 * yshift) -(9 * yshift)){ player.y = 91 * yshift; } //document.getElementById("UI").innerHTML = "Player position is x: " +player.x + " y: " + player.y; document.getElementById('circe').setAttribute("transform", 'translate('+player.x+","+player.y+")"); } }, true); <!DOCTYPE html> <html lang="en" dir="ltr"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Basic Snake Game</title> <style> html, body { margin: 0; padding: 0; border: 0; height: 100% } svg { position: absolute; margin: 0; padding: 0; border: 0; background-color: blueviolet; } </style> </head> <body> <!-- <h1 id="UI">Player position is x: 0 y: 0</h1> --> <svg id="test" width="100%" height="100%"> <circle id="circe" cx="5%" cy="5%" r="5%" stroke="green" stroke-width="0%" fill="yellow" transform="translate(0,0)" /> </svg> <script src="test.js"></script> </body> </html>Son diferentes porque estás usando una transformación. La transformación se aplica sobre (además de) las coordenadas cx y cy .
En otras palabras, el círculo se está posicionando en:
x = cx + translate.x = 5% + 5% y = cy + (n * translate.y) = 5% + (n * 5%) Una forma de solucionar esto es olvidar el atributo de transform y simplemente actualizar los atributos cx y cy en su lugar. P.ej.
document.getElementById('circe').setAttribute("cy", player.y);Manifestación
var goal = {x: window.innerWidth, y: window.innerHeight} var xshift = document.getElementById("test").clientWidth/100 var yshift = document.getElementById("test").clientHeight/100 var player= {type:"Player", x:5 * xshift, y: 5 * yshift} document.addEventListener('keydown', function(event) { if (event.key === 'ArrowDown'){ player.y += yshift; if(player.y > (100 * yshift) -(9 * yshift)){ player.y = 91 * yshift; } //document.getElementById("UI").innerHTML = "Player position is x: " +player.x + " y: " + player.y; document.getElementById('circe').setAttribute("cy", player.y); } }, true); html, body { margin: 0; padding: 0; border: 0; height: 100%; } svg { position: absolute; margin: 0; padding: 0; border: 0; background-color: blueviolet; } <!-- <h1 id="UI">Player position is x: 0 y: 0</h1> --> <svg id="test" width="100%" height="100%"> <circle id="circe" cx="5%" cy="5%" r="5%" stroke="green" stroke-width="0%" fill="yellow" transform="translate(0,0)" /> </svg>
Puede verificar el código completo desde: este violín , combiné sus piezas de código y agregué una sola línea.
`
var goal = {x: window.innerWidth, y: window.innerHeight} var xshift = document.getElementById("test").clientWidth/100 var yshift = document.getElementById("test").clientHeight/100 var player= {type:"Player", x:5 * xshift, y: 5 * yshift} document.addEventListener('keydown', function(event) { if (event.key === 'ArrowDown'){ doShift(); } }, true); function doShift(){ player.y += yshift; if(player.y > (100 * yshift) -(9 * yshift)){ player.y = 91 * yshift; } //document.getElementById("UI").innerHTML = "Player position is x: " +player.x + " y: " + player.y; document.getElementById('circe').setAttribute("transform", 'translate('+player.x+","+player.y+")"); } //document.addEventListener("onready", ()=> doShift()); //document.ondomcontentready=doShift; doShift();`;
Aunque parece un truco, el último doShift(); llamada crea el mismo efecto que cuando presiona el botón hacia abajo por primera vez: especifica lo que desea.