Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

166
Vistas
Escalar SVG con la posición del cursor como origen de transformación

Estoy tratando de escalar un círculo SVG con 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, y en cada otro intento 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 del perímetro del mismo. 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"/> </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>

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

No estoy seguro de un par de cosas:

  • lo que quieres decir con que no quieres que el círculo cambie de posición
  • también si realmente desea escalar todo el SVG, o solo el círculo dentro del SVG

En la siguiente demostración, mantuve el SVG sin cambios, pero escalando el círculo en función de dónde se encuentra dentro del SVG cuando gira la rueda del mouse.

Esperemos que sea lo que estabas buscando.

 // let scale = 1; const svg = document.getElementById("svg"); const circle = document.querySelector("svg circle"); // Circle transform. Inits to 1:1 scale (called an "identity transform"). var circleTransform = svg.createSVGMatrix(); // start svg.addEventListener("wheel", wheelZoom); function wheelZoom(event) { event.preventDefault(); // Get the mouse position as SVG coordinates var coords = convertScreenCoordsToSvgCoords(event.clientX, event.clientY); // Calculate an appropriate scale adjustment var scale = 1.0 + (event.deltaY * 0.001); // To scale around the mouse coords, first we transform the coordinate // system so that the origin is at the mouse coords. circleTransform = circleTransform.translate(coords.x, coords.y); // Then we apply the scale circleTransform = circleTransform.scale(scale, scale); // Finally we move the coordinate system back to where it was circleTransform = circleTransform.translate(-coords.x, -coords.y); // Now we need to update the circle's transform var transform = svg.createSVGTransform(); // An SVGTransform DOM object... transform.setMatrix(circleTransform); // set to the new circleTransform... circle.transform.baseVal.initialize(transform); // and used to update the circle transform property } function convertScreenCoordsToSvgCoords(x, y) { var pt = svg.createSVGPoint(); // An SVGPoint SVG DOM object pt.x = x; pt.y = y; // getScreenCTM tells us the combined transform that determines where // the circle is rendered. Including any viewBox. // We use the inverse of that to convert the mouse X and Y to their // equivalent values inside the SVG. pt = pt.matrixTransform(circle.getScreenCTM().inverse()); return {'x': pt.x, 'y': pt.y}; }
 svg { background-color: linen; }
 <div class="container"> <svg id="svg" height="600" width="600"> <circle cx="300" cy="300" r="300" stroke="black" stroke-width="3" fill="white"/> </svg> </div>

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda