Heim  >  Artikel  >  Web-Frontend  >  Vergrößern/verkleinern Sie einen klebrigen Punkt auf der Leinwand

Vergrößern/verkleinern Sie einen klebrigen Punkt auf der Leinwand

WBOY
WBOYOriginal
2024-07-18 05:56:57934Durchsuche

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.

Demo

Vorführung

Code Schritt für Schritt

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:

Image description
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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Vorheriger Artikel:Wurde DOM mit HTML erfunden?Nächster Artikel:Wurde DOM mit HTML erfunden?