Rumah  >  Artikel  >  hujung hadapan web  >  Zum masuk zum keluar titik melekit dalam kanvas

Zum masuk zum keluar titik melekit dalam kanvas

WBOY
WBOYasal
2024-07-18 05:56:57935semak imbas

Zum keluar zum masuk dengan titik tongkat ialah kes penggunaan biasa yang kami temui pada alat reka bentuk atau pembina seperti Figma. Dalam blog ini, saya akan membentangkan algoritma asas untuk mengendalikannya dengan javascript, HTML dan CSS.

Demo

Demonstrasi

Kod langkah demi langkah

1. Buat bekas dan item boleh skala

<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;
}

Dalam contoh ini, saya menggunakan div sebagai item boleh skala dengan kelas “scalable-child” dan bekasnya ialah div dengan kelas “parent”.
Sila ambil perhatian untuk beberapa hartanah:

  • Atas, kiri: 0 ialah kedudukan lalai

  • Peristiwa penuding: tiada, kerana kami akan menambah acara pada induk, jika peristiwa penuding !== tiada algoritma akan gagal.

  • Ubah-asal: atas kiri, yang menjadikan asal koordinat untuk mengira kedudukan

2. Tambahkan pendengar acara roda

const parent = document.querySelector('.parent');
const child = document.querySelector('.scalable-child');

parent.addEventListener('wheel', wheelEventHandler, {
  passive: false,
  capture: true,
});

Kami akan menggunakan WheelEvent untuk mengendalikan zum masuk, zum keluar dan kanak-kanak bergerak

Nota: contoh ini menunjukkan hanya untuk pad jejak. Anda perlu mengendalikan acara untuk kekunci pintas seperti (Ctrl +, Ctr -) atau tetikus juga.

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`,
  });
};

Pertama, kami mempunyai pembolehubah isZooming untuk menyemak sama ada mengezum atau mengalihkan elemen anak.

Kemudian kami mengira kedudukan dan skala baharu untuk elemen kanak-kanak. Kiri, atas dan skala digunakan sebagai pembolehubah sederhana.

Dan tiba masanya untuk memfokuskan algoritma pada 2 fungsi pengiraan:

3. Kira pada Zum

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,
  };
};

Apabila mengezum, wheelEvent akan mengembalikan deltaY sebagai nisbah skala dan kami boleh menggunakannya untuk mengira Skala baharu

  • deltaY > 0 => zum keluar

  • deltaY < 0 => zum masuk
    DetalScale = e.deltaY * oldScale * 0.01 untuk mengawal kelajuan penskalaan

Mari lihat imej di bawah untuk lebih memahami cara mengira pembolehubah Kiri dan Baharu baharu:

Image description
Mula mengezum masuk kanak-kanak apabila tetikus berada dalam titik A. Pada masa itu, kita boleh mendapatkan beberapa nilai:

  • e.offsetX: jarak antara tetikus ke tepi kiri ibu bapa

  • e.offsetY: jarak antara tetikus ke tepi atas ibu bapa

  • kiri: nilai gaya kiri kanak-kanak semasa

  • atas: nilai gaya teratas kanak-kanak semasa

Kanak-kanak diskalakan daripada nisbah skala kepada nisbah skala’, dan titik A pergi ke A’.
Jadi untuk menjadikan A mata melekit (dengan ibu bapa), kita perlu mengira deltaX dan deltaY kemudian gerakkan kembali anak dengan tepat px.

detalX = x’ - x
= x * (skala’ / skala) - x
= x * (skala’ / skala - 1)
= (e.offsetX - kiri) * (skala’ / skala - 1)

detalY = y’ - y
= y * (skala’ / skala) - y
= y * (skala’ / skala - 1)
= (e.offsetY - atas) * (skala’ / skala - 1)

newLeft = kiri - detalX
newTop = atas - detalY

4. Kira semasa Bergerak

const calculateOnMoving = (e, oldScale, oldLeft, oldTop) => {
  return {
    newLeft: oldLeft - e.deltaX * 2,
    newTop: oldTop - e.deltaY * 2,
    newScale: oldScale,
  };
};

Mengenai acara bergerak, kita perlu mengira hanya nilai Kiri baru dan baruAtas. Dan kami *2 setiap nilai delta untuk meningkatkan kelajuan juga.

Itu sahaja yang perlu kami tangani. Saya harap ia membantu. Terima kasih kerana menonton!
Anda boleh melihat kod sumber penuh di sini.

Atas ialah kandungan terperinci Zum masuk zum keluar titik melekit dalam kanvas. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel sebelumnya:Adakah DOM Dicipta dengan HTML?Artikel seterusnya:Adakah DOM Dicipta dengan HTML?