Vergrößern und Verkleinern mit Stick Point ist ein regelmäßiger Anwendungsfall, den wir bei Design- oder Builder-Tools wie Figma antreffen. In diesem Blog stelle ich einen grundlegenden Algorithmus zur Handhabung mit Javascript, HTML und CSS vor.
Vorführung
1. Erstellen Sie einen Container und ein skalierbares Element
<div id="app"> <div class="parent"> <div class="scalable-child"></div> </div> </div>
.scalable-child { width: 300px; height: 300px; position: relative; top: 0; left: 0; pointer-events: none; transform-origin: left top; background-image: url('https://cdn4.vectorstock.com/i/1000x1000/17/58/caro-pattern-background-vector-2261758.jpg'); background-size: contain; } .parent { position: relative; background-color: white; width: 100vw; height: 100vh; }
In diesem Beispiel verwende ich ein Div als skalierbares Element mit der Klasse „scalable-child“ und sein Container ist ein Div mit der Klasse „parent“.
Bitte beachten Sie für einige Eigenschaften:
Oben links: 0 ist die Standardposition
Pointer-event: keine, da wir das Ereignis zum übergeordneten Element hinzufügen. Wenn pointer-event !== none, schlägt der Algorithmus fehl.
Transformationsursprung: links oben, das macht den Koordinatenursprung zur Berechnung der Position
2. Rad-Ereignis-Listener hinzufügen
const parent = document.querySelector('.parent'); const child = document.querySelector('.scalable-child');
parent.addEventListener('wheel', wheelEventHandler, { passive: false, capture: true, });
Wir werden WheelEvent verwenden, um das Vergrößern, Verkleinern und das Bewegen des untergeordneten Elements zu verwalten
Hinweis: Dieses Beispiel zeigt nur das Trackpad. Sie müssen auch Ereignisse für Hotkeys wie (Strg +, Strg -) oder Maus verarbeiten.
let left = 0; let top = 0; let scale = 1; const wheelEventHandler = (e) => { e.preventDefault(); // Handle zoom with touch pad and hot key. const isZooming = e.ctrlKey || e.metaKey; let newValues = {}; if (isZooming) { newValues = calculateOnZooming(e, scale, left, top); } else { newValues = calculateOnMoving(e, scale, left, top); } left = newValues.newLeft; top = newValues.newTop; scale = newValues.newScale; Object.assign(child.style, { transform: `scale(${scale})`, left: `${left}px`, top: `${top}px`, }); };
Zuerst haben wir die Variable isZooming, um zu prüfen, ob das untergeordnete Element gezoomt oder verschoben wird.
Dann berechnen wir die neue Position und Skalierung für das untergeordnete Element. Links, oben und Skala werden als gemäßigte Variablen verwendet.
Und es ist Zeit, den Algorithmus auf zwei Berechnungsfunktionen zu konzentrieren:
3. Berechnen Sie beim Zoomen
const calculateOnZooming = (e, oldScale, oldLeft, oldTop) => { let newScale = oldScale - e.deltaY * oldScale * 0.01; newScale = Math.max(newScale, 0.1); const newLeft = oldLeft - (e.offsetX - oldLeft) * (newScale / scale - 1); const newTop = oldTop - (e.offsetY - oldTop) * (newScale / scale - 1); return { newScale, newLeft, newTop, }; };
Beim Zoomen gibt WheelEvent deltaY als Skalierungsverhältnis zurück und wir können es zur Berechnung von newScale verwenden
deltaY > 0 => herauszoomen
deltaY < 0 => Vergrößern
Das detalScale = e.deltaY * oldScale * 0.01 zur Steuerung der Skalierungsgeschwindigkeit
Sehen wir uns das Bild unten an, um besser zu verstehen, wie die Variablen newLeft und newTop berechnet werden:
Beginnen Sie mit dem Vergrößern des Kindes, wenn sich die Maus am Punkt A befindet. Zu diesem Zeitpunkt können wir einige Werte erhalten:
e.offsetX: Abstand zwischen der Maus und dem linken Rand des Elternteils
e.offsetY: Abstand zwischen der Maus und der Oberkante des Elternteils
links: der linke Stilwert des aktuellen Kindes
oben: Top-Stilwert des aktuellen Kindes
Das Kind wird von Maßstabsverhältnis zu Maßstabsverhältnis skaliert, und Punkt A geht zu A’.
Um einen Punkt A (mit dem übergeordneten Punkt) kleben zu lassen, müssen wir deltaX und deltaY berechnen und dann den untergeordneten Punkt mit genau px zurücksetzen.
detalX = x’ - x
= x * (Skala’ / Skala) – x
= x * (Skala’ / Skala - 1)
= (e.offsetX - left) * (scale’ / scale - 1)
detalY = y’ - y
= y * (Skala’ / Skala) – y
= y * (Skala’ / Skala - 1)
= (e.offsetY - top) * (scale’ / scale - 1)
newLeft = links - detalX
newTop = oben - detalY
4. Berechnen Sie den Umzug
const calculateOnMoving = (e, oldScale, oldLeft, oldTop) => { return { newLeft: oldLeft - e.deltaX * 2, newTop: oldTop - e.deltaY * 2, newScale: oldScale, }; };
Bei einem bewegten Ereignis müssen wir nur die Werte newLeft und newTop berechnen. Und wir *2 jeden Deltawert, um auch die Geschwindigkeit zu erhöhen.
Das ist alles, was wir bewältigen müssen. Ich hoffe, es ist hilfreich. Vielen Dank fürs Zuschauen!
Den vollständigen Quellcode können Sie hier einsehen.
Das obige ist der detaillierte Inhalt vonVergrößern/verkleinern Sie einen klebrigen Punkt auf der Leinwand. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!