es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Escalando SVG con la posición del cursor como origen de la transformación.

Estoy intentando escalar un círculo SVG con el trackpad (moviendo dos dedos hacia arriba/abajo) y el origen de la transformación debe ser la posición del cursor. La escala funciona bien la primera vez, pero en cada intento posterior el círculo cambia de posición (no debería). Esto se puede ver claramente si el cursor está dentro del círculo y cerca de su perímetro. A continuación se muestra el código.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" content="width=device-width">

    <style>
        .container
        {
            position: fixed;
            left: 0;
            right: 0;
            top: 0;
            bottom: 0;
        }

    </style>
</head>
<body>


<div class="container">
    <svg id="svg" height="600" width="600">
        <circle cx="300" cy="300" r="300" stroke="black" stroke-width="3" fill="white"></circle>
    </svg>
</div>

<script>
    let scale = 1;
    const e = document.getElementById("svg");

    function wheelZoom(event)
    {
        event.preventDefault();

        scale += event.deltaY * -0.01;
        scale = Math.min(Math.max(.5, scale), 2);

        x = 100*(event.clientX-e.getBoundingClientRect().x)/e.getBoundingClientRect().width;
        y = 100*(event.clientY-e.getBoundingClientRect().y)/e.getBoundingClientRect().height;

        e.style.transformOrigin = `${x}% ${y}%`;
        e.style.transform = `scale(${scale})`;
    }

    e.addEventListener("wheel", wheelZoom);
</script>


</body>
</html>

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    El problema con el código presentado es que las variables x e y no están definidas antes de utilizarse para establecer el origen de la transformación. Esto significa que el origen de la transformación no se mantiene consistente con la posición del cursor después de la primera acción de escalado, lo que provoca que el círculo cambie de posición.

    Para solucionar esto, declara las variables x e y fuera de la función para que conserven sus valores y se actualicen correctamente con cada acción de escalado. El bloque de código actualizado se muestra a continuación:

    let scale = 1;
    const e = document.getElementById("svg");
    let x = 0;
    let y = 0;
    
    function wheelZoom(event) {
      event.preventDefault();
    
      scale += event.deltaY * -0.01;
      scale = Math.min(Math.max(.5, scale), 2);
    
      x = 100*(event.clientX-e.getBoundingClientRect().x)/e.getBoundingClientRect().width;
      y = 100*(event.clientY-e.getBoundingClientRect().y)/e.getBoundingClientRect().height;
    
      e.style.transformOrigin = `${x}% ${y}%`;
      e.style.transform = `scale(${scale})`;
    }
    
    e.addEventListener("wheel", wheelZoom);
    

    Con esta solución, el círculo permanecerá en su posición original y se escalara correctamente en función del movimiento del panel táctil.

Comments are closed.