Schauen Sie sich wie immer einfach die Bilder an!
Der Effekt ist wie folgt:
Große HD-Bilder!
Ich arbeite seit vielen Jahren als Programmierer, aber meine alten Augen sind trüb und ich kann die Animation nicht klar sehen? ! Dann schauen Sie sich die statischen Screenshots an! ! !
Die Auswirkungen unterschiedlicher Scores sind wie folgt:
Nachdem wir uns die Show des Verkäufers angesehen haben, werfen wir einen Blick auf den Produktionsprozess des Produkts!
Canvas zeichnet einen Kreis 1. In vue lautet der Code in <template lang=pug> wie folgt:
canvas#baseCanvas ist der graue Ring unten
canvas#myCanvas ist der farbige Ring oben
Wir müssen den CSS-Stil verwenden, um den farbigen Ring über dem grauen Ring abzudecken.
2. CSS-Stil: 3. Zeichencode im js-canvas-StilDieser Code ist auch sehr einfach. Schauen Sie sich einfach die Canvas-API an
3-1. Definieren Sie in der Vue-Komponente die erforderlichen Variablen oben im Skript-Tag.
3-2. Im Methodenobjekt von vue sind drei Methoden definiert:
drawBaseCanvas: Wird zum Zeichnen des unteren grauen Rings verwendet. Da der graue Kreis keinen Animationseffekt hat, zeichnen Sie einfach zu Beginn einen vollständigen grauen Kreis. drawClrCanvas: Wird zum Zeichnen des farbigen Rings oben verwendet. clearCanvas: Wird zum Löschen der Leinwand verwendet. Dies ist es, was die Farbringanimation erfordert. Denn der Kern unseres Ringanimationseffekts besteht darin, den farbigen Ring von Zeit zu Zeit zu löschen, dann den Endwinkelwert zu erhöhen und ihn neu zu zeichnen, sodass es sich um eine kontinuierliche Animation handelt.
Hier ist der Code für die drei Methoden:
Die Codes in den oben genannten drei Methoden sind fast alle Anwendungen der Canvas-API. Lesen Sie einfach das Tutorial.
Nur in der draoClrCanvas-Methode werden beim Zeichnen eines Leinwandkreises der Startwert und der Endwert im Bogenparameter festgelegt.
Der Startwert bestimmt die Startposition des Kreises beim Zeichnen und der Endwert die Endposition (ich scheine Unsinn gesagt zu haben, aber nachdem ich gründlich über den Gedankenbeschreibungstext nachgedacht habe, möchte ich ihn nicht löschen, hahaha)
Die Berechnung dieses Endwertes ist für mich recht mühsam.
Warum muss die Zählvariable so berechnet werden? Ich habe vergessen, wie ich das herausgefunden habe.
this.grade ist eine positive Ganzzahl innerhalb von 100, die die Punktzahl angibt. Es ist in den Daten definiert und der Standardwert ist 0 Punkte.
Der farbige Kreis ist also am Anfang unsichtbar, da der Startpunkt und der Endpunkt beide 0 Punkte sind.
Wenn Sie den Gradwert von 0 bis 100 ändern, ändert sich auch der Wert des Leinwandfarbrings.
Solange wir den Gradwert schrittweise ändern und neu zeichnen, werden die farbigen Ringe allmählich größer, um den Animationseffekt zu erzielen.
RinganimationseffektAufgrund meiner besonderen Anforderungen hier muss die Animation jedes Mal ausgelöst werden, wenn sich der Benutzer zum Wischer bewegt, auf dem sich die Leinwand befindet (später ist dies problematischer und erfordert, dass die Histogramm- und Leinwandteile einen Eingangseffekt haben, bevor die Animation beginnt. Der Effekt ist im Bild oben am längsten (wie bei dieser GIF-Animation).
Also muss ich Swiper verwenden, um es zu erreichen. In der Rückruffunktion des Swiper-Schalters wird der Notenwert kontinuierlich von 0 an erhöht und das Zeichnen des farbigen Rings erneut ausgelöst, um den Animationseffekt zu erzielen.
Der Swiper, den ich in Vue verwende, ist „vue-awesome-swiper“. Ich habe die Schritte für ihre Verwendung in anderen Artikeln geschrieben.
In der Konfiguration von Swiper in Vue-Data gibt es ein On-Objekt. Die slideChange-Funktion im on-Objekt ist die Rückruffunktion, die jedes Mal ausgelöst wird, wenn der Swiper die Seite umblättert.
Hier möchte ich auf einige Besonderheiten eingehen:
(1) vm: Es handelt sich um eine Variable, die ich im Vue-Skript gespeichert habe. Sie wird auf Null initialisiert und dann beim Mounten als Vue-Instanzobjekt zugewiesen.
Daten initialisieren und graue Kreise zeichnen
Durch diese Methode erhalte ich die Attributwerte grade und gradeTarget in der Funktion object-data-swiper-callback der Vue-Instanz und ändere sie.
PS: Ich weiß nicht, ob das ein dummer Ansatz ist. Als ich das tat, stieß ich auf ein Problem. Ich wusste nicht, wie ich die Vue-Instanz im On-Callback von Swiper erhalten sollte. Es gab also einen so gewundenen Weg, das Land zu retten. Wenn ich eine bessere Lösung habe, hoffe ich, dass Sie mir eine neue Idee geben können. Vielen Dank, mein Lieber.
(2) (this.activeIndex == 2 && vm.isStar) || (this.activeIndex == 1 && !vm.isStar)
Dieses Urteil wird aus geschäftlichen Gründen gefällt und kann ignoriert werden.
Dies zeigt auf das Swiper-Objekt in der Funktion swiperChange. this.activeIndex ist eine Eigenschaft der Swiper-Instanz. In offiziellen Worten gibt es den Index des aktuell aktiven Blocks (Aktivierungsblocks) zurück. Sie können verstehen, dass er sich auf die Seite bezieht, die Sie gerade aufrufen, nämlich den Index der Swiper-Folie, die Sie gerade betrachten.
Aufgrund meiner Identität als Benutzer entscheide ich maßgeblich, ob die vorherige Seite des Swipers dort angezeigt wird, wo sich die aktuelle Leinwand befindet. Wenn es nicht angezeigt wird, wird die vorherige Seite überhaupt nicht gezeichnet, dann wird der entsprechende Swiper-Index der aktuellen Seite zu (Index-1).
Alles in allem werde ich, wenn die Bedingungen erfüllt sind und der Benutzer zur Swiper-Seite wechselt, auf der sich die Leinwand befindet, die Ringzeichnungslogik im if auslösen. Andernfalls gehen Sie zu „sonst“, um den Datenseitenstatus zu initialisieren, den Timer zum Anhalten der Animation zu löschen und den farbigen Ring zu löschen.
(3)vm.aniShow
Wie in meinem letzten Artikel „Zeichnen von Histogrammen mit reinem CSS“ erwähnt, sollte die Animation des Histogramms zusammen mit der Animation der Leinwand besprochen werden. Weil ihre Animationsimplementierung mit der Swiper-Umschaltung zusammenarbeiten muss. Das ist der Code hier:
Wenn das Attribut vue - data - aniShow wahr wird, wird der Klassenname ani zu div.row hinzugefügt:
Wenn aniShow wahr ist, wird die Höhe des Fortschritts ebenfalls mit einem eigenen Zielwert verknüpft, d. h. die tatsächliche Höhe des Fortschritts wird der Höhe des Stilattributs zugewiesen, nachdem sie in Prozent umgewandelt wurde.
Da der Fortschrittsübergang zu diesem Zeitpunkt die Höhenänderung überwacht, beginnt die Histogrammanimation, die mit zunehmender Höhe zunimmt.
Unter dem Namen der Ani-Klasse erzielt die Übergangsverzögerung des Fortschritts ihren stark gestaffelten Inkrementeffekt.
Es kann verwirrend sein, nur die Textbeschreibung zu lesen, aber schauen Sie sich den Effekt noch einmal an:
(4) Farbkreis-Zeichnungscodeteil
gradeTarget ist die tatsächliche Punktzahl, also das zu ziehende Endergebnis.
Die Note beginnt bei 0 und erhöht sich auf die Größe von gradeTarget.
Ich habe hier nicht direkt ++vm.grade gelesen und weiß nicht, was ich damals gedacht habe.
Wenn Sie beurteilen, ob die Note auf den Zielwert gradeTarget ansteigt oder größer als der Zielwert ist, stoppen Sie die Erhöhung und lassen Sie grade = gradeTarget. Urteil, das zum kritischen Wert gehört. In der Bewegungsfunktion wird auch eine Kollisionserkennung berücksichtigt.
Im Gegenteil, wenn das Ziel nicht erreicht wird, wird die zuletzt gezeichnete Leinwand gelöscht und ein neuer Farbring wird neu gezeichnet, nachdem die Note schrittweise geändert wurde.
(5) Fügen Sie all dies in setTimeout ein und halten Sie vor der Ausführung 500 Millisekunden an, um zu warten, bis das Balkendiagramm und das Ringdiagramm in den Markt eintreten, bevor Sie mit dem Zeichnen des inkrementellen Effekts des Kreises beginnen.
Tatsächlich handelt es sich bei dem obigen Code um einen sehr einfachen logischen Prozess, den der Leser nach einmaligem Lesen des Codes verstehen sollte.
Neue Ideen:
Ich habe diesen Effekt vor langer Zeit gemacht, als ich heute über die Produktionsmethode nachgedacht habe, über eine Optimierungslösung für meinen eigenen Code nachgedacht:
Tatsächlich ist es nicht erforderlich, die Farbkreis-Zeichnungsmethode im Timer erneut aufzurufen. Was wir direkt geändert haben, ist das Attribut this.grade. Es wäre gut, die Änderungen dieses Attributs zu überwachen. Auf diese Weise wird die Ringmethode automatisch ausgeführt, wenn diese Eigenschaft im Timer geändert wird.
Das ist noch eine Idee und bedarf noch meiner Übung.
Inkrementeller Effekt des Mitteltextes:Da es sich bei der Note jedes Mal um eine inkrementelle Punktzahl handelt, können Sie die bidirektionale Datenbindung von Vue verwenden, um die Note direkt als Bewertungswert an die entsprechende DOM-Ansicht zu binden.
Schließlich wird die Animation des Rings und des Balkendiagramms oben mit einer Animation kombiniert, um die Animationsverzögerung zu steuern. Ganz einfach.
index.vue-Quellcode:
(Beachten Sie, dass der Quellcode leicht organisiert und separat extrahiert wurde. Der Vollständigkeit halber und zum Schutz anderer Geschäftscodes wurden einige Variablennamen geändert, die möglicherweise geringfügig von den vorherigen Screenshots abweichen.)
<template lang='pug'> .indexs#Indexs.app-bg Transition(name=fade) swiper#swiperBox(:options=swiperOption ref=mySwiper) swiper-slide.swiper-slide1 .container .up swiper-slide.swiper -slide2(v-if=isShow) .my-shark .up swiper-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 : 'Keine Daten'}} .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 .week {{item.week}} .data.data02 .data02-charts .canvas-box //- baseCanvas canvas#baseCanvas.my-canvas(ref=baseCanvas width=174 height=174) //- canvas canvas#myCanvas.my-canvas.clr-canvas(ref=myCanvas width =174 height=174) .canvas-data #[span.num {{grade}}]points</template><script>var vm = null, timer1 = null, /* Canvas-Grundwert*/ c = null, //document.getElementById(myCanvas); ctx = null, //canvas-2d Canvas x = 161 / 2 + 1, //Kreismittelpunktkoordinate r = (161 - 10) / 2; //Radiusgröße/* Swiper-Komponente*/import { Swiper, SwiperSlide } von vue-awesome-swiper;import { getData } from ../io/getData;export default { name: Indexes, Components: { swiper, swiperSlide }, data() { return { grade: 0, //Donut-Chart-Score gradeTarget: 78,54, //Tatsächliche Score-Nummer , Sie können isShow: true ändern, nachdem Sie Daten über Ajax angefordert haben, // Ob der zweite Seitenwischer angezeigt werden soll aniShow: false, // Ob die Säulendiagrammanimation aktiviert werden soll Daten: [{ Woche: erste Woche, Note: 0 }, { Woche: zweite Woche, Note: 30 }, { Woche: dritte Woche, Note: 99,99 }, { Woche: vierte Woche, Note: 76,98 }, { Woche: fünfte Woche, Note: 100 }], swiperOption: { //Swiper-Parameter notNextTick: true, Richtung: vertikal, grabCursor: true, setWrapperSize: true, autoHeight: true, slidesPerView: 1, Mousewheel: false, MousewheelControl: false, height: window.innerHeight, // Höheneinstellung, Füllen der Gerätehöhe ResistanceRatio: 0, ObservParents: True, InitialSlide: 2 - 1, // Beim Festlegen der Initialisierung , die Standardanzeigeseite von Swiper, von vorne beginnend bei: { slideChange() { if ( (this.activeIndex == 2 && vm.isShow) ||. (this.activeIndex == 1 && !vm.isShow) ) { console.log(this.activeIndex, vm.isShow, draw animation); setTimeout(function() { // Histogrammanimation anzeigen vm.aniShow = true; // Der Timer löst kontinuierlich das Zeichnen farbiger Ringe aus, um den Ringanimationseffekt zu erzielen timer1 = setInterval(function() { // Copywriting der Zwischenpartitur ändern var num = vm.grade; num++; if (num >= vm.gradeTarget) { vm.grade = vm.gradeTarget; } else { vm.grade = num; }, 1000 / 60); }, 500); Initialisieren Sie nach dem Umblättern den Status der Datenseite, löschen Sie den Timer, um die Animation anzuhalten, und löschen Sie die farbigen Ringe console.log (andere Seiten); ; vm.clearCanvas (); } } } }, berechnet: {}, Mounted() { // Daten initialisieren, grauen Kreis zeichnen vm = c = this.$refs.myCanvas; ctx = c.getContext(2d); this.drawBaseCanvas(); , //document.getElementById(myCanvas); // debugger; ctx = c.getContext(2d), o = x, randius = r; /*Standard grauer Kreis*/ ctx.StrokeStyle = #eee; ctx.beginPath(); ctx.arc(o, o, randius, 0, 2 * Math.PI); ; }, clearCanvas() { // Leinwand löschen ctx.clearRect(0, 0, 200, 200); drawClrCanvas() { var gradient = ctx.createLinearGradient(75, 50, 5, 90); Gradient.addColorStop(1.0, #7E5CFF); // Gradient verwenden Zum Füllen ctx.lineWidth = 10; ctx.lineCap = Round; ctx.shadowColor = rgba(191,142,255, 0,36); ctx.shadowOffsetY = 8; ctx.beginPath(); var count = this.grade / (100 / 2) + 1; ctx.arc(x, x, r, Math.PI, Math.PI * count, false); ctx.Stroke(); } }};</script><style lang='scss'>// Column Chart.row { Position: Relative; Margin-Bottom: -0.28 - 0,08 - 0,38rem; text-align: center;}.data-txt { Schriftgröße: 0,2rem; 0.2rem; margin-bottom: 0.09rem;}.progress { height: 0rem; Transition: height 0.5s easy-in-out;}.ani { @for $i from 1 to 6 { &:nth-of-type( #{$i}) { .progress { Transition-Delay: #{$i * 0.15}s } } } // &:nth-of-type(1) { // .progress { // Transition-Delay: .4s; // } // &:nth-of-type(2) { // .progress { // Transition-Delay: .8s; } // } // &:nth-of-type(3) { // .progress { // Transition-Delay: 1s; // } // } // &:nth-of-type(4) { / / .Fortschritt { // Übergangsverzögerung: 1,4 s; // } // } // &:nth-of-type(5) { // .progress { // Übergangsverzögerung: 1,8 s // }}.pg- data { display: block; width: 0.12rem; height: 100%; background: linear-gradient(0deg, #c88eff 0%, #7e5cff 100 %); box-shadow: 0 -0.04rem 0.14rem 0 rgba(129, 93, 255, 0.4); border-radius: 0.05rem 0.05rem 0 0;}//0 Punkte display Rule.nodata { .pg- data { border-radius: 0; background: #e7e7e7; none; }}.week { Schriftgröße: 0,2rem; Linienhöhe: 0,08rem; Farbe: #666;}// Ringdiagramm - data02 data part.data02-charts { margin-top : 0,32rem; Höhe: 1,61rem;}.canvas-box { position: relative; float: left; 1.61rem; height: 1.61rem;}.my-canvas { width: 1.61rem;}.clr-canvas { position: absolute; left: 0;} .canvas-data { position: absolute; top: 0,56rem; right: 0; -0,1rem; text-align: center; schriftgröße: 0,24rem;
Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass er für das Studium aller hilfreich ist. Ich hoffe auch, dass jeder das VeVb Wulin Network unterstützt.