Quiero poder acercar el punto debajo del mouse en un lienzo HTML 5, como hacer zoom en Google Maps . ¿Cómo puedo lograr eso?
javascript
html
canvas
csiz
fuente
fuente
Respuestas:
La mejor solución es simplemente mover la posición de la ventana gráfica en función del cambio en el zoom. El punto de zoom es simplemente el punto en el zoom anterior y el nuevo zoom que desea que permanezca igual. Es decir, la vista ampliada previamente y la vista ampliada tienen el mismo punto de zoom relativo a la vista. Dado que estamos escalando en relación con el origen. Puede ajustar la posición de la vista en consecuencia:
Entonces, realmente puedes desplazarte hacia abajo y hacia la derecha cuando acercas, por un factor de cuánto acercaste, en relación con el punto en el que hiciste zoom.
fuente
Finalmente lo resolvió:
La clave, como señaló @Tatarize , es calcular la posición del eje de manera que el punto de zoom (puntero del mouse) permanezca en el mismo lugar después del zoom.
Originalmente el mouse está a una distancia
mouse/scale
de la esquina, queremos que el punto debajo del mouse permanezca en el mismo lugar después del zoom, pero esto estámouse/new_scale
lejos de la esquina. Por lo tanto, necesitamos cambiar lasorigin
(coordenadas de la esquina) para dar cuenta de esto.El código restante debe aplicar la escala y traducir al contexto de dibujo para que su origen coincida con la esquina del lienzo.
fuente
Este es en realidad un problema muy difícil (matemáticamente), y estoy trabajando en lo mismo casi. Hice una pregunta similar en Stackoverflow pero no obtuve respuesta, pero publiqué en DocType (StackOverflow para HTML / CSS) y obtuve una respuesta. Échale un vistazo http://doctype.com/javascript-image-zoom-css3-transforms-calculate-origin-example
Estoy en medio de la construcción de un complemento jQuery que hace esto (zoom de estilo de Google Maps usando transformaciones CSS3). Tengo el zoom en el bit del cursor del mouse funcionando bien, aún tratando de descubrir cómo permitir que el usuario arrastre el lienzo como lo puede hacer en Google Maps. Cuando lo haga funcionar, publicaré el código aquí, pero revise el enlace de arriba para la parte del mouse-zoom-to-point.
No me di cuenta de que había métodos de escala y traducción en el contexto de Canvas, puedes lograr lo mismo usando CSS3, por ejemplo. usando jQuery:
Asegúrese de establecer el CSS3 transform-origin en 0, 0 (-moz-transform-origin: 0 0). El uso de CSS3 transform le permite acercar cualquier cosa, solo asegúrese de que el contenedor DIV esté configurado para desbordarse: oculto para evitar que los bordes con zoom se derramen por los lados.
Depende de usted si utiliza transformaciones CSS3, o los métodos de escala y traducción propios del lienzo, pero consulte el enlace anterior para ver los cálculos.
Actualización: Meh! Voy a publicar el código aquí en lugar de hacer que sigas un enlace:
Por supuesto, deberá adaptarlo para usar la escala del lienzo y los métodos de traducción.
Actualización 2: Acabo de notar que estoy usando transform-origin junto con translate. Me las arreglé para implementar una versión que solo usa la escala y la traducción por su cuenta, compruébelo aquí http://www.dominicpettifer.co.uk/Files/Mosaic/MosaicTest.html Espere a que se descarguen las imágenes y luego use su rueda del mouse para hacer zoom, también es compatible con la panorámica arrastrando la imagen. Está utilizando transformaciones CSS3, pero debería poder usar los mismos cálculos para su lienzo.
fuente
Me encontré con este problema usando c ++, que probablemente no debería haber tenido, solo comencé a usar matrices OpenGL para empezar ... de todos modos, si estás usando un control cuyo origen es la esquina superior izquierda, y quieres paneo / zoom Al igual que Google Maps, aquí está el diseño (usando Allegro como mi controlador de eventos):
fuente
Me gusta la respuesta de Tatarize , pero proporcionaré una alternativa. Este es un problema trivial de álgebra lineal, y el método que presento funciona bien con panorámica, zoom, sesgo, etc. Es decir, funciona bien si su imagen ya está transformada.
Cuando se escala una matriz, la escala está en el punto (0, 0). Entonces, si tiene una imagen y la escala en un factor de 2, el punto inferior derecho se duplicará en las direcciones x e y (usando la convención de que [0, 0] es la esquina superior izquierda de la imagen).
Si, en cambio, desea ampliar la imagen sobre el centro, entonces la solución es la siguiente: (1) traduzca la imagen de modo que su centro esté en (0, 0); (2) escalar la imagen por factores x e y; (3) traduzca la imagen de nuevo. es decir
Más abstracto, la misma estrategia funciona para cualquier punto. Si, por ejemplo, desea escalar la imagen en un punto P:
Y, por último, si la imagen ya está transformada de alguna manera (por ejemplo, si está rotada, sesgada, traducida o escalada), entonces la transformación actual necesita ser preservada. Específicamente, la transformación definida anteriormente necesita ser multiplicada posteriormente (o multiplicada a la derecha) por la transformación actual.
Ahí tienes. Aquí hay un plunk que muestra esto en acción. Desplácese con la rueda del mouse sobre los puntos y verá que permanecen consistentemente. (Probado solo en Chrome.) Http://plnkr.co/edit/3aqsWHPLlSXJ9JCcJzgH?p=preview
fuente
Aquí está mi solución para una imagen orientada al centro:
fuente
Aquí hay una forma alternativa de hacerlo que usa setTransform () en lugar de scale () y translate (). Todo se almacena en el mismo objeto. Se supone que el lienzo está en 0,0 en la página, de lo contrario, deberá restar su posición de los códigos de la página.
Código de acompañamiento para manejar la panorámica:
Para obtener la respuesta usted mismo, considere que las mismas coordenadas de la página deben coincidir con las mismas coordenadas del lienzo antes y después del zoom. Entonces puedes hacer algo de álgebra a partir de esta ecuación:
(pageCoords - traducción) / scale = canvasCoords
fuente
Quiero poner aquí información para aquellos que hacen un dibujo separado de la imagen y la mueven para acercarla.
Esto puede ser útil cuando desea almacenar los zooms y la posición de la ventana gráfica.
Aquí está el cajón:
La escala de aviso DEBE ser la primera .
Y aquí está el zoomer:
y, por supuesto, necesitaríamos un arrastrador:
fuente
fuente
Aquí hay una implementación de código de la respuesta de @ tatarize, usando PIXI.js. Tengo una ventana gráfica que mira parte de una imagen muy grande (por ejemplo, el estilo de Google Maps).
$canvasContainer
es mi contenedor htmlimageContainer
es mi contenedor PIXI que tiene la imagen en él.mousePosOnImage
es la posición del mouse con respecto a la imagen completa (no solo el puerto de vista).Así es como obtuve la posición del mouse:
fuente
Debe obtener el punto en el espacio mundial (en oposición al espacio de la pantalla) antes y después del zoom, y luego traducir por el delta.
La posición del mouse está en el espacio de la pantalla, por lo que debe transformarla en espacio mundial. La transformación simple debería ser similar a esto:
fuente
puede usar la función scrollto (x, y) para manejar la posición de la barra de desplazamiento hasta el punto que necesita que se muestre después del zoom. para encontrar la posición del mouse, use event.clientX y event.clientY. Esto te ayudara
fuente
Una cosa importante ... si tienes algo como:
Necesitas hacer lo mejor en el lienzo:
fuente