Efek dari menghidupkan halaman realistis di JS

Saya sajikan untuk perhatian Anda - salah satu opsi yang mungkin untuk menerapkan trik yang agak lucu untuk menciptakan efek pergantian halaman yang realistis.



Demo dan dokumentasi
Github .

Saya menerapkan efek yang sama untuk waktu yang lama, kembali ke universitas dan di Delphi. Ternyata cukup layak, meskipun saya menghabiskan banyak waktu saat itu. Sekarang - selama masa isolasi diri, menjadi menarik untuk mengimplementasikan sesuatu yang serupa pada JS, untuk PC dan perangkat seluler.

Terus terang, saya tidak yakin tentang penerapan praktis dari efek ini, dan saya pikir dalam banyak kasus - tidak ada yang lebih baik daripada perubahan gambar sederhana tanpa animasi apa pun. Tetapi sangat mungkin untuk menggunakan, katakanlah di situs restoran, untuk menerbitkan menu (tetapi yang paling penting - itu akan digandakan di sebelah tautan!).

Semuanya ditulis dalam naskah. Tidak ada perpustakaan pihak ketiga yang digunakan. Tidak ada ketergantungan.

Fitur perpustakaan utama


  • Bekerja baik dengan gambar sederhana, dengan rendering di atas kanvas, dan dengan blok html - menggunakan transformasi css
  • Sistem konfigurasi yang cukup fleksibel dan API sederhana
  • Mendukung perangkat seluler
  • Orientasi otomatis berubah antara mode potret dan lansekap

Kode ditulis dengan mata hanya pada ES6 +, dan sistem modular juga ES6. Dukungan browser rata-rata 90% berdasarkan caniuse.com.

Instalasi


Instalasi dimungkinkan dari npm:

npm install page-flip

Atau, unduh file yang dikumpulkan dari repositori.

Pilihan inisialisasi pustaka dasar mungkin seperti ini:

<div id="book">
    <div class="my-page">
        Page one
    </div>
    <div class="my-page">
        Page two
    </div>
    <div class="my-page">
        Page three
    </div>
    <div class="my-page">
        Page four
    </div>
</div>

import {PageFlip} from 'page-flip';
const pageFlip = new PageFlip(document.getElementById('book'),
    {
        width: 400, // required parameter - base page width
        height: 600  // required parameter - base page height
    }
);

pageFlip.loadFromHTML(document.querySelectorAll('.my-page'));

Deskripsi dan spesifikasi API yang lebih terperinci dapat ditemukan di tautan di atas.
Saya ingin berbicara tentang beberapa masalah dan nuansa yang saya temui selama pengembangan.

Perhitungan


Hal pertama yang harus dibicarakan adalah model matematika. Pada prinsipnya, semua perhitungannya cukup sepele, tetapi saya butuh banyak waktu.

Tugas utama yang perlu dipecahkan adalah menentukan sudut transformasi dari halaman balik. Mari kita lihat gambar berikut:



Titik "A" menunjukkan titik sentuh saat ini di buku. Berdasarkan posisi titik ini - perlu untuk melakukan perhitungan lebih lanjut.

Untuk menentukan sudut - perlu untuk menghitung dua nilai - jarak dari titik A ke batas atas dan kanan buku. Pada gambar di bawah, masing-masing ditunjukkan oleh T dan L.



G adalah diagonal sudut, dapat dihitung dengan teorema Pythagoras.

Sebagai hasilnya, untuk menghitung rotasi gambar, Anda dapat menggunakan rumus berikut: angle = - 2 * acos (L / G), dan yang paling penting, jangan lupa bahwa titik transformasi dalam kasus ini adalah sudut kiri atas halaman.

Setelah menghitung sudut - bagian yang paling memakan waktu tetap ada - ini menghitung visibilitas halaman. Apa yang seharusnya tampaknya perlu untuk pergi, dan sisanya, masing-masing - untuk memangkas.

Pertama, Anda perlu menemukan titik persimpangan halaman untuk dibalik dengan batas buku. Dalam gambar mereka ditunjukkan oleh poin B dan C.



Saya melakukan ini dengan cara yang paling sederhana dan paling sederhana - di dahi. Dia membangun persamaan garis dengan dua titik, dan kemudian mencari titik persimpangan mereka.

Setelah menemukan semua titik persimpangan, kami menentukan simpul area visibilitas - dan pada titik-titik ini kami sudah memotong halaman yang akan dibalik.



Pada dasarnya, semua matematika di sini bermuara pada dua hal:

  • perhitungan sudut transformasi
  • perhitungan visibilitas halaman

Shading sudah berdasarkan perhitungan yang dibuat sebelumnya.

Sekarang mari kita beralih ke beberapa poin yang harus kita hadapi selama implementasi.

Algoritma umum cukup sederhana dan turun ke halaman balik dan memotong.

Dalam hal kanvas dan gambar sederhana, semuanya cukup sederhana. Setelah melakukan perhitungan, metode konteks kanvas 2d seperti menerjemahkan, memutar, dan klip digunakan.
Dengan blok html sedikit lebih rumit. Dan jika tidak ada masalah dengan rotasi - berkat transformasi css, maka dengan memotong semuanya ternyata menjadi sedikit lebih buruk.

Akibatnya, cara termudah adalah dengan menggunakan clip-path dan properti css pada gambar - poligon. Tetapi sebelum mengatur simpul poligon untuk tanam, perlu untuk mengubah koordinat titik dari kanvas "global" - menjadi titik lokal, relatif terhadap elemen html. Ini diselesaikan dengan aplikasi kebalikan dari matriks rotasi, dengan pergeseran relatif ke posisi elemen.

Masalah lain adalah penskalaan dan penentuan posisi otomatis buku. Saya mencoba untuk menyelesaikan ini dengan objek konfigurasi, yang dilewatkan selama pembuatan. Tetapi pada akhirnya, ada beberapa parameter, dan ternyata tidak cukup nyaman dan tidak jelas.

Saya pertama kali menggunakan Webpack untuk perakitan, tetapi pada akhirnya saya memutuskan untuk mencoba rollup.js, dan sangat terkejut dengan kode terakhir. Webpack masih tetap ada, karena menangani perakitan dengan cepat beberapa kali lebih cepat, dan lebih nyaman selama pengembangan.

Saya akan senang mendengar komentar dan saran untuk pengembangan perpustakaan lebih lanjut.

All Articles