Quero poder ampliar o ponto sob o mouse em uma tela HTML 5, como o zoom no Google Maps . Como posso conseguir isso?
javascript
html
canvas
csiz
fonte
fonte
Respostas:
A melhor solução é simplesmente mover a posição da viewport com base na alteração no zoom. O ponto de zoom é simplesmente o ponto no zoom antigo e o novo zoom que você deseja manter o mesmo. Ou seja, a viewport pré-ampliada e a viewport pós-ampliada têm o mesmo ponto de zoom em relação à viewport. Dado que estamos escalando em relação à origem. Você pode ajustar a posição da janela de exibição de acordo:
Então, na verdade, você pode simplesmente deslocar-se para baixo e para a direita ao aumentar o zoom, por um fator de quanto você ampliou, em relação ao ponto em que você ampliou.
fonte
Finalmente resolvi:
A chave, como apontou @Tatarize , é calcular a posição do eixo de forma que o ponto de zoom (ponteiro do mouse) permaneça no mesmo local após o zoom.
Originalmente, o mouse está a uma distância
mouse/scale
do canto, queremos que o ponto embaixo do mouse permaneça no mesmo local após o zoom, mas isso estámouse/new_scale
longe do canto. Portanto, precisamos mudar asorigin
(coordenadas do canto) para explicar isso.O código restante precisa aplicar a escala e traduzir para o contexto do desenho, para que sua origem coincida com o canto da tela.
fonte
Este é realmente um problema muito difícil (matematicamente), e estou trabalhando quase na mesma coisa. Fiz uma pergunta semelhante no Stackoverflow, mas não obtive resposta, mas postei no DocType (StackOverflow para HTML / CSS) e obtive uma resposta. Confira http://doctype.com/javascript-image-zoom-css3-transforms-calculate-origin-example
Estou no meio da construção de um plugin jQuery que faz isso (zoom no estilo do Google Maps usando transformações CSS3). O zoom do cursor do mouse está funcionando bem, ainda tentando descobrir como permitir que o usuário arraste a tela como você pode fazer no Google Maps. Quando o funcionar, postarei o código aqui, mas verifique o link acima para ver a parte do zoom do mouse até o ponto.
Eu não percebi que havia métodos de escala e tradução no contexto do Canvas, você pode conseguir a mesma coisa usando CSS3, por exemplo. usando jQuery:
Certifique-se de definir a origem da transformação CSS3 como 0, 0 (-moz-transform-origin: 0 0). O uso da transformação CSS3 permite aumentar o zoom em qualquer coisa, apenas verifique se o DIV do contêiner está configurado para estourar: oculto para impedir que as bordas ampliadas se espalhem pelas laterais.
Se você usa as transformações CSS3 ou os próprios métodos de escala e conversão da tela, é com você, mas verifique o link acima para os cálculos.
Atualização: Meh! Vou apenas postar o código aqui, em vez de levá-lo a seguir um link:
Obviamente, você precisará adaptá-lo para usar a escala de tela e traduzir métodos.
Atualização 2: Acabei de perceber que estou usando a origem de transformação junto com a tradução. Consegui implementar uma versão que apenas usa escala e traduz por conta própria, confira aqui http://www.dominicpettifer.co.uk/Files/Mosaic/MosaicTest.html Aguarde o download das imagens e use o seu roda do mouse para aumentar o zoom, também suporta pan, arrastando a imagem ao redor. Ele está usando transformações CSS3, mas você deve poder usar os mesmos cálculos para o seu Canvas.
fonte
Eu me deparei com esse problema usando c ++, que provavelmente não deveria ter acabado de usar matrizes OpenGL para começar ... de qualquer maneira, se você estiver usando um controle cuja origem é o canto superior esquerdo e desejar aplicar zoom / panorâmica como o Google Maps, aqui está o layout (usando o allegro como meu manipulador de eventos):
fonte
Gosto da resposta de Tatarize , mas darei uma alternativa. Esse é um problema trivial de álgebra linear, e o método que apresento funciona bem com panorâmica, zoom, inclinação, etc. Ou seja, funciona bem se sua imagem já estiver transformada.
Quando uma matriz é dimensionada, a escala está no ponto (0, 0). Portanto, se você tiver uma imagem e a dimensionar por um fator de 2, o ponto inferior direito dobrará nas direções x e y (usando a convenção de que [0, 0] é o canto superior esquerdo da imagem).
Se, em vez disso, você deseja ampliar a imagem no centro, a solução é a seguinte: (1) traduza a imagem de modo que seu centro esteja em (0, 0); (2) dimensionar a imagem pelos fatores x e y; (3) traduza a imagem de volta. ie
Mais abstratamente, a mesma estratégia funciona para qualquer ponto. Se, por exemplo, você deseja dimensionar a imagem em um ponto P:
E, finalmente, se a imagem já estiver transformada de alguma maneira (por exemplo, se for girada, inclinada, traduzida ou dimensionada), a transformação atual precisará ser preservada. Especificamente, a transformação definida acima precisa ser pós-multiplicada (ou multiplicada à direita) pela transformação atual.
Aí está. Aqui está uma jogada que mostra isso em ação. Role com a roda do mouse sobre os pontos e você verá que eles permanecem consistentemente. (Testado apenas no Chrome.) Http://plnkr.co/edit/3aqsWHPLlSXJ9JCcJzgH?p=preview
fonte
Aqui está a minha solução para uma imagem orientada para o centro:
fonte
Aqui está uma maneira alternativa de fazer isso que usa setTransform () em vez de scale () e translate (). Tudo é armazenado no mesmo objeto. A tela é assumida como 0,0 na página, caso contrário você precisará subtrair sua posição das cordas da página.
Código de acompanhamento para lidar com o pan:
Para obter a resposta, considere que as mesmas coordenadas da página precisam corresponder às mesmas da tela antes e depois do zoom. Então você pode fazer alguma álgebra a partir desta equação:
(pageCoords - tradução) / scale = canvasCoords
fonte
Quero colocar aqui algumas informações para aqueles que desenham e movem separadamente a imagem e a aumentam.
Isso pode ser útil quando você deseja armazenar zooms e posição da janela de visualização.
Aqui está a gaveta:
Observe a escala DEVE ser a primeira .
E aqui está o zoomer:
e, é claro, precisaríamos de um arrastador:
fonte
fonte
Aqui está uma implementação de código da resposta de @ tatarize, usando PIXI.js. Eu tenho uma viewport olhando parte de uma imagem muito grande (por exemplo, estilo do Google Maps).
$canvasContainer
é o meu contêiner html.imageContainer
é o meu contêiner PIXI que contém a imagem.mousePosOnImage
é a posição do mouse em relação à imagem inteira (não apenas à porta de visualização).Aqui está como eu consegui a posição do mouse:
fonte
Você precisa entender o espaço no mundo (ao contrário do espaço na tela) antes e depois do zoom e depois traduzir pelo delta.
A posição do mouse está no espaço da tela, portanto você deve transformá-lo no espaço mundial. A transformação simples deve ser semelhante a esta:
fonte
você pode usar a função scrollto (x, y) para manipular a posição da barra de rolagem até o ponto que precisa ser mostrado após o zoom. Para encontrar a posição do mouse, use event.clientX e event.clientY. isso vai te ajudar
fonte
Uma coisa importante ... se você tem algo como:
Você precisa fazer a coisa equivalente na tela:
fonte