• Empleos
  • Sobre nosotros
  • profesionales
    • Inicio
    • Empleos
    • Cursos y retos
    • Preguntas
    • Profesores
  • empresas
    • Inicio
    • Publicar vacante
    • Nuestro proceso
    • Precios
    • Pruebas Online
    • Nómina
    • Blog
    • Comercial
    • Calculadora de salario

0

134
Vistas
Acercar el lienzo y luego alejar el zoom en una posición diferente del mouse Rompe la visualización del fondo

Estoy tratando de implementar una función de zoom en mi lienzo manteniendo la posición del mouse en relación con donde estaba antes.

Esta función lo logra casi. Y aquí hay un ejemplo completo: https://codepen.io/PJEstrada006/pen/dyRxVXE?editors=0011

 public zoom_wheel_canvas_translate(event): void { // this is the illusionary point on UI that we wish to stay locked on let point = this.mouse_position; const wheel = event.deltaY < 0 ? 1 : -1; // Compute zoom factor. let zoomIntensity = 0.2; let zoom = Math.exp(wheel * zoomIntensity); this.scale = this.scale * zoom; if (this.scale <= 1) { this.canvas_ctx.setTransform(1, 0, 0, 1, 0, 0); this.scale = 1; return } if (this.scale >= 30) { this.scale = 30 } this.canvas_ctx.clearRect( 0, 0, this.canvas_elm.width, this.canvas_elm.height ); let transform = this.canvas_ctx.getTransform(); this.canvas_ctx.resetTransform(); this.canvas_ctx.translate(point.x, point.y); this.canvas_ctx.scale(zoom, zoom); this.canvas_ctx.translate(-point.x, -point.y); this.canvas_ctx.transform(transform.a, transform.b, transform.c, transform.d, transform.e, transform.f) let transform_new = this.canvas_ctx.getTransform(); console.log('a', transform.a, 'd', transform.d) console.log('e', transform.e, 'f', transform.f) }

Tengo una imagen establecida como fondo del lienzo que se dibuja así:

 ctx.drawImage( this.image, 0, 0 )

El problema es que si hago algo como lo siguiente:

  1. Coloque el ratón en el centro de la pantalla.
  2. Acercar (Funciona bien)
  3. Mueve el ratón a otro lugar.
  4. Seguir haciendo zoom
  5. Alejar todo el camino a escala siendo 1

El alejamiento finalmente termina traduciendo el lienzo de manera incorrecta y la imagen de mi lienzo aparece "cortada" o incompleta debido a traducciones o escalas incorrectas. Esto sucede justo antes de que la escala se convierta en 1, luego se corrige solo porque tengo una llamada resetTransform() cuando la escala = 1.

Espero que, sin importar cómo mueva el mouse, eventualmente aleje el zoom y termine con la matriz de transformación original (matriz de identidad).

¿Alguien puede ayudarme a detectar qué estoy haciendo mal con mis transformaciones? No entiendo muy bien por qué funciona perfectamente si no muevo el mouse, pero deja de funcionar si muevo el mouse en un estado de zoom y luego lo alejo.

almost 3 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

Está buscando "comprender por qué este algoritmo de mouse out no funciona", no diría que no funciona ya que no hay errores, probé el zoom en su codepen y me parece bien...
Su zoom es relativo a la posición del mouse, interactuar con él se siente intuitivo y fluido.

Hice algo de limpieza en tu código:
https://codepen.io/heldersepu/pen/LYjYEyL?editors=0010

El único problema que veo es traducir sin considerar que la imagen podría estar fuera de los límites,
ver este código:

 context.translate(x, y); context.scale(zoom, zoom); context.translate(-x, -y);

Ese código estará bien en un mapa mundial donde la imagen es realmente grande y envolvente, creo que Google Maps usa una lógica similar, y es un caso de uso perfecto allí, pero no está considerando la limitación de su imagen.

Al hacer zoom en su imagen, no vamos a ver el problema porque la imagen siempre está rellena, pero al salir, puede estar saliendo de los límites de la imagen si estamos en el borde.
Aquí hay un ejemplo:

  • mueve el mouse hacia abajo a la izquierda
  • hacer zoom varias veces
  • mueve el mouse hacia abajo a la derecha
  • disminuir el zoom

el lienzo resultante se parece a:

¿Qué hacer en ese caso?
Una opción podría ser no traducir cuando alejamos:

 if (wheel > 0) context.translate(x, y); context.scale(zoom, zoom); if (wheel > 0) context.translate(-x, -y);

O podría traducir condicionalmente en un eje y no en el otro dependiendo de la posición del mouse, pero la solución correcta es para que usted decida, debe probar y ver lo que le gusta.

almost 3 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 Nuestro proceso Comercial
Legal
Términos y condiciones Política de privacidad
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recomiéndame algunas ofertas
Necesito ayuda