Seperti biasa, lihat saja gambarnya!
Efeknya adalah sebagai berikut:
Gambar HD besar!
Saya telah bekerja sebagai pembuat kode selama bertahun-tahun, tetapi mata saya yang lama redup dan saya tidak dapat melihat animasinya dengan jelas? ! Kemudian lihat tangkapan layar statis! ! !
Dampak dari skor yang berbeda adalah sebagai berikut:
Setelah menyaksikan tayangan penjualnya, mari kita lihat proses produksi produknya!
Canvas menggambar lingkaran 1. Pada vue, kode di <template lang=pug> adalah sebagai berikut:
canvas#baseCanvas adalah cincin abu-abu di bagian bawah
canvas#myCanvas adalah cincin berwarna di atas
Kita perlu menggunakan gaya css untuk membantu kita menutupi cincin berwarna di atas cincin abu-abu.
2. gaya css: 3. kode gambar gaya js-kanvasKode ini juga sangat sederhana, lihat saja canvas apinya
3-1. Di komponen vue, tentukan variabel yang diperlukan di bagian atas tag skrip.
3-2. Dalam objek metode vue, tiga metode didefinisikan:
drawBaseCanvas: digunakan untuk menggambar cincin abu-abu bagian bawah. Karena lingkaran abu-abu tidak memiliki efek animasi, gambar saja lingkaran abu-abu lengkap di awal. drawClrCanvas: digunakan untuk menggambar cincin berwarna di atas. clearCanvas: digunakan untuk membersihkan kanvas. Inilah yang dibutuhkan oleh animasi cincin berwarna. Karena inti dari efek animasi cincin kita adalah menghapus cincin berwarna sesekali, kemudian meningkatkan nilai sudut akhir dan menggambar ulang, sehingga menjadi animasi yang berkelanjutan.
Berikut kode ketiga metode tersebut:
Kode-kode pada ketiga cara diatas hampir semua aplikasi Canvas API, langsung saja baca tutorialnya.
Hanya pada metode draoClrCanvas, saat menggambar lingkaran kanvas, nilai awal dan nilai akhir diatur dalam parameter arc.
Nilai awal menentukan posisi awal gambar lingkaran, dan nilai akhir menentukan posisi akhir (sepertinya saya bilang omong kosong, tapi setelah berpikir keras tentang teks uraian pemikiran, saya tidak mau menghapusnya hahaha)
Perhitungan nilai akhir ini cukup merepotkan saya.
Mengapa variabel count perlu dihitung seperti ini?
this.grade adalah bilangan bulat positif dalam 100, yang menunjukkan skor. Itu ditentukan dalam data, dan defaultnya adalah 0 poin.
Jadi lingkaran berwarna tersebut awalnya tidak terlihat karena titik awal dan titik akhir sama-sama 0 poin.
Jika Anda mengubah nilai grade dari 0-100, nilai cincin warna kanvas juga akan berubah.
Dengan cara ini, selama kita secara bertahap mengubah nilai tingkatan dan menggambar ulang, cincin berwarna akan meningkat secara bertahap untuk mencapai efek animasi.
Efek animasi deringKarena kebutuhan khusus saya di sini, animasi perlu dipicu setiap kali pengguna beralih ke penggesek tempat kanvas berada (nantinya lebih merepotkan dan mengharuskan bagian histogram dan kanvas memiliki efek masuk sebelum animasi dimulai. Efeknya paling panjang pada gambar di atas (seperti animasi gif itu).
Jadi saya harus menggunakan wiper untuk mencapainya. Dalam fungsi panggilan balik sakelar gesek, skor nilai terus bertambah dari 0, dan gambar cincin berwarna dipicu ulang untuk mencapai efek animasi.
Swiper yang saya gunakan di vue adalah 'vue-awesome-swiper'. Langkah-langkah penggunaannya telah saya tulis di artikel lain.
Ada objek aktif dalam konfigurasi wiper di vue-data. Fungsi slideChange pada objek on adalah fungsi panggilan balik yang dipicu setiap kali penggesek membalik halaman.
Di sini saya akan membicarakan beberapa poin khusus:
(1) vm: Ini adalah variabel yang saya simpan di skrip vue. Variabel ini diinisialisasi ke null, dan kemudian di mount, variabel tersebut ditetapkan sebagai objek instance vue.
Inisialisasi data dan gambar lingkaran abu-abu
Melalui metode ini, saya mendapatkan nilai atribut grade dan gradeTarget di fungsi vue instance object-data-swiper-callback dan memodifikasinya.
ps: Saya tidak tahu apakah ini pendekatan yang bodoh. Ketika saya melakukan ini, saya mengalami masalah. Jadi ada cara yang melengkung untuk menyelamatkan negara. Jika saya memiliki solusi yang lebih baik, saya harap Anda dapat memberi saya ide baru. Terima kasih banyak sayang.
(2) (ini.activeIndex == 2 && vm.isStar) || (ini.activeIndex == 1 && !vm.isStar)
Penilaian ini dibuat karena urusan bisnis dan dapat diabaikan.
ini menunjuk ke objek wiper di fungsi wiperChange. this.activeIndex adalah properti instance wiper. Secara resmi, ini mengembalikan indeks blok aktif saat ini (blok aktivasi). Anda dapat memahami bahwa dia mengacu pada halaman mana yang sedang Anda buka, yang merupakan subskrip dari slide-swiper yang sedang Anda lihat.
Karena identitas saya sebagai pengguna, saya akan dengan tegas memutuskan apakah akan menampilkan halaman wiper sebelumnya di mana kanvas saat ini berada. Jika tidak ditampilkan, halaman sebelumnya tidak akan tergambar sama sekali, maka subskrip penggesek yang sesuai dari halaman saat ini akan menjadi (indeks-1).
Secara keseluruhan, ketika kondisi terpenuhi dan pengguna membuka halaman geser tempat kanvas berada, saya akan memicu logika menggambar cincin di if. Jika tidak, buka yang lain untuk menginisialisasi status halaman data, hapus pengatur waktu untuk menjeda animasi, dan hapus cincin berwarna.
(3)vm.aniShow
Seperti disebutkan dalam artikel terakhir saya "Menggambar Histogram dengan CSS Murni", animasi histogram harus dibahas bersama dengan animasi kanvas. Karena implementasi animasinya perlu bekerja sama dengan peralihan gesek. Itulah kodenya di sini:
Ketika atribut vue - data - aniShow menjadi true, nama kelas ani akan ditambahkan ke div.row:
Demikian pula, jika aniShow benar, tinggi kemajuan akan dilampirkan dengan nilai targetnya sendiri, yaitu tinggi kemajuan sebenarnya akan ditetapkan ke tinggi atribut gaya setelah dikonversi dalam persentase.
Pada saat ini, karena transisi kemajuan memantau perubahan ketinggian, animasi peningkatan histogram seiring dengan peningkatan ketinggian dimulai.
Di bawah nama kelas ani, penundaan transisi kemajuan mencapai efek peningkatan yang sangat terhuyung-huyung.
Mungkin membingungkan hanya dengan membaca deskripsi teks, tapi lihat lagi efeknya:
(4) Bagian kode gambar lingkaran warna
gradeTarget adalah skor sebenarnya yang merupakan hasil akhir yang akan diambil.
Nilai dimulai dari 0 dan meningkat ke ukuran gradeTarget.
Saya tidak langsung ++vm.grade di sini, dan saya tidak tahu apa yang saya pikirkan saat itu.
Jika menilai, jika nilai bertambah ke nilai target gradeTarget atau lebih besar dari nilai target, hentikan penambahan dan biarkan nilai=target nilai. Penilaian yang termasuk dalam nilai kritis. Dalam fungsi gerak, ini juga dianggap sebagai deteksi tabrakan.
Sebaliknya, jika target tidak tercapai, kanvas yang terakhir digambar akan dihapus, dan cincin berwarna baru akan digambar ulang setelah perubahan nilai secara bertahap.
(5) Letakkan semua ini di setTimeout, jeda selama 500 milidetik sebelum mengeksekusi, untuk menunggu diagram batang dan diagram cincin memasuki pasar sebelum mulai menggambar efek tambahan lingkaran.
Faktanya, kode di atas adalah proses logis yang sangat sederhana. Pembaca seharusnya dapat memahaminya setelah membaca kode tersebut satu kali.
Ide baru:
Saya membuat efek ini sejak lama. Saat saya memilah metode produksi hari ini, saya memikirkan solusi pengoptimalan untuk kode saya sendiri:
Sebenarnya, tidak perlu memanggil kembali metode menggambar lingkaran warna di pengatur waktu. Yang langsung kita ubah adalah atribut this.grade. Alangkah baiknya kita pantau perubahan atribut ini. Dengan cara ini, ketika properti ini diubah di pengatur waktu, metode dering akan dijalankan secara otomatis.
Ini masih berupa ide dan masih perlu latihan saya.
Efek tambahan teks tengah:Karena nilai adalah skor yang bertambah setiap saat, Anda dapat menggunakan data binding dua arah Vue untuk secara langsung mengikat nilai sebagai nilai skor ke tampilan DOM yang sesuai.
Terakhir, animasi diagram cincin dan batang di atas digabungkan dengan animasi untuk mengontrol penundaan animasi. Sangat sederhana.
kode sumber index.vue:
(Catatan, kode sumber telah sedikit diatur dan diekstraksi secara terpisah. Untuk kelengkapan dan untuk melindungi kode bisnis lainnya, beberapa nama variabel telah dimodifikasi, yang mungkin sedikit berbeda dari tangkapan layar sebelumnya)
<template lang='pug'> .indexs#Indexs.app-bg transisi(nama=fade) wiper#swiperBox(:options=swiperOption ref=mySwiper) wiper-slide.swiper-slide1 .container .up wiper-slide.swiper -slide2(v-if=isShow) .my-shark .up wiper-slide.swiper-slide3 .container .data-cont .data.data01 .data01-charts .row(v-for='item,index in Data' :key=index :class='aniShow ? ani:') . data-txt {{item.grade > 0 ? item.grade : 'Tidak ada data'}} .progress(:class='item.grade == 0 ? nodata : ' :style='height: ' + (aniShow ? (item.grade >= 100 ? (100 * 1,5) / 100 : item.grade == 0 ? 0,04 : item.grade * 1,5 / 100 ) : 0) +'rem') span.pg-data .minggu {{item.minggu}} .data.data02 .data02-charts .canvas-box //- kanvas dasar#baseCanvas.my-canvas(ref=baseCanvas lebar=174 tinggi=174) //- kanvas kanvas#myCanvas.my-canvas.clr-canvas(ref=lebar kanvasku =174 tinggi=174) .canvas-data #[span.num {{grade}}]poin</template><script>var vm = null, timer1 = null, /* nilai dasar kanvas*/ c = null, //document.getElementById(myCanvas = null, //canvas-2d canvas x = 161 / 2 + 1, //koordinat pusat lingkaran r = (161) - 10) / 2; //Ukuran radius/* komponen penggesek*/impor { penggesek, penggesekSlide } dari vue-awesome-swiper;impor { getData } dari ../io/getData;export default { nama: Indeks, komponen: { wiper, wiperSlide }, data() { return { nilai: 0, //Skor bagan donat nilaiTarget: 78,54, //Nomor skor aktual , Anda dapat mengubah isShow: true setelah meminta data melalui ajax, // Apakah akan menampilkan penggesek halaman kedua aniShow: false, // Apakah akan mengaktifkan animasi bagan kolom Data: [{ minggu: minggu pertama, nilai: 0 }, { minggu: minggu kedua, nilai: 30 }, { minggu: minggu ketiga, nilai: 99,99 }, { minggu: minggu keempat, nilai: 76,98 }, { minggu: minggu kelima, nilai: 100 }], wiperOption: { //parameter wiper notNextTick: true, arah: vertikal, grabCursor: true, setWrapperSize: true, autoHeight: true, slidesPerView: 1, mousewheel: false, mousewheelControl: false, height: window.innerHeight, //Pengaturan ketinggian, mengisi resistansi ketinggian perangkat: 0, observasiParents: true, initialSlide: 2 - 1, //Saat mengatur inisialisasi , halaman tampilan default wiper, dimulai dari awal pada: { slideChange() { if ( (this.activeIndex == 2 && vm.isShow) ||.(this.activeIndex == 1 && !vm.isShow) ) { console.log(this.activeIndex, vm.isShow, menggambar animasi setTimeout(function() { // Menampilkan animasi histogram vm.aniShow = true; // Pengatur waktu terus-menerus memicu gambar cincin berwarna untuk mencapai efek animasi cincin timer1 = setInterval(function() { // Mengubah copywriting skor perantara var num = vm.grade; angka++; jika (angka >= vm.gradeTarget) { vm.grade = vm.gradeTarget; clearInterval(timer1); lain { vm.grade = angka; / 60); }, 500 } lain { // Setelah membalik halaman, inisialisasi status halaman data, hapus timer untuk menjeda animasi, dan hapus cincin berwarna console.log (halaman lain); clearInterval(vm.grade = vm.aniShow = false ; vm.clearCanvas(); } } } } }, dihitung: {}, mount() { // Inisialisasi data, gambar lingkaran abu-abu vm = ini; this.$refs.myCanvas; ctx = c.getContext(2d); this.drawBaseCanvas(); }, metode: { drawBaseCanvas() { // gambar kanvas/* nilai dasar*/ var c = this.$refs.baseCanvas , //document.getElementById(myCanvas); // debugger; ctx = c.getContext(2d), o = x, randius = r; /*Lingkaran abu-abu default*/ ctx.strokeStyle = #eee; ctx.lineWidth = 10; ctx.beginPath(); ; }, clearCanvas() { // Hapus kanvas ctx.clearRect(0, 0, 200, 200 }, drawClrCanvas() { var gradien = ctx.createLinearGradient(75, 50, 5, 90); gradien.addColorStop(0, #C88EFF); Untuk mengisi ctx.lineWidth = 10; ctx.lineCap = bulat; ctx.shadowColor = rgba(191,142,255, 0,36); ctx.shadowBlur = 8; ctx.shadowOffsetY = 8; ctx.beginPath(); x, r, Math.PI, Math.PI * hitung, salah); ctx.stroke(); } }};</script><style lang='scss'>// kolom chart.row { posisi: indeks-z: 1; - 0,08 - 0,38rem; perataan teks: tengah;}.data-txt { ukuran font: 0,2rem; 0,2rem; margin-bawah: 0,09rem;}.progress { tinggi: 0rem; transisi: tinggi 0,5 detik kemudahan masuk;}.ani { @untuk $i dari 1 hingga 6 { &:nth-of-type( #{$i}) { .progress { penundaan transisi: #{$i * 0,15}s; { // .progress { // penundaan transisi: .4s; // } // } // &:nth-of-type(2) { // .progress { // penundaan transisi: .8s; } // } // &:nth-of-type(3) { // .progress { // penundaan transisi: 1s; // } // } // &:nth-of-type(4) { / / .kemajuan { // penundaan transisi: 1,4 detik; // } // } // &:nth-of-type(5) { // .progress { // penundaan transisi: 1,8 detik; data { tampilan: blok; lebar: 0,12rem; tinggi: 100%; margin: 0 otomatis; latar belakang: gradien linier(0deg, #c88eff 0%, #7e5cff 100%); bayangan kotak: 0 -0,04rem 0,14rem 0 rgba(129, 93, 255, 0,4); radius batas: 0,05rem 0,05rem 0 0;}//0 poin menampilkan rule.nodata { .pg- data { radius batas: 0; latar belakang: #e7e7e7; tidak ada; }}.minggu { ukuran font: 0,2rem; tinggi garis: 0,2rem; margin-top: 0,08rem; warna: #666;}// Bagan cincin - data02 data part.data02-charts { margin-top : 0.32rem; tinggi: 1.61rem;}.canvas-box { posisi: relatif; lebar: kiri; 1.61rem; tinggi: 1.61rem; margin-kiri: 0.92rem;}.kanvas-saya { lebar: 1.61rem; tinggi: 1.61rem;}.clr-kanvas { posisi: absolut; .canvas-data { posisi: absolut; atas: 0,56rem; kiri: 0; kanan: 0; margin: otomatis; -0,1rem; perataan teks: tengah; ukuran font: 0,24rem; .num { ukuran font: 0,32rem;
Di atas adalah keseluruhan isi artikel ini, saya harap dapat bermanfaat untuk pembelajaran semua orang. Saya juga berharap semua orang mendukung VeVb Wulin Network.