Ich möchte in der Lage sein, den Punkt unter der Maus in einer HTML 5-Zeichenfläche zu vergrößern, wie z. B. das Zoomen in Google Maps . Wie kann ich das erreichen?
javascript
html
canvas
csiz
quelle
quelle
Antworten:
Die bessere Lösung besteht darin, die Position des Ansichtsfensters basierend auf der Änderung des Zooms einfach zu verschieben. Der Zoompunkt ist einfach der Punkt im alten Zoom und im neuen Zoom, den Sie beibehalten möchten. Das heißt, das vorgezoomte Ansichtsfenster und das nachgezoomte Ansichtsfenster haben denselben Zoompunkt relativ zum Ansichtsfenster. Vorausgesetzt, wir skalieren relativ zum Ursprung. Sie können die Position des Ansichtsfensters entsprechend anpassen:
Sie können also beim Vergrößern einfach nach unten und rechts schwenken, um einen Faktor, um wie viel Sie hineingezoomt haben, relativ zu dem Punkt, auf den Sie gezoomt haben.
quelle
Endlich gelöst:
Wie @Tatarize hervorhob , besteht der Schlüssel darin, die Achsenposition so zu berechnen, dass der Zoompunkt (Mauszeiger) nach dem Zoom an derselben Stelle bleibt.
Ursprünglich befindet sich die Maus in einem Abstand
mouse/scale
von der Ecke. Wir möchten, dass der Punkt unter der Maus nach dem Zoom an derselben Stelle bleibt, aber dies istmouse/new_scale
von der Ecke entfernt. Deshalb müssen wir dieorigin
(Koordinaten der Ecke) verschieben, um dies zu berücksichtigen.Der verbleibende Code muss dann die Skalierung anwenden und in den Zeichnungskontext übersetzen, damit sein Ursprung mit der Canvas-Ecke übereinstimmt.
quelle
Dies ist tatsächlich ein sehr schwieriges Problem (mathematisch), und ich arbeite fast an der gleichen Sache. Ich habe eine ähnliche Frage zu Stackoverflow gestellt, aber keine Antwort erhalten, aber in DocType (StackOverflow für HTML / CSS) gepostet und eine Antwort erhalten. Überprüfen Sie es heraus http://doctype.com/javascript-image-zoom-css3-transforms-calculate-origin-example
Ich bin gerade dabei, ein jQuery-Plugin zu erstellen, das dies tut (Zoom im Google Maps-Stil mithilfe von CSS3-Transformationen). Ich habe das Zoom-zu-Maus-Cursor-Bit in Ordnung und versuche immer noch herauszufinden, wie der Benutzer die Leinwand wie in Google Maps verschieben kann. Wenn es funktioniert, werde ich hier eine Postleitzahl veröffentlichen, aber den obigen Link für den Maus-Zoom-to-Point-Teil lesen.
Ich wusste nicht, dass es Skalierungs- und Übersetzungsmethoden im Canvas-Kontext gibt. Mit CSS3 können Sie dasselbe erreichen, z. Verwenden von jQuery:
Stellen Sie sicher, dass Sie den CSS3-Transformationsursprung auf 0, 0 setzen (-moz-Transformationsursprung: 0 0). Mit der CSS3-Transformation können Sie alles vergrößern. Stellen Sie lediglich sicher, dass der Container-DIV auf Überlauf eingestellt ist: Ausgeblendet, um zu verhindern, dass die gezoomten Kanten aus den Seiten herauslaufen.
Es liegt an Ihnen, ob Sie CSS3-Transformationen oder Canvas-eigene Skalierungs- und Übersetzungsmethoden verwenden. Überprüfen Sie jedoch den obigen Link für die Berechnungen.
Update: Meh! Ich werde nur den Code hier posten, anstatt Sie dazu zu bringen, einem Link zu folgen:
Sie müssen es natürlich anpassen, um die Canvas-Skala zu verwenden und Methoden zu übersetzen.
Update 2: Ich habe gerade bemerkt, dass ich transform-origin zusammen mit translate verwende. Ich habe es geschafft, eine Version zu implementieren, die nur Skalierung und Übersetzung selbst verwendet. Schauen Sie hier nach: http://www.dominicpettifer.co.uk/Files/Mosaic/MosaicTest.html Warten Sie, bis die Bilder heruntergeladen wurden, und verwenden Sie dann Ihre Mausrad zum Zoomen, unterstützt auch das Schwenken durch Ziehen des Bildes. Es werden CSS3-Transformationen verwendet, aber Sie sollten in der Lage sein, dieselben Berechnungen für Ihre Leinwand zu verwenden.
quelle
Ich bin auf dieses Problem mit C ++ gestoßen, was ich wahrscheinlich nicht hätte tun sollen. Ich habe zunächst nur OpenGL-Matrizen verwendet. Wie auch immer, wenn Sie ein Steuerelement verwenden, dessen Ursprung in der oberen linken Ecke liegt, und Sie möchten schwenken / zoomen Hier ist wie bei Google Maps das Layout (mit Allegro als Event-Handler):
quelle
Ich mag die Antwort von Tatarize , aber ich werde eine Alternative anbieten . Dies ist ein triviales lineares Algebra-Problem, und die von mir vorgestellte Methode funktioniert gut mit Schwenken, Zoomen, Neigen usw. Das heißt, es funktioniert gut, wenn Ihr Bild bereits transformiert ist.
Wenn eine Matrix skaliert wird, befindet sich die Skalierung am Punkt (0, 0). Wenn Sie also ein Bild haben und es um den Faktor 2 skalieren, verdoppelt sich der Punkt unten rechts sowohl in x- als auch in y-Richtung (unter Verwendung der Konvention, dass [0, 0] oben links im Bild ist).
Wenn Sie stattdessen das Bild um die Mitte zoomen möchten, lautet die Lösung wie folgt: (1) Verschieben Sie das Bild so, dass seine Mitte bei (0, 0) liegt. (2) Skalieren des Bildes um x- und y-Faktoren; (3) Übersetzen Sie das Bild zurück. dh
Noch abstrakter funktioniert dieselbe Strategie für jeden Punkt. Wenn Sie beispielsweise das Bild an einem Punkt P skalieren möchten:
Und wenn das Bild bereits auf irgendeine Weise transformiert wurde (z. B. wenn es gedreht, verzerrt, übersetzt oder skaliert wurde), muss die aktuelle Transformation beibehalten werden. Insbesondere muss die oben definierte Transformation mit der aktuellen Transformation nachmultipliziert (oder rechtsmultipliziert) werden.
Hier hast du es. Hier ist ein Plunk, der dies in Aktion zeigt. Scrollen Sie mit dem Mausrad auf den Punkten und Sie werden sehen, dass sie konstant stehen bleiben. (Nur in Chrome getestet.) Http://plnkr.co/edit/3aqsWHPLlSXJ9JCcJzgH?p=preview
quelle
Hier ist meine Lösung für ein zentrumsorientiertes Bild:
quelle
Hier ist eine alternative Methode, bei der setTransform () anstelle von scale () und translate () verwendet wird. Alles ist im selben Objekt gespeichert. Es wird angenommen, dass sich die Zeichenfläche auf der Seite bei 0,0 befindet. Andernfalls müssen Sie ihre Position von den Seitenkoordinaten abziehen.
Begleitcode für das Schwenken:
Um die Antwort selbst abzuleiten, müssen Sie berücksichtigen, dass dieselben Seitenkoordinaten vor und nach dem Zoom mit denselben Canvas-Koordinaten übereinstimmen müssen. Dann können Sie ausgehend von dieser Gleichung eine Algebra machen:
(pageCoords - Übersetzung) / scale = canvasCoords
quelle
Ich möchte hier einige Informationen für diejenigen einfügen, die Bilder separat zeichnen und bewegen - zoomen.
Dies kann nützlich sein, wenn Sie Zooms und die Position des Ansichtsfensters speichern möchten.
Hier ist Schublade:
Hinweis Skala muss zuerst sein .
Und hier ist Zoomer:
und natürlich brauchen wir einen schlepper:
quelle
quelle
Hier ist eine Code-Implementierung der Antwort von @ tatarize unter Verwendung von PIXI.js. Ich habe ein Ansichtsfenster, das einen Teil eines sehr großen Bildes betrachtet (z. B. Google Maps-Stil).
$canvasContainer
ist mein HTML-Container.imageContainer
ist mein PIXI-Container, der das Bild enthält.mousePosOnImage
ist die Mausposition relativ zum gesamten Bild (nicht nur zum Ansichtsfenster).So habe ich die Mausposition erhalten:
quelle
Sie müssen den Punkt im Weltraum (im Gegensatz zum Bildschirmbereich) vor und nach dem Zoomen ermitteln und dann durch das Delta übersetzen.
Die Mausposition befindet sich im Bildschirmbereich, daher müssen Sie sie in den Weltraum umwandeln. Die einfache Transformation sollte folgendermaßen aussehen:
quelle
Mit der Funktion scrollto (x, y) können Sie die Position der Bildlaufleiste bis zu dem Punkt behandeln, der nach dem Zoomen angezeigt werden muss. Um die Position der Maus zu ermitteln, verwenden Sie event.clientX und event.clientY. das wird dir helfen
quelle
Eine wichtige Sache ... wenn Sie etwas haben wie:
Sie müssen das Äquivalente auf Leinwand machen:
quelle