Je veux pouvoir zoomer sur le point sous la souris dans un canevas HTML 5, comme un zoom sur Google Maps . Comment puis-je y parvenir?
javascript
html
canvas
csiz
la source
la source
Réponses:
La meilleure solution consiste simplement à déplacer la position de la fenêtre en fonction de la modification du zoom. Le point de zoom est simplement le point de l'ancien zoom et du nouveau zoom que vous souhaitez conserver. C'est-à-dire que la fenêtre pré-zoomée et la fenêtre post-zoomée ont le même point de zoom par rapport à la fenêtre. Étant donné que nous mettons à l'échelle par rapport à l'origine. Vous pouvez ajuster la position de la fenêtre en conséquence:
Donc, vraiment, vous pouvez simplement faire un panoramique vers le bas et vers la droite lorsque vous effectuez un zoom avant, en fonction du facteur de zoom avant, par rapport au point sur lequel vous avez zoomé.
la source
Enfin résolu:
La clé, comme l' a souligné @Tatarize , est de calculer la position de l'axe de telle sorte que le point de zoom (pointeur de la souris) reste au même endroit après le zoom.
À l'origine, la souris est à une distance
mouse/scale
du coin, nous voulons que le point sous la souris reste au même endroit après le zoom, mais celui-ci estmouse/new_scale
éloigné du coin. Par conséquent, nous devons décaler lesorigin
(coordonnées du coin) pour en tenir compte.Le code restant doit ensuite appliquer la mise à l'échelle et se traduire dans le contexte de dessin afin que son origine coïncide avec le coin du canevas.
la source
C'est en fait un problème très difficile (mathématiquement), et je travaille presque sur la même chose. J'ai posé une question similaire sur Stackoverflow mais je n'ai obtenu aucune réponse, mais j'ai posté dans DocType (StackOverflow pour HTML / CSS) et j'ai obtenu une réponse. Découvrez-le http://doctype.com/javascript-image-zoom-css3-transforms-calculate-origin-example
Je suis en train de créer un plugin jQuery qui fait cela (zoom de style Google Maps à l'aide des transformations CSS3). J'ai le zoom sur le curseur de la souris qui fonctionne bien, en essayant toujours de comprendre comment permettre à l'utilisateur de faire glisser la toile comme vous pouvez le faire dans Google Maps. Quand je le ferai fonctionner, je publierai le code ici, mais consultez le lien ci-dessus pour la partie souris-zoom-point.
Je ne savais pas qu'il y avait des méthodes de mise à l'échelle et de traduction sur le contexte de Canvas, vous pouvez obtenir la même chose en utilisant CSS3 par exemple. en utilisant jQuery:
Assurez-vous de définir l'origine de la transformation CSS3 sur 0, 0 (-moz-transform-origin: 0 0). L'utilisation de la transformation CSS3 vous permet de zoomer sur n'importe quoi, assurez-vous simplement que le conteneur DIV est défini sur overflow: hidden pour empêcher les bords zoomés de se répandre sur les côtés.
Que vous utilisiez les transformations CSS3 ou les propres méthodes de mise à l'échelle et de traduction du canevas dépend de vous, mais vérifiez le lien ci-dessus pour les calculs.
Mise à jour: Meh! Je vais simplement poster le code ici plutôt que de vous faire suivre un lien:
Vous devrez bien sûr l'adapter pour utiliser l'échelle du canevas et les méthodes de traduction.
Mise à jour 2: Je viens de remarquer que j'utilise transform-origin avec translate. J'ai réussi à mettre en œuvre une version qui utilise simplement l'échelle et la traduction seule, vérifiez-la ici http://www.dominicpettifer.co.uk/Files/Mosaic/MosaicTest.html Attendez que les images soient téléchargées puis utilisez votre molette de la souris pour zoomer, prend également en charge le panoramique en faisant glisser l'image autour. Il utilise des transformations CSS3, mais vous devriez pouvoir utiliser les mêmes calculs pour votre canevas.
la source
J'ai rencontré ce problème en utilisant C ++, que je n'aurais probablement pas dû avoir Je viens d'utiliser des matrices OpenGL pour commencer ... de toute façon, si vous utilisez un contrôle dont l'origine est le coin supérieur gauche, et que vous voulez un panoramique / zoom comme google maps, voici la mise en page (en utilisant allegro comme gestionnaire d'événements):
la source
J'aime la réponse de Tatarize , mais je vais proposer une alternative. C'est un problème trivial d'algèbre linéaire, et la méthode que je présente fonctionne bien avec le panoramique, le zoom, l'inclinaison, etc. Autrement dit, cela fonctionne bien si votre image est déjà transformée.
Lorsqu'une matrice est mise à l'échelle, l'échelle est au point (0, 0). Donc, si vous avez une image et que vous la mettez à l'échelle d'un facteur 2, le point en bas à droite doublera dans les directions x et y (en utilisant la convention selon laquelle [0, 0] est le coin supérieur gauche de l'image).
Si, à la place, vous souhaitez agrandir l'image autour du centre, la solution est la suivante: (1) traduisez l'image de telle sorte que son centre soit à (0, 0); (2) mettre l'image à l'échelle par des facteurs x et y; (3) traduire l'image en arrière. c'est à dire
Plus abstraitement, la même stratégie fonctionne pour n'importe quel point. Si, par exemple, vous souhaitez mettre l'image à l'échelle en un point P:
Et enfin, si l'image est déjà transformée d'une manière ou d'une autre (par exemple, si elle est tournée, inclinée, traduite ou mise à l'échelle), la transformation actuelle doit être préservée. Plus précisément, la transformation définie ci-dessus doit être post-multipliée (ou multipliée à droite) par la transformation actuelle.
Voilà. Voici un plunk qui montre cela en action. Faites défiler avec la molette de la souris sur les points et vous verrez qu'ils restent toujours en place. (Testé dans Chrome uniquement.) Http://plnkr.co/edit/3aqsWHPLlSXJ9JCcJzgH?p=preview
la source
Voici ma solution pour une image centrée:
la source
Voici une autre façon de le faire qui utilise setTransform () au lieu de scale () et translate (). Tout est stocké dans le même objet. Le canevas est supposé être à 0,0 sur la page, sinon vous devrez soustraire sa position des coordonnées de la page.
Code d'accompagnement pour gérer le panoramique:
Pour obtenir la réponse vous-même, considérez que les mêmes coordonnées de page doivent correspondre aux mêmes coordonnées de canevas avant et après le zoom. Ensuite, vous pouvez faire de l'algèbre à partir de cette équation:
(pageCoords - translation) / scale = canvasCoords
la source
Je veux mettre ici quelques informations pour ceux qui font séparément le dessin de l'image et le zoom en mouvement.
Cela peut être utile lorsque vous souhaitez stocker des zooms et la position de la fenêtre.
Voici le tiroir:
L' échelle de notification DOIT être la première .
Et voici zoomer:
et, bien sûr, nous aurions besoin d'un dragger:
la source
la source
Voici une implémentation de code de la réponse de @ tatarize, en utilisant PIXI.js. J'ai une fenêtre qui regarde une partie d'une très grande image (par exemple le style google maps).
$canvasContainer
est mon conteneur html.imageContainer
est mon conteneur PIXI qui contient l'image.mousePosOnImage
est la position de la souris par rapport à l'image entière (pas seulement le port de vue).Voici comment j'ai obtenu la position de la souris:
la source
Vous devez obtenir le point dans l'espace mondial (par opposition à l'espace écran) avant et après le zoom, puis traduire par le delta.
La position de la souris est dans l'espace d'écran, vous devez donc la transformer en espace mondial. La transformation simple devrait être similaire à ceci:
la source
vous pouvez utiliser la fonction scrollto (x, y) pour gérer la position de la barre de défilement jusqu'au point que vous devez afficher après le zoom.pour trouver la position de la souris, utilisez event.clientX et event.clientY. cela t'aidera
la source
Une chose importante ... si vous avez quelque chose comme:
Vous devez faire la chose équivalente dans la toile:
la source