Como siempre, ¡solo mira las fotos!
El efecto es el siguiente:
¡Grandes imágenes en alta definición!
He trabajado como codificador durante muchos años, pero mis viejos ojos están apagados y no puedo ver la animación con claridad. ! ¡Entonces mira las capturas de pantalla estáticas! ! !
Los efectos de diferentes puntuaciones son los siguientes:
Después de ver el programa del vendedor, ¡echemos un vistazo al proceso de producción del producto!
Canvas dibuja un círculo 1. En vue, el código en <template lang=pug> es el siguiente:
canvas#baseCanvas es el anillo gris en la parte inferior
canvas#myCanvas es el anillo de color de arriba
Necesitamos usar el estilo CSS para ayudarnos a cubrir el anillo de color encima del anillo gris.
2. estilo CSS: 3. código de dibujo estilo js-canvasEste código también es muy simple, solo mira la API del lienzo.
3-1. En el componente vue, defina las variables requeridas en la parte superior de la etiqueta del script.
3-2. En el objeto de método de vue, se definen tres métodos:
drawBaseCanvas: se utiliza para dibujar el anillo gris inferior. Como el círculo gris no tiene efecto de animación, simplemente dibuja un círculo gris completo al principio. drawClrCanvas: se utiliza para dibujar el anillo de color de arriba. clearCanvas: se utiliza para limpiar el lienzo. Esto es lo que requiere la animación del anillo de colores. Porque el núcleo de nuestro efecto de animación de anillo es borrar el anillo de color de vez en cuando, luego aumentar el valor del ángulo final y volver a dibujarlo, para que sea una animación continua.
Aquí está el código para los tres métodos:
Los códigos de los tres métodos anteriores son casi todos aplicaciones de la API de lienzo, solo lea el tutorial.
Solo en el método draoClrCanvas, al dibujar un círculo de lienzo, el valor inicial y el valor final se establecen en el parámetro de arco.
El valor inicial determina la posición inicial de dibujo del círculo y el valor final determina la posición final (parece que dije tonterías, pero después de pensar mucho en el texto de descripción del pensamiento, no quiero borrarlo jajaja)
El cálculo de este valor final me resulta bastante problemático.
¿Por qué es necesario calcular la variable de recuento de esta manera?
this.grade es un número entero positivo dentro de 100, que indica la puntuación. Está definido en datos y el valor predeterminado es 0 puntos.
Entonces, el círculo coloreado es invisible al principio porque el punto inicial y el punto final son ambos 0 puntos.
Si cambia el valor de la calificación, de 0 a 100, el valor del anillo de color del lienzo también cambiará.
De esta forma, mientras modifiquemos gradualmente el valor de la calificación y lo volvamos a dibujar, los anillos de colores aumentarán gradualmente para lograr el efecto de animación.
Efecto de animación de anilloDebido a mis necesidades especiales aquí, la animación debe activarse cada vez que el usuario gira hacia el deslizador donde se encuentra el lienzo (más tarde, es más problemático y requiere que el histograma y las partes del lienzo tengan un efecto de entrada antes de que comience la animación). El efecto es el más largo en la imagen de arriba (como esa animación gif).
Entonces tengo que usar swiper para lograrlo. En la función de devolución de llamada del interruptor deslizante, la puntuación de calificación aumenta continuamente desde 0 y el dibujo del anillo de color se vuelve a activar para lograr el efecto de animación.
El deslizador que uso en vue es 'vue-awesome-swiper'. He escrito los pasos para su uso en otros artículos.
Hay un objeto en la configuración de swiper en vue-data. La función slideChange en el objeto on es la función de devolución de llamada que se activa cada vez que el deslizador pasa la página.
Aquí hablaré de algunos puntos especiales:
(1) vm: es una variable que tengo almacenada en el script de vue. Se inicializa en nulo y luego, cuando se monta, se asigna como un objeto de instancia de vue.
Inicializar datos y dibujar círculos grises.
A través de este método, obtengo los valores de los atributos grade y gradeTarget en la función object-data-swiper-callback de la instancia vue y los modifico.
PD: No sé si este es un enfoque estúpido. Cuando hice esto, encontré un problema. No sabía cómo obtener la instancia de vue en la devolución de llamada de swiper. Así que había una forma tan tortuosa de salvar al país. Si tengo una solución mejor, espero que puedas brindarme una nueva idea. Muchas gracias, querida.
(2) (this.activeIndex == 2 && vm.isStar) || (this.activeIndex == 1 &&!vm.isStar)
Este juicio se hace por motivos comerciales y puede ignorarse.
esto apunta al objeto swiper en la función swiperChange. this.activeIndex es una propiedad de la instancia de swiper. En términos oficiales, devuelve el índice del bloque activo actual (bloque de activación). Puedes entender que se refiere a la página a la que estás accediendo actualmente, que es el subíndice de la diapositiva que estás mirando actualmente.
Debido a mi identidad como usuario, decidiré decisivamente si mostrar la página anterior del swiper donde se encuentra el lienzo actual. Si no se muestra, la página anterior no se dibujará en absoluto y el subíndice de deslizador correspondiente de la página actual se convertirá en (índice-1).
Con todo, cuando se cumplan las condiciones y el usuario acceda a la página del deslizador donde se encuentra el lienzo, activaré la lógica de dibujo del anillo en el if. De lo contrario, vaya a otra opción para inicializar el estado de la página de datos, borre el temporizador para pausar la animación y borre el anillo de color.
(3)vm.aniMostrar
Como mencioné en mi último artículo "Dibujar histogramas con CSS puro", la animación del histograma debe discutirse junto con la animación del lienzo. Porque su implementación de animación necesita cooperar con el cambio de deslizador. Ese es el código aquí:
Cuando el atributo vue - data - aniShow se vuelve verdadero, el nombre de la clase ani se agregará a div.row:
De manera similar, si aniShow es verdadero, la altura del progreso se adjuntará con su propio valor objetivo, es decir, la altura real del progreso se asignará a la altura del atributo de estilo después de convertirlo en porcentaje.
En este momento, debido a que la transición de progreso monitorea el cambio de altura, comienza la animación de aumento del histograma a medida que aumenta la altura.
Bajo el nombre de clase ani, la transición-retraso del progreso logra su efecto de incremento altamente escalonado.
Puede resultar confuso simplemente leer la descripción del texto, pero eche otro vistazo al efecto:
(4) Parte del código de dibujo del círculo de color
gradeTarget es la puntuación real, que es el resultado final que se extraerá.
La calificación comienza desde 0 y aumenta hasta el tamaño de gradeTarget.
No hice ++vm.grade directamente aquí y no sé lo que estaba pensando en ese momento.
Si juzga, si la calificación aumenta hasta el valor objetivo calificaciónObjetivo o es mayor que el valor objetivo, deje de incrementar y deje calificación=gradoObjetivo. Juicio que pertenece al valor crítico. En la función de movimiento, también se considera detección de colisión.
Por el contrario, si no se alcanza el objetivo, el último lienzo dibujado se borrará y se volverá a dibujar un nuevo anillo de color después de que la calificación cambie gradualmente.
(5) Coloque todo esto en setTimeout, haga una pausa de 500 milisegundos antes de ejecutar, para esperar a que el gráfico de barras y el gráfico de anillos ingresen al mercado antes de comenzar a dibujar el efecto incremental del círculo.
De hecho, el código anterior es un proceso lógico muy simple. Los lectores deberían poder entenderlo después de leer el código una vez.
Nuevas ideas:
Hice este efecto hace mucho tiempo cuando estaba resolviendo el método de producción hoy, pensé en una solución de optimización para mi propio código:
De hecho, no es necesario volver a llamar el método de dibujo del círculo de color en el temporizador. Lo que cambiamos directamente es el atributo this.grade. Sería bueno monitorear los cambios de este atributo. De esta forma, cuando se modifique esta propiedad en el temporizador, el método de anillo se ejecutará automáticamente.
Esto sigue siendo una idea y todavía necesita mi práctica.
Efecto incremental del texto medio:Debido a que la calificación es una puntuación que se incrementa cada vez, puede utilizar el enlace de datos bidireccional de Vue para vincular directamente la calificación como un valor de puntuación a la vista DOM correspondiente.
Finalmente, la animación del anillo y el gráfico de barras de arriba se combinan con la animación para controlar el retraso de la animación. Muy sencillo.
Código fuente de index.vue:
(Tenga en cuenta que el código fuente se organizó ligeramente y se extrajo por separado. Para completar y proteger otros códigos comerciales, se modificaron algunos nombres de variables, que pueden ser ligeramente diferentes de las capturas de pantalla anteriores)
<template lang='pug'> .indexs#Indexs.app-bg transición(nombre=fade) swiper#swiperBox(:options=swiperOption ref=mySwiper) swiper-slide.swiper-slide1 .container .up swiper-slide.swiper -slide2(v-if=isShow) .mi-tiburón .arriba 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: 'Sin datos'}} .progress(:class='item.grade == 0 ? nodata : ' :estilo='altura: ' + (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 ancho =174 altura=174) .canvas-data #[span.num {{grade}}]puntos</template><script>var vm = null, timer1 = null, /* valor básico del lienzo*/ c = null, //document.getElementById(myCanvas = null, //canvas-2d canvas x = 161/2 + 1, //coordenada central del círculo r = (161); - 10) / 2; //Tamaño del radio/* componente swiper*/import { swiper, swiperSlide } de vue-awesome-swiper;import { getData } de ../io/getData; export default { nombre: Índices, componentes: { swiper, swiperSlide }, data() { return { calificación: 0, // Puntuación del gráfico de anillos gradeTarget: 78,54, // Número de puntuación real , puede modificar isShow: true después de solicitar datos a través de ajax, // Si se muestra el deslizador de la segunda página aniShow: false, // Si se habilita la animación del gráfico de columnas Datos: [{ semana: primera semana, nota: 0 }, { semana: segunda semana, nota: 30 }, { semana: tercera semana, nota: 99,99 }, { semana: cuarta semana, nota: 76,98 }, { semana: quinta semana, nota: 100 }], swiperOption: { //parámetros de swiper notNextTick: verdadero, dirección: vertical, grabCursor: verdadero, setWrapperSize: verdadero, autoHeight: true, slidesPerView: 1, mousewheel: false, mousewheelControl: false, height: window.innerHeight, //Configuración de altura, llenado de la altura del dispositivo ResistanceRatio: 0, observeParents: true, inicialSlide: 2 - 1, //Al configurar la inicialización , la página de visualización predeterminada de swiper, comenzando desde cero en: { slideChange() { if ( (this.activeIndex == 2 && vm.isShow) || (this.activeIndex == 1 && !vm.isShow) ) { console.log(this.activeIndex, vm.isShow, dibujar animación); setTimeout(function() { // Mostrar animación de histograma vm.aniShow = true; // El temporizador activa continuamente el dibujo de anillos de colores para lograr el efecto de animación del anillo timer1 = setInterval(function() { // Cambia la redacción de la puntuación intermedia var num = vm.grade; num++; if (num >= vm.gradeTarget) { vm.grade = vm.gradeTarget; vm.drawClrCanvas(); / 60); }, 500); } más { // Después de pasar la página, inicialice el estado de la página de datos, borre el temporizador para pausar la animación y borre los anillos de colores console.log (otras páginas); ; vm.clearCanvas (); } } } } }; calculado: {}, montado() { // Inicializa los datos, dibuja un círculo gris vm = this; this.$refs.myCanvas; ctx = c.getContext(2d); this.drawBaseCanvas(); }, métodos: { drawBaseCanvas() { // dibujo del lienzo/* valor básico*/ var c = this.$refs.baseCanvas , //document.getElementById(myCanvas); // depurador; ctx = c.getContext(2d), o = x, randius = r; /*Círculo gris predeterminado*/ ctx.strokeStyle = #eee; ctx.lineWidth = 10; ctx.beginPath(); ; }, clearCanvas() { // Limpiar el lienzo ctx.clearRect(0, 0, 200, 200); drawClrCanvas() { var gradient = ctx.createLinearGradient(75, 50, 5, 90); gradient.addColorStop(0, #C88EFF); gradient.addColorStop(1.0, #7E5CFF); Para llenar ctx.lineWidth = 10; ctx.shadowColor = rgba(191,142,255, 0.36); ctx.shadowBlur = 8; ctx.shadowOffsetY = 8; ctx.beginPath(); x, r, Math.PI, Math.PI * recuento, falso); ctx.stroke(); } }};</script><style lang='scss'>// columna chart.row { posición: relativo; índice z: 1; ancho: 0,61rem; - 0,08 - 0,38rem; alineación de texto: centro;}.data-txt { tamaño de fuente: 0,2rem altura de línea: 0.2rem; margen inferior: 0.09rem;}.progreso { altura: 0rem; transición: altura 0.5s facilidad de entrada;}.ani { @for $i de 1 a 6 { &:nésimo de tipo( #{$i}) { .progress { retraso-transición: #{$i * 0.15}s } } } // &:enésimo-de-tipo(1) { // .progreso { // retraso-transición: .4s; // } // } // &:nth-of-type(2) { // .progreso { // retraso-transición: .8s; } // } // &:enésimo-de-tipo(3) { // .progreso { // retraso-de-transición: 1s; // } // } // &:enésimo-de-tipo(4) { / / .progreso { // retraso de transición: 1,4 s; // } // } // &:enésimo-de-tipo(5) { // .progreso { // retraso de transición: 1,8 s; datos { pantalla: bloque; ancho: 0.12rem; alto: 100%; margen: 0 auto; fondo: gradiente lineal (0deg, #c88eff 0%, #7e5cff 100%); sombra de cuadro: 0 -0.04rem 0.14rem 0 rgba(129, 93, 255, 0.4); radio de borde: 0.05rem 0.05rem 0 0;}//0 puntos display rule.nodata { .pg- datos { radio de borde: 0; fondo: #e7e7e7; sombra de cuadro: none; }}.week { tamaño de fuente: 0.2rem; altura de línea: 0.2rem; margen superior: 0.08rem; color: #666;}// Gráfico de anillo - data02 data part.data02-charts { margen-top : 0.32rem; altura: 1.61rem;}.canvas-box { posición: relativa; flotante: izquierda; 1,61rem; altura: 1,61rem; margen izquierdo: 0,92rem;}.my-canvas {ancho: 1,61rem; altura: 1,61rem;}.clr-canvas {posición: superior: 0 izquierda: 0;} .canvas-data { posición: absoluta; arriba: 0.56rem; izquierda: 0; margen: auto; -0.1rem; alineación de texto: centro; tamaño de fuente: 0.24rem; .num {tamaño de fuente: 0.32rem; peso de fuente: }}</estilo>
Lo anterior es el contenido completo de este artículo. Espero que sea útil para el estudio de todos. También espero que todos apoyen VeVb Wulin Network.