Dalam proyek terbaru, UI merancang animasi latar belakang dengan efek gelombang air. Namun, tidak ada animasi gif atau svg. Saya mencoba menggunakan CSS untuk mengimplementasikannya, tetapi efek animasinya tidak terlalu bagus menggunakan kurva Bezier untuk mencapainya. , saya memikirkan berbagai diagram bentuk gelombang yang pernah saya lihat sebelumnya, jadi saya berpikir untuk mensimulasikannya secara singkat menggunakan gambar fungsi trigonometri.
1. Gambarlah gambar fungsi sinEkspresi fungsi sin adalah sebagai berikut,
y=Asin(wx+φ)+h
Diantaranya, A melambangkan amplitudo, ω melambangkan frekuensi sudut (ω=2π/T, T adalah periode fungsi), φ melambangkan fase awal, dan h melambangkan panjang translasi bayangan ke arah positif. sumbu y; (Perlu diperhatikan di sini: h dalam matematika aslinya berarti terjemahan ke atas, tetapi sistem koordinat layar digunakan di kanvas, yaitu sudut kiri atas adalah titik asal, dan h berarti terjemahan ke bawah);
Kode gambarnya adalah sebagai berikut:
(1) Tambahkan tag kanvas
<kanvas id=kanvas></kanvas>
(2) Tambahkan gaya css dan atur lebar dan tinggi kanvas
html,tubuh { padding: 0; margin: 0; lebar: 100%; tinggi: 100%;}kanvas { lebar: 100%;}
(3) Gambarlah gambar fungsi
var kanvas = document.getElementById(kanvas), ctx = kanvas.getContext('2d'), lebar = kanvas.lebar = kanvas.offsetWidth, tinggi = kanvas.tinggi = kanvas.offsetHeight;//Deklarasikan parameter var A=50, W=1 / 50, Q=0, H= tinggi / 2;//Metode menggambar (fungsi draw(){ ctx.clearRect(0, 0, lebar, height);//Hapus kanvas ctx.beginPath(); //Jalur awal ctx.strokeStyle=#000; //Atur warna garis ctx.lineWidth = 1; //Atur lebar garis ctx.moveTo(0, height /2) ; //Posisi titik awal untuk (misalkan x = 0; x <= lebar; x++) {// Gambarkan var dari x yang bersesuaian dengan y = A*Math.sin(W*x+Q) +H ctx.lineTo(x, y) } ctx.stroke(); //Gambar jalur ctx.closePath(); //Tutup jalur})()
Dengan cara ini kita mendapatkan gambar berikut:
2. Tambahkan animasi ke gambar fungsiApa yang diperoleh di atas adalah gambar fungsi statis, dan bentuk gelombang atau gelombang air yang biasa kita lihat berubah terus menerus seiring waktu. Di sini kita perlu menggunakan parameter fase φ pada langkah sebelumnya, (js adalah Q dalam kode ), kita dapat terus menerus. menambah atau mengurangi φ seiring waktu untuk mendapatkan gambar yang berbeda pada waktu yang berbeda; gunakan window.requestAnimationFrame untuk mengimplementasikan animasi bingkai;
Ubah kode di atas menjadi:
var kanvas = document.getElementById(kanvas), ctx = kanvas.getContext('2d'), lebar = kanvas.lebar = kanvas.offsetWidth, tinggi = kanvas.tinggi = kanvas.offsetHeight;//Deklarasikan parameter var A=50, W=1 / 50, Q=0, H= tinggi / 2;//Metode menggambar (fungsi draw(){ ctx.clearRect(0, 0, lebar, height);//Hapus kanvas ctx.beginPath(); //Jalur awal ctx.strokeStyle=#000; //Atur warna garis ctx.lineWidth = 1; //Atur lebar garis ctx.moveTo(0, height /2) ; //Posisi titik awal untuk (misalkan x = 0; x <= lebar; x++) {// Gambarkan var dari x yang bersesuaian dengan y = A*Math.sin(W*x+Q) +H ctx.lineTo(x, y) } ctx.stroke(); //Gambar jalur ctx.closePath(); //Tutup jalur})()
Efeknya adalah sebagai berikut (perangkat lunak tangkapan layar Zhazha):
3. Gambarlah jalur yang terisi lengkapWalaupun jalur di atas tertutup, namun tidak memenuhi bagian yang perlu kita isi, efek pengisian langsungnya adalah sebagai berikut:
Jalur yang terisi penuh akan terlihat seperti ini:
Setelah menutup path, buatlah warna gradien sebagai warna isiannya. Kodenya adalah sebagai berikut:
var lingrad = ctx.createLinearGradient(0,0,width,0); lingrad.addColorStop(0, 'rgba(0,186,128,0.8)'); lingrad.addColorStop(1, 'rgba(111,224,195,1)'); draw(){ window.requestAnimationFrame(draw); ctx.clearRect(0, 0, lebar, tinggi); ctx.beginPath(); ctx.strokeStyle=#000; ctx.fillStyle = ctx.lineWidth = 1; =kecepatan; untuk (misalkan x = 0; x <= lebar; x++) { var y = A*Matematika.sin(W*x+Q) +H; ctx.lineTo(x, y); } ctx.lineTo(lebar, tinggi); ctx.lineTo(0, tinggi); .closePath();})()
Efeknya adalah sebagai berikut:
4. Meningkatkan animasi gelombang air1. Pertama, Anda dapat melapisi bentuk gelombang frekuensi yang lebih tinggi pada bentuk gelombang di atas untuk membuat bentuk gelombang tidak beraturan.
var s = 0,1*Math.sin(x/150)+1;var y = A*Math.sin(W*x+Q) +H;y=y*s;
2. Tambahkan bentuk gelombang lain dengan perubahan fase berbeda, dan pengisian gradiennya berlawanan dengan arah gradien sebelumnya untuk membentuk efek bayangan yang tumpang tindih dan atur efek tumpang tindih jalur globalCompositeOperation;
var kanvas = dokumen.getElementById(kanvas), ctx = kanvas.getContext('2d'), lebar = kanvas.lebar = kanvas.offsetWidth, tinggi = kanvas.tinggi = kanvas.offsetHeight;var A=30, W=1 / 200, Q=0, T= tinggi / 2;var A2=30, W2=1/300, Q2=0, H2= tinggi / 2;var speed=-0,01;var speed2=-0,02;var lingrad = ctx.createLinearGradient(0,0,width,0);lingrad.addColorStop(0, 'rgba(0,186,128,0.8)');lingrad.addColorStop( 1, 'rgba(111.224.195,1)'); var lingrad2 = ctx.createLinearGradient(0,0,width,0);lingrad2.addColorStop(0,'rgba(111,224,195,1)');lingrad2.addColorStop(1, 'rgba(0,186,128,0.8)'); (fungsi draw(){ window.requestAnimationFrame(draw); ctx.clearRect(0, 0, width, height); ctx.beginPath(); ctx.fillStyle = lingrad; ctx.moveTo(0, height /2); = 0; x <= lebar; x++) { var s = 0,1*Matematika.sin(x/150)+1; A*Math.sin(W*x+Q) +H; y=y*s; ctx.lineTo(x, y); ctx.lineTo(lebar, tinggi); .fill(); ctx.closePath() //Atur efek tumpang tindih ctx.globalCompositeOperation = tujuan-over //Gambarkan bentuk gelombang kedua ctx.beginPath(); ctx.fillStyle = lingrad2; Q2+=kecepatan2; untuk (misalkan x = 0; x < lebar; x++) { var y = A2*Math.sin(x*W2+Q2) +H2; ; } ctx.lineTo(lebar,tinggi); ctx.lineTo(0,tinggi()); ctx.closePath();})()
Di atas adalah keseluruhan isi artikel ini, saya harap dapat bermanfaat untuk pembelajaran semua orang. Saya juga berharap semua orang mendukung VeVb Wulin Network.