inmersión profunda en codificación creativa para principiantes | Frank Dvorak | Skillshare

Velocidad de reproducción


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

inmersión profunda en codificación creativa para principiantes

teacher avatar Frank Dvorak, Creative Coding

Ve esta clase y miles más

Obtenga acceso ilimitado a todas las clases
Clases enseñadas por líderes de la industria y profesionales activos
Los temas incluyen ilustración, diseño, fotografía y más

Ve esta clase y miles más

Obtenga acceso ilimitado a todas las clases
Clases enseñadas por líderes de la industria y profesionales activos
Los temas incluyen ilustración, diseño, fotografía y más

Lecciones en esta clase

    • 1.

      Introducción

      0:39

    • 2.

      Configuración de HTML y CSS

      1:20

    • 3.

      Configuración de JavaScript

      2:08

    • 4.

      Cómo dibujar rectángulos

      1:30

    • 5.

      Cómo dibujar líneas

      3:10

    • 6.

      Programación orientada a objetos

      5:24

    • 7.

      Colores dinámicos con HSL

      1:52

    • 8.

      Arte aleatorizado en línea

      3:26

    • 9.

      Dibujo de líneas multi-segmented

      3:25

    • 10.

      Líneas animadoras

      4:36

    • 11.

      Efecto de tormenta de rayos arco iris

      5:29

    • 12.

      Degradado lineal

      2:24

    • 13.

      Degradado radial

      1:14

    • 14.

      Cómo rellenar formas con un patrón

      4:03

    • 15.

      Mejora tus efectos con sombras

      1:42

    • 16.

      Trigonometría

      1:51

    • 17.

      efecto de garabatas en el caos

      4:43

    • 18.

      ¿Qué es un campo de flujo

      1:07

    • 19.

      Configuración de lienzo HTML

      1:28

    • 20.

      Dibujo en forma en lienzo

      2:52

    • 21.

      Programación orientada a objetos en JavaScript

      8:07

    • 22.

      Dibujo de sistemas de partículas

      1:17

    • 23.

      Animación de sistemas de partículas

      3:54

    • 24.

      Líneas y senderos para dibujar

      3:46

    • 25.

      Patrones de movimiento con trigonometría

      1:16

    • 26.

      Creación de un campo de vector

      8:03

    • 27.

      Cómo crear un campo de flujo

      7:04

    • 28.

      experimentos de campo de flujo

      3:28

    • 29.

      Modo de grid y depuración

      8:17

    • 30.

      Colores aleatorios

      2:54

    • 31.

      Diseño adaptable

      5:15

    • 32.

      Experimentación con patrones de campo de flujo

      2:43

    • 33.

      Dibujo de texto

      5:53

    • 34.

      Qué son los datos de píxeles

      5:13

    • 35.

      Manejo de datos de píxeles

      3:42

    • 36.

      Conversión de colores en ángulos

      10:28

    • 37.

      Flujo y degradación

      4:47

    • 38.

      Consejos, trucos y experimentos

      10:39

    • 39.

      Los campos de flujo de imágenes explicados

      8:27

    • 40.

      Trucos de manipulación de colores

      10:22

  • --
  • Nivel principiante
  • Nivel intermedio
  • Nivel avanzado
  • Todos los niveles

Generado por la comunidad

El nivel se determina según la opinión de la mayoría de los estudiantes que han dejado reseñas en esta clase. La recomendación del profesor o de la profesora se muestra hasta que se recopilen al menos 5 reseñas de estudiantes.

177

Estudiantes

1

Proyecto

Acerca de esta clase

Hacer cosas hermosas con código puede ser fácil si lo tomas paso a paso. Exploremos la codificación creativa y descubriremos qué puede hacerse combinando diferentes técnicas de dibujo y animación.

El conocimiento es poder. Por eso utilizaremos solo los principios de programación básicos: funciones, arreglos y para bucles, y con JavaScript, sin marcos y sin bibliotecas, y sin que tengan que ver con vanilla. Te explicaré cada línea de código mientras creamos múltiples proyectos animados. Ser capaz de entender plenamente cómo funciona el código nos permitirá ganar un control completo sobre el código, y podemos hacer que haga lo que quiera.

Permítanme enseñarte a dibujar una línea sencilla, animarla y convertirla en efectos cada vez más complejos a medida que agregamos más técnicas a nuestro kit de herramientas de codificación creativa, una por una.

Descubre los secretos de la codificación creativa hoy mismo. Lo más importante es que en realidad es mucho más fácil de lo que crees crear animaciones complejas y bellas y atractivas. Solo tienes que tomarlo paso a paso. Todo tiene sentido si romperás el proceso en partes individuales.

Clase 1 a 16:

En el primer bloque para principiantes, aprenderemos a dibujar formas en lienzo y a animarlas, convirtiéndolas en espirales animadas, relámpagos con arco iris y garabatas al azar.

Clase 17 a 39:

Si ya entiendes los aspectos básicos para dibujar un lienzo HTML, puedes pasar directamente a la sección 2, donde comienzo el proyecto de curso principal desde cero. Crearemos un campo de flujo animado, experimentaremos con él y lo haremos doblado en el texto y las imágenes.

¡Diviértete!

Conoce a tu profesor(a)

Teacher Profile Image

Frank Dvorak

Creative Coding

Profesor(a)

Hello, I'm Frank. I'm a front-end web developer, owner of Frank's Laboratory YouTube channel. Come explore creative coding, game development and generative art with me.

Ver perfil completo

Habilidades relacionadas

Animación y 3D Movimiento y animación
Level: Beginner

Valoración de la clase

¿Se cumplieron las expectativas?
    ¡Superadas!
  • 0%
  • 0%
  • Un poco
  • 0%
  • No realmente
  • 0%

¿Por qué unirse a Skillshare?

Mira las galardonadas Skillshare Originals

Cada clase tiene lecciones cortas y proyectos prácticos

Tu membresía apoya a los profesores de Skillshare

Aprende desde cualquier lugar

Ve clases sobre la marcha con la aplicación de Skillshare. Progresa en línea o descarga las clases para verlas en el avión, el metro o donde sea que aprendas mejor.

Transcripciones

1. Introducción: Las cosas geniales y hermosas con código pueden ser fáciles si lo tomas paso a paso, todo tiene sentido si lo divides en partes individuales, déjame mostrarte cómo tomar principios básicos de programación, funciones, matrices y bucles para crear bases complejas de código animado. Una vez que entendamos completamente las técnicas, las llevaremos al siguiente nivel en la sección avanzada. Hoy, descubriremos las herramientas, genial, experimentaremos con código, y usaremos ese conocimiento para diseñar nuestras propias animaciones. Hagamos arte con código y aprendamos programación al mismo tiempo. Que se diviertan. 2. Configuración de HTML y CSS: En esta primera sección, voy a crear un proyecto separado amigable para principiantes. Aprenderemos a animar líneas y cómo convertirlas en múltiples efectos diferentes, como aligeramiento, espirales , ondas, etc. Si lo desea, puede saltar directamente a la sección de campo de flujo, que comienza desde menos de 17. Incluí descargas de código fuente durante los puntos clave de cada proyecto. Así que es más fácil para ti saltar entre los proyectos y experimentar con el código. Si eso es lo que quieres hacer, te guiaré a través de todo el proceso paso a paso, y te explicaré cada línea de código, pero se necesitan algunos conocimientos básicos de HTML, CSS y JavaScript para obtener el máximo valor. Aquí, solo estoy configurando una página web genérica básica con elemento HTML canvas en ella. Vinculé a los archivos style.css y script.js. Y luego declaro algunos estilos CSS para canvas y creo reglas de reinicio globales para asegurarme de que los márgenes y los paddings aparezcan iguales en diferentes navegadores. Recomiendo usar un navegador moderno para esta clase, idealmente Google Chrome. Puedes ver que estoy usando esta posición absoluta común, centro y técnica para asegurarme de que Canvas esté en medio de la página web, vertical y horizontalmente. 3. Configuración de JavaScript: Configuración básica dentro de index.HTML y estilo CSS, nos movemos a script.js. Toda nuestra lógica estará escrita aquí. Configuré mi elemento lienzo HTML, nuestro tablero de dibujo con las dos líneas de código habituales. Creé una variable personalizada que llamo e.g. canvas, y señalé hacia el elemento canvas que creamos en index.HTML usando su ID. Le di una identificación de Canvas uno. Después creo una variable de contexto, CTX. Tomo esa variable de lienzo que acabo de crear, y llamo al método getContext incorporado en ella. Este método crea el llamado draw in context, que es básicamente un objeto JavaScript con todos los métodos y propiedades de dibujo de Canvas incorporados. Le pasamos un argumento llamado tipo contextos. Queremos trabajar con contexto de renderizado bidimensional. Hoy en día, el elemento canvas tiene dos tamaños independientes. tamaño del elemento, el tamaño real del elemento HTML y el tamaño de la superficie de dibujo. Queríamos asegurarnos de que ambos tamaños estén establecidos en los mismos valores. Lo hago al no definir el tamaño del lienzo en CSS y solo ciertos atributos de ancho y alto en Canvas a los valores. Yo quiero así. Si también está declarando el tamaño del lienzo en su archivo CSS, asegúrese de que esté configurado en los mismos valores para evitar dibujos estirados o distorsionados de otra manera. Si consola log c dx desde la línea dos, podemos ver este lienzo renderizando el objeto de contexto del que hablé. En el interior. Podemos ver los ajustes predeterminados de Canvas como la fuente de estilo de relleno actual. Podemos ver que el estilo de trazo predeterminado está configurado en negro aquí, por ejemplo, también podemos ver todos los métodos de dibujo de Canvas incorporados. Hoy, nos centraremos en dibujar y líneas animadas. Entonces aprenderemos todo lo que necesitas saber sobre método begin path que viene de aquí. También tenemos método de ruta cerrada aquí, línea a aquí, y pasar al método aquí. Usemos estos métodos para que entendamos completamente lo que hacen y cómo funcionan. 4. Cómo dibujar rectángulos: Podemos dibujar muchas formas diferentes en Lienzo, las formas demasiado básicas son círculos y rectángulos. Dibujar un rectángulo es muy sencillo. Podemos tomar contextos que definimos en la línea dos. Sabemos que contiene una referencia al objeto que contiene todos los métodos de dibujo de lienzo. A partir de ahí llamamos método de rectángulo de relleno incorporado. Rellenar rectángulo espera coordenadas partir de las cuales comenzaremos a dibujar en el rectángulo, la esquina superior izquierda del rectángulo. Coordenada X, la distancia de la esquina superior izquierda del rectángulo desde el borde izquierdo del lienzo será de 100 píxeles, y coordenada, la distancia desde la parte superior también será de 100 píxeles. El ancho del rectángulo será 50 píxeles y la altura será de 150. Puedo cambiar el ancho a 200 píxeles, coordenada vertical y 250 píxeles. Creo que se entiende la idea por defecto, el relleno de las formas dibujadas en Canvas se establece en negro. Puedo usar la propiedad FillStyle para anular el valor predeterminado y puedo configurarlo en otra cosa. Vamos a probar el rojo. También podemos llamar método de rectángulo de trazo incorporado, que simplemente delinear la forma. Por defecto, será línea negra con un ancho de píxel. Puedo cambiar eso usando la propiedad de ancho de línea. Vamos a probar diez píxeles. Y puedo usar un estilo de trazo para cambiar el color de todas las líneas dibujadas en Lienzo, por ejemplo, azul. 5. Cómo dibujar líneas: Entonces estos son los conceptos básicos de dibujar formas en Canvas. Hoy, nos centraremos en trazar líneas. Funcionan un poco diferente a los rectángulos. Tenemos que comenzar por dos puntos método de ruta de inicio incorporado. Este método iniciará una nueva ruta y también cerrará automáticamente toda la ruta existente si la hay. Esto es importante porque de esta manera puedes dibujar cada línea en un color diferente y sin comenzar camino, todas tus líneas se unirán automáticamente en una forma masiva, que no es lo que queremos hoy. ¿Verdad? Ahora, solo queremos trazar una línea simple. Comenzamos por usar el método incorporado move to. Este método creará una nueva subrayectoria para nuestros propósitos y propósitos. Pensemos en pasar a métodos como una forma de establecer las coordenadas x e y iniciales de nuestra línea. Entonces usaremos la línea a los métodos que crearán una línea recta desde el subcamino, desde el punto definido en movimiento hasta dos, las coordenadas pasaremos a la línea dos. Pensemos en ello por ahora que la línea dos métodos representarán las coordenadas x e y finales de nuestra línea. Mover a la línea final dos métodos sólo definen la ruta. No renderizan directamente nada para dibujar el camino sobre nosotros, tenemos que usar el método de trazo incorporado. Ahora, estamos dibujando una línea a partir de las coordenadas 300, 302, coordenadas 350, 400. Podemos cambiar estos valores para cambiar dónde comienza nuestra línea y dónde termina. Puedo borrar el rectángulo. Ahora bien, en esta área, quería definir escenarios globales. El ancho de línea será de diez píxeles o 100. Muevo las coordenadas. Tenemos muchas otras propiedades que podemos usar aquí. Puedes verlos todos si la consola registra CTX desde la línea dos como lo hicimos antes, por ejemplo, mira lo que sucede cuando dije la propiedad Line Cap para redondear. Configuré el estilo de trazo en magenta, ancho de línea en diez. También podemos encadenar múltiples líneas dos métodos como este. Cada nueva línea dos métodos, vamos a definir otro punto en la forma que se conectará con nuestro subpath. Y escribió el dentista, este es el concepto principal de animación que estamos haciendo hoy. Tendremos una línea que empieza en alguna parte. Entonces tendremos muchas llamadas de la línea dos a los puntos de hallazgo a lo largo de ese camino. Y similar al clásico juego de serpiente, vamos a animar esto agregando siempre un nuevo segmento de línea al inicio y eliminando el último segmento, Haciendo que parezca que la línea se arrastra por la pantalla. Añado una nueva línea. Añado uno más. Elimino el segmento más antiguo, agrego otra línea nueva. Automatizaremos esto y jugaremos con las coordenadas que pasemos a estas líneas para crear interés en los patrones de movimiento. Una vez que entiendas este concepto, lo usaremos para construir hermosos campos de flujo como este en una clase avanzada. Podría ser más fácil de lo que piensas hacer que las líneas fluyan alrededor de imágenes o letras. 6. Programación orientada a objetos: Ahora que entendemos el concepto, vamos a escalarlo. Quería crear una clase JavaScript personalizada que dibujara y animara líneas para mí, quería animar muchas líneas al mismo tiempo. Entonces usar una clase es ideal aquí. El constructor de clase es un método especial para crear una instancia de una clase. Cuando lo llamamos con la nueva palabra clave later class constructor, crearemos un nuevo objeto JavaScript en blanco, y establecerá sus propiedades y valores basados en el blueprint interior. Entonces definamos ese plano. Quiero que empieces muy sencillo y vamos a optimizar el código después para asegurarnos de que quede absolutamente claro lo que está pasando. Cada objeto de línea tendrá las coordenadas x e y iniciales. Entonces, una propiedad personalizada que llamo, por ejemplo start x será un punto aleatorio entre cero y ancho horizontalmente. coordenada vertical inicial de cada línea será un valor aleatorio entre cero y una especie de altura vertical. Entonces, cuando combinamos estas coordenadas x e y aleatorias, nos dará un punto en algún lugar dentro del área del lienzo. Quiero hacer lo mismo para terminar las coordenadas x e y así. Entonces, cuando se crea un nuevo objeto de línea, se le asigna aleatoriamente el punto de inicio y el punto final. Vamos a darle un método de dibujo personalizado para trazar una línea entre estos dos puntos. Yo llamo comenzar camino primero. Mover al método para definir las coordenadas x e y iniciales de la línea. Método de la línea dos para definir coordenadas x e y finales de la línea. Y llamamos trazo para renderizar realmente ese camino en Canvas. Tenemos una clase, nuestro plano está listo. ¿Cómo lo usamos realmente para crear un objeto de línea? Yo creo una variable constante, llamo a la línea uno. Lo puse igual a nueva línea así. La nueva palabra clave buscará una clase con este nombre y activará su constructor de clase. Constructor de clase, crearemos un nuevo objeto JavaScript en blanco, y le asignará valores y propiedades basados en el blueprint dentro de ese objeto se guardará en disgusto ellos línea una variable. Dado que este objeto fue creado usando la clase de línea, tiene acceso a este método de dibujo público y puedo llamarlo así como esta línea un dibujo de punto, se calcularon las coordenadas de inicio y finalización aleatorias y se dibujó una línea perfecta. Arriba en la línea siete, ancho de línea incierto a diez píxeles. Pero tal vez quiero que cada línea creada por la clase tenga un ancho aleatorio dentro de un rango predefinido. Creé esta propiedad de ancho de línea de puntos, y será un valor aleatorio, 1-16 píxeles. Lo envolveré en Math.floor para que no obtengamos valores de subpíxeles. Es un buen hábito hacer eso por todo lo que dibujamos en Canvas siempre que sea posible. También podría haberlo hecho para las coordenadas x e y. Tomo CTX de línea a ancho de línea y lo configuro a este valor de ancho de línea aleatorio. Ahora, cada vez que actualice la ventana de mi navegador, alinearme con la posición aleatoria y se dibujará el ancho de línea aleatorizado. Estamos haciendo algo que aquí se considera una mala práctica. Definí la variable canvas en la línea uno, y estoy usando esa misma variable directamente dentro de mi clase. Yo hago lo mismo con la variable ctx. El código funcionará, pero si estás escribiendo código orientado a objetos, el objetivo es mantener a tus clases independientes de su entorno léxico, independiente del código que está fuera de la clase misma. ¿Correcto? Ahora bien, esta clase sólo funcionará si aquí se definen las variables Canvas y CTX. La forma correcta de hacerlo es convertir estas variables externas en propiedades de clase. De esa manera, se pasará al constructor de clase aquí cuando se cree la clase. Y pueden venir de cualquier parte de nuestra base de código, haciendo que nuestra clase sea más autónoma y reutilizable. A menudo me preguntas por qué hago esto en los comentarios, así que espero que esto lo explique. constructor de clase de línea esperará el cannabis como argumento. En el interior. Convierto ese argumento en una propiedad de clase. Estoy diciendo tomar la variable canvas que se pasó aquí y convertirla en propiedad Canvas en esta instancia de clase de línea que estás creando en este momento. Entonces podemos usar este punto Canvas de la línea 12 aquí, en lugar de tirar directamente de la variable de la línea uno. Para que todo esto funcione, sé que el constructor de clase de línea nos espera como argumento. Entonces tomo la variable canvas de la línea uno y la paso como argumento aquí. Cuando creamos una instancia de esa clase con la nueva palabra clave perfect, también estamos tirando directamente de la variable CTX de la tierra a nuestra clase aquí. Por lo que nuestro método de sorteo público esperará contexto como argumento y se utilizará aquí. Después tomamos CT x-variable de la línea dos y la pasamos a dibujar método aquí abajo. Cuando lo llamamos así, CTX se convertirá en contexto aquí. Entonces así es como haces que las clases sean más autoencerradas y menos dependientes del frío circundante fuera de esa clase. 7. Colores dinámicos con HSL: Estamos definiendo el estilo de trazo en la línea ocho, pero tal vez quiero que el color de las líneas también sea aleatorizado. En ese caso, tengo que definir el estilo de trazo dentro del método de dibujo aquí. Dije que es para escribirlo solo para probarlo. Si está funcionando. Quería asignar un color aleatorio cada vez que creamos una nueva línea. La forma más fácil de hacerlo es mediante el uso de la declaración de color HSL en la web, podemos definir colores de muchas maneras diferentes. Tienes tus declaraciones de color RGB y hexadecimal estándar con las que todos están familiarizados. También podemos usar declaración de color HSL, matiz, saturación, luminosidad. El primer argumento aquí, representarás un grado en la rueda de colores 0-360. La saturación será del 100 por ciento. Queremos colores completos. La ligereza será del 50 por ciento. Queremos un color no afectado por la luz u oscuridad. Cero grados en la rueda de colores es correcto, como puedes ver, 120 es verde, 240 es azul, 360. Volvimos al rojo en bicicleta. Otra vez. A medida que aumentamos la vista, viajamos por todos los colores intermedios. Si vamos más altos que 360, simplemente volvimos a pedalear desde el principio desde el color rojo. La declaración de color Hsl está estructurada de una manera que hace que sea muy fácil aleatorizar colores o ciclar dinámicamente a través del espectro de color. Creo una propiedad de clase personalizada. A esto lo llamo punto vista. Será un valor aleatorio 0-360, y quiero solo enteros. Entonces Math.floor, haremos que el estilo de trazo sea dinámico reemplazando el valor de tono codificado con esta variable aleatoria como esta. Y eso es todo. Cada vez que refresco la página, calculamos aleatoriamente un color diferente. 8. Arte aleatorizado en línea: Como decíamos, la clase JavaScript es un blueprint. Podemos usarlo para crear muchos objetos similares. Entonces, ¿por qué estamos creando una sola línea aleatoria? Vamos a crear muchos más. En este punto, es muy fácil. Primero creo una variable llamada matriz de leones. Esta será una matriz para mantener todos los objetos de la aerolínea en un solo lugar. Ahora puedo crear un for-loop. Ese bucle for se ejecutará por ejemplo diez veces. Cada vez que se ejecuta, tomo la matriz de líneas y llamo al método push de matriz incorporado. Método Push. Tomaremos lo que le pasemos como argumento y lo empujará hasta el final de la matriz. Le pasaré una nueva línea. Y en línea 11, puedo ver que constructor de clase de línea espera Canvas como argumento. Así que le paso canvas variable de la línea uno. Elimino este código, y me consolar el array de líneas de registro. Como era de esperar, contiene diez objetos de línea creados usando nuestra clase de línea personalizada. Abro uno e inspeccioné para asegurarme de que todas las propiedades tengan valores. Quiero que compruebes que nada está indefinido, lo que sería una señal de un problema. Todo está bien aquí. También puedo crear un número de líneas, una variable, y la configuro en 50. Lo uso aquí en el for-loop. En la consola, puedo ver que la matriz de líneas ahora contiene 50 objetos de línea con posiciones aleatorias, ancho de línea y colores. ¿Cómo los dibujamos? Dado que estamos sosteniendo todos los objetos align dentro de la matriz de líneas, simplemente podemos llamar a una matriz incorporada para cada método en él, para cada método llamará a una función de devolución de llamada proporcionada una vez para cada elemento de la matriz. Así que dentro, para cada objeto de línea en la matriz, quiero llamar a su método de dibujo asociado que definimos en la línea 20. Si te estás preguntando de dónde viene esta palabra objeto, es solo una palabra aleatoria que elegí usar. Básicamente somos un inicio de sesión en cada objeto de la matriz, un nombre de variable que se utilizará para hacer referencia a ese objeto dentro de este para cada método, ese nombre de variable puede ser cualquier cosa siempre y cuando sigamos refiriéndonos a él de esa manera en todas partes dentro de este método de devolución de llamada, también puedo llamarlo línea por ejemplo así para cada objeto de línea dentro matriz de líneas llamado su método de dibujo. En la línea 20, puedo ver que el método draw espera contexto como argumento. Entonces le paso variable CTX. Definimos en la línea dos. Estamos dibujando 50 líneas sobre Lienzo. Cada uno tiene coordenadas de inicio y finalización aleatorias, ancho aleatorio y color. Puedes refrescar la página para generar un nuevo conjunto de valores aleatorios y dibujarlos en Canvas. Enhorabuena si este es tu primer proyecto de codificación creativa, esta es una forma muy sencilla de arte generado por procedimiento, el llamado arte generativo. El arte generativo es una colaboración entre un ser humano y una máquina. Las reglas y alcances de esta obra son decididas por nosotros, los humanos. Pero algunas de las características, en este caso colores y posiciones, son decididas aleatoriamente por una computadora. Por supuesto, hay formas mucho más avanzadas de arte generativo. E hice muchas clases donde exploramos eso de diferentes maneras. Veamos a dónde podemos llevar esta. Vamos a animarlo. 9. Dibujo de líneas multi-segmented: Para mayor claridad, volveré a una línea para que podamos ver mejor lo que está pasando. Como dijimos al principio, quería tener una línea hecha de múltiples segmentos. Estaremos agregando nuevos segmentos y quitaremos unos viejos para que parezca que se arrastra como el clásico juego de serpientes. Necesito hacer algunos cambios en la clase de línea para lograrlo, solo necesitaremos un conjunto de coordenadas x e y, así. Estas coordenadas se actualizarán para cada tick del bucle de animación y agregaremos y mantendremos un cierto número de posiciones en una matriz de historia que defino aquí. Primero, será un objeto simple con propiedad x e y igual a este punto x y este punto y acabamos de aleatorizar aquí. Este historial de nodos es un objeto ahora, pero será una matriz donde cada elemento esa matriz es un objeto como este con las coordenadas x e y. El método Move to definirá las coordenadas x e y de inicio de nuestro camino. Y será este índice de matriz de historia de puntos cero, que será objeto así. Y accedemos a su coordenada x y también a su coordenada y. Digamos que voy a mantener diez objetos dentro de la matriz de historia. Cada uno tiene su valor de posición x e y. Aquí quiero recorrer sin importar cuantas posiciones tengamos en la historia array, y quiero conectarlas con una línea. Así que creo un bucle for que se ejecutará tantas veces dependiendo de la longitud de esta matriz de historia de puntos desde la línea 15. Y cada vez que se ejecute, tomará objeto, que se verá así en ese índice en la matriz, y pasará sus coordenadas x e y al método de la línea dos. Así que nos hemos movido al método para establecer la posición x e y inicial de la línea. Y luego recorremos todas las demás posiciones y las conectamos con una línea. Entonces llamamos trazo para renderizar ese camino multisegmentado en Canvas. Aún no tenemos bucle de animación, así que crearé otro bucle for que simplemente ejecutaremos tres veces y crearemos tres posiciones x e y aleatorias. Necesito asegurarme de que la historia de la piedra aquí arriba sea en realidad una matriz. Al principio, contendrá solo un elemento con un índice de cero. Será este objeto el que tenga las propiedades x e y establecidas en estas coordenadas de punto x e y. Aquí corro un for-loop tres veces. Cada vez que se ejecuta, creo nuevas posiciones x e y aleatorias. Tomo distorsionar la matriz de historia y empujo otro objeto con estas nuevas propiedades x e y en su cuidado con los corchetes aquí. Bonito. Cada vez que actualizo la ventana del navegador, dibujamos una nueva línea de múltiples segmentos comenzando las coordenadas x e y. Y para bucle que se ejecuta 123 veces cada vez que crea un segmento de línea, una subruta. Puedo hacer que el for-loop se ejecute 30 veces si quiero, lo que creará una forma mucho más compleja. Espero que quede claro ahora cómo funciona el concepto de matriz de historia. Ahora vamos un paso más allá para animarlo. 10. Líneas animadoras: Creo una función personalizada a la que llamo, por ejemplo, animar. En el interior, trazaremos una línea. Lo actualizaremos. Y luego llamamos marco de animación de solicitud incorporado, que le dice al navegador que queremos realizar una animación. Esto hará que el navegador llame a una función que especificamos antes del siguiente repintado. En la práctica, esto significa que simplemente le paso el nombre de su función padre, animo carreras, hace algo y luego solicito fotograma de animación. Volveremos a llamar a animar, creando un bucle de animación repetitivo sin fin. Solicitar el método de marco de animación se ajusta al objeto de ventana, pero se puede llamar directamente así. Entonces aquí definimos animar. Tengo que llamarlo. Para iniciar el primer bucle de animación. Pongo un registro de consola dentro que dice animando, solo para comprobar que el loop realmente se está ejecutando. Sí, eliminé. Quiero poner nuestro código de sorteo dentro así. Esto es solo crear un crecimiento interminable en línea. Podemos comentar temporalmente esquema para los siete. Si tu computadora lucha con esto, lo arreglaremos en un segundo. Quiero eliminar pintura vieja entre todos los fotogramas de animación, así que llamo método de rectángulo claro incorporado. Quiero borrar todo el lienzo desde la coordenada cero-cero hasta el ancho del lienzo, la altura del lienzo. Bien, comento esto porque estamos agregando 30 segmentos de línea una y otra vez en matriz de historia aquí en la línea 20 para crear un interminable grow in array, creo un método de actualización en la clase de línea para cada fotograma de animación, cada vez que se ejecuta el método de actualización, quiero agregar uno nuevos segmentos a nuestra línea. Voy a borrar todo esto. Descomento la línea 47. Y por cada tick de animación, quiero que llamen al método de dibujo en cada objeto dentro de la matriz de líneas. Actualmente, solo tenemos un objeto ahí dentro. También quería llamar al método de actualización que acabamos de definir. Ahora podemos ver línea se dibuja segmento por segmento. No tiene sentido recorrer la misma matriz dos veces aquí. Entonces, en cambio, llamo dibujar y actualizar en la misma función de devolución de llamada. Cuidado con los corchetes aquí. ¿Es para cometer un error y obtener un error? Bonito. No quiero que esté dibujando un camino con una cantidad de puntos infinitamente creciente. Quiero tener cierta longitud máxima. Y cuando se llegue a eso, eliminaremos el segmento más antiguo y agregaremos uno nuevo. Digamos que quiero que el camino tenga diez segmentos de largo. Método de actualización interna. A medida que agrego un nuevo segmento, verifico si la longitud de matriz histórica es mayor que la longitud máxima. Si es más de diez, usaremos el método de desplazamiento de matriz incorporado. El método de desplazamiento de matriz elimina el primer elemento de la matriz porque estamos usando método push para agregar un nuevo segmento. El método Push agrega un nuevo elemento al final de la matriz. El método Shift eliminará el segmento más antiguo para nosotros desde el inicio de la matriz. Y aquí llegamos al segundo paso en nuestra línea procesal art. ¿Qué opinas de esto? Escala, pero con reglas, podemos agregar tantas líneas como queramos. Todos tienen ancho y color aleatorios debido a la lógica que escribimos al principio, solo estamos recogiendo puntos al azar dentro del cannabis. ¿Y si queremos alguna sensación de movimiento continuo? Queremos que la posición actualizada del siguiente segmento tenga alguna relación con la posición del segmento anterior. Esto nos está acercando un paso más a un campo de flujo real. Espero que estés obteniendo algo de valor. Exploremos el movimiento y ahora pensaré en nuestra línea como una partícula. Su primer segmento se mueve a lo largo del lienzo en cierta velocidad y dirección. Los otros segmentos siguen. Doy a cada línea velocidad X, velocidad horizontal y velocidad. ¿Por qué la velocidad vertical? Comenzaremos desde un punto aleatorio en algún lugar dentro del área del lienzo. Y cada vez que llamamos método de actualización, aumentamos la exposición actual por el valor de velocidad x y posición vertical y por el valor de velocidad. ¿Por qué? Insight animation loop Voy a descomentar, dibujar y actualizar para ver lo que acabamos de hacer. Bien. Yo creo 20 líneas. Sí. Esto es lo que está pasando. 11. Efecto de tormenta de rayos arco iris: Voy por el efecto de aligeramiento. Quiero una tormenta relámpago arcoíris. Cada vez que actualicemos la posición horizontal por velocidad x de diez píxeles, además de eso, agregaremos un valor aleatorio 0-10 y 50. ¿Qué pasa con un valor aleatorio entre -25 y más 25 horizontalmente y los mismos intereses verticales Entonces cuando refresco mi página, me sale un juego de relámpagos muy cortos. Si quiero que vayan más de arriba a abajo, tal vez la velocidad horizontal sea solo más u2 y la velocidad vertical 15 o 46. Me gustaría que la animación se reproduzca y luego se restablezca. Podría, por ejemplo, verificar si todos los segmentos salieron del área del lienzo. O puedo darle un temporizador a cada línea. Digamos que cada línea tiene una vida útil de longitud máxima desde la línea 18 por diez, cada línea se moverá durante 100 fotogramas de animación. Dentro del método de actualización, aumentaré el temporizador en uno por cada fotograma de animación. ¿Cómo hago esto? Si el temporizador es menor que la vida útil? Animamos la línea. También necesito definir este temporizador de puntos en el constructor de clase aquí arriba. E inicialmente lo puse a cero. Cuando el temporizador es más que vida útil, seguimos dibujando las líneas, pero ya no estamos agregando y quitando segmentos, así que parece que se congelaron en el espacio. En ese punto, quiero comenzar a eliminar segmentos uno por uno hasta que desaparezca la línea. Entonces si no, y aquí volveré a llamar turno en la matriz de historia. Tened un segundo conmigo. Necesito elaborar la lógica aquí. Tenemos que asegurarnos de que siempre haya al menos un elemento en la matriz. De lo contrario, si esta longitud de punto histórico de puntos es menor o igual que uno, llamado método de reinicio. Vamos a definir el método de reinicio. Ahora bien, ¿funcionará esto? El temporizador está aumentando siempre y cuando el temporizador sea menor que la vida útil, agregue y elimine posiciones, haciendo que la línea se arrastre alrededor. Si la longitud es menor o igual a uno, restablecerla. contrario, es decir, el temporizador es más que la vida útil, pero la longitud aún no es menor o igual a uno. Sigue eliminando un segmento a la vez. Creo que esto debería funcionar. Ahora necesito definir el método de reset que acabaremos de establecer la línea de nuevo a su estado inicial para que podamos animarla. Otra vez. Tendremos que restablecer la posición x e y, y agregaremos esa posición inicial dentro de la matriz de historial. También reiniciaremos el temporizador a cero para que pueda volver a contar. Estoy recibiendo un error de consola. Probablemente note esto antes de que necesite llamar a un turno para eliminar el primer segmento de la matriz en la matriz de historial real. Así. Sí, esto es lo que quería. Las líneas se mueven alrededor de 400 fotogramas de animación y luego se reinician. Todos se reinician al mismo tiempo porque codificamos duramente maxlength para que sea el mismo valor para todos ellos. Lo configuré a un valor aleatorio, 10-160 segmentos. Ahora estamos obteniendo cierto sentido de movimiento. También puedo aleatorizar la velocidad x, digamos un valor aleatorio entre -2.5 y más 2.5 velocidad, y será seis. Velocidad. ¿Por qué diez? A lo mejor aquí debería hacer valor aleatorio entre -0.5 y más 0.5. Velocidad Y5 siete. También puedo jugar con el rango aleatorio aquí y aquí. Generar números aleatorios como este para cada fotograma de animación es muy caro para el rendimiento, solo para que lo sepas. Pero como no tenemos miles de líneas, la mayoría de las computadoras probablemente ni siquiera notarán reducir cuántas veces tus llamadas de base de código dominaron el marco de animación de pares aleatorios aumentará masivamente el rendimiento de tus efectos. Dije vida útil a longitud máxima por tres. Se puede ver que tenemos una línea que parte de un segmento. Crece hasta alcanzar la longitud máxima, luego llama a un máximo de tres términos. Es maxlength. En ese punto, ya no crece. Se encoge desde el último segmento desde el final, y luego desaparece y se restablece. Este tipo de movimiento de línea es exactamente lo que necesitas para crear campos de flujo. Ahora bien, una forma de implementarlo. Yo creo 100 líneas. Esta es mi versión de tormenta relámpago arcoíris generada por procedimientos. Si eres principiante y has seguido todo el camino hasta aquí, ahora eres un corredor creativo con un conocimiento del lienzo HTML. Enhorabuena, siéntete libre agregar este proyecto, tu currículum en línea. 12. Degradado lineal: Html canvas ofrece tantas herramientas integradas diferentes que nos permiten modificar nuestras animaciones. Acabamos de construir el efecto de tormenta relámpago arcoíris. Las líneas que estamos dibujando en Canvas son solo formas. Déjame mostrarte cuatro formas muy diferentes cómo puedes mejorar el relleno y trazo de tus formas usando gradientes, imágenes y sombras. Html canvas ofrece dos métodos para dibujar gradientes. Podemos utilizar el método de crear gradiente lineal. Es muy sencillo de usar. Déjame mostrarte. Crea un degradado a lo largo de una línea que conecta dos conjuntos dados de coordenadas. Primero dos argumentos, le pasamos nuestras coordenadas x e y del punto de inicio. Quiero que mi gradiente comience en la coordenada cero-cero. Y yo quería que el punto final estuviera en coordenadas lienzo ancho, alto. Dibujamos una línea invisible de aquí a aquí. El gradiente se dibujará a lo largo de esta línea. Para trabajar con gradientes, ayuda a guardarlo en una variable. Yo lo llamo por ejemplo gradiente uno. Entonces tomo esa variable y llamo al método incorporado add color stop en ella. Aquí definimos offset y color. Entonces en el desplazamiento cero al inicio del gradiente, quería comenzar desde el rosa. Copo esta línea algunas veces. Empecemos en el desplazamiento 0.2. En realidad, se leerá 0.3. 0.4 es naranja, 0.5 es el amarillo. 0.6 será verde. 0.7, turquesa, 0.8 es violeta. Eso es suficiente. Creo que tomaría esta declaración de estilo de trazo y la puse aquí después de definir el degradado. Y lo pondré a la variable que contiene nuestro degradado lineal recién definido. Observe que no hay comillas, solo el nombre de la variable así. También necesito comentar la línea 33 para que se aplique nuestro gradiente. Como puede ver, estamos dibujando un degradado lineal desde coordenada cero-cero hasta el ancho del lienzo, la altura del lienzo. Yo creo 200 líneas. Esta es una versión muy diferente de la tormenta relámpago arcoíris, ¿no? 13. Degradado radial: Copio esta línea de código. Yo lo llamaré gradiente a. También hemos creado un método de gradiente radial. Este espera al menos seis argumentos, x e y del punto central del círculo de inicio interno y su radio. Quiero que el punto central del círculo esté en medio de Canvas. Entonces, el ancho del lienzo es de 0.5, alto del lienzo por 0.5 y el radio será de 30 píxeles. El círculo final también estará comenzando en el centro de la lona con un radio de 200. Se lo doy a las paradas de color solo para mostrarte cómo se ve eso. Creo que ya entiendes este concepto de todos modos. A 0.4 offset, tendremos verde desde 0.6, será azul. Después configuro el estilo de trazo en la herramienta Degradado. Aquí. Puedo cambiar el valor del radio. Puedo agregar parada de color aquí. Entonces así es como se usa el gradiente lineal y radial. 14. Cómo rellenar formas con un patrón: A medida que estamos llenando nuestras formas con gradientes, podemos llenarlas con un patrón. Ese patrón puede ser algo que dibujemos en un lienzo fuera de la pantalla, pero también podemos usar una imagen. En index.HTML. Yo creo un elemento IMG. Le doy una identificación de imagen de patrón. Como fuente, normalmente usaría una ruta hacia ese archivo de imagen, pero eso nos daría problemas si ejecutamos nuestro código localmente solo desde una carpeta sin usar un servidor para evitar problemas de uso compartido de recursos entre orígenes, convertiré la imagen real en código base 64, y haré que ese código sea parte de nuestro archivo HTML índice. Cuando haga eso, la imagen será considerada el mismo origen en todos los escenarios. Así que no tengo que lidiar con nada sitio servidor. En este curso, quiero enfocarme en el desarrollo web front-end. Preparé una imagen que puedes descargar en la sección de recursos a continuación, la hice del mismo tamaño que nuestro lienzo. También podemos usar tu propia imagen si quieres. Puedo usar JavaScript para convertir la imagen en cadena de datos base-64 dibujándola en Canvas y usando dos URL de datos método incorporado. Pero por simplicidad, voy a usar un sitio web para hacer eso por mí, hay muchos sitios web que pueden convertir las imágenes en código en segundos para nosotros, solo voy a Google y busqué PNG para basar la frase 64. Voy a elegir este enlace en línea PNG tools.com. Arrastre y suelte la imagen que quiero convertir aquí y me genera una cadena de datos. Tenemos que asegurarnos de que la cadena comience con la base 64. Si no cae, da clic en esta casilla de verificación para obtener el formato correcto. Copio todo este bloque de código. Es mucho código dependiendo de qué tan grande sea la imagen que estés usando. Lo pego aquí dentro del argumento fuente, dentro como RC. En Visual Studio Code, puedo ir a View where drop para poner esta línea extremadamente larga de código en una línea, facilitando la navegación en este archivo de código. Voy a estilo CSS. En realidad guardé los cambios en index.HTML y se puede ver que estamos dibujando la imagen en la página web sin necesidad del archivo de imagen real. El código que acabamos de generar reemplaza completamente el archivo de imagen y contiene toda la información de píxeles sobre esa imagen. Oculto la imagen con CSS usando su ID display none. Bien, tenemos una imagen que podemos usar. Entonces en esta área, definimos los gradientes. Aquí, vamos a crear un patrón. También es muy fácil. Voy a necesitar una referencia a ese elemento IMG acabamos de crear en index.HTML. Creo una variable a la que llamo pattern image, y apunté JavaScript hacia el elemento IMG usando su ID. Otra variable que llamo patrón uno es igual al punto ctx. Y aquí usamos el método de creación de patrones incorporado. Este método funciona de manera muy similar a los dos métodos que utilizamos para crear gradientes. Se necesitan dos argumentos, imagen y repetición, y luego podemos usarlo como FillStyle o estilo de trazo para llenar nuestras formas con esa imagen. Déjame mostrarte cómo se ve eso. La imagen a dibujar será la imagen de patrón que acabamos de crear. Y la regla de repetición no será repetida. Ahora simplemente configuro un estilo de trazo en el botón uno. Y aquí vamos. Podemos ver que nuestras líneas ahora están llenas de una imagen. Esta técnica se puede utilizar como una forma de revelar una imagen, por ejemplo, dependiendo de qué tipo de aplicación o efecto estés construyendo, también podemos usar un mosaico sin costuras como imagen para crear un patrón repetitivo, que es probablemente para lo que se diseñó este método. Como propósito principal, puedo usar líneas más anchas para ver más de la imagen e.g 15. Mejora tus efectos con sombras: Me gusta usar las sombras de Canvas para obtener a mis formas un sutil efecto 3D. Dije desplazamiento de sombra a dos píxeles. Esto definirá la distancia entre sombra y la forma horizontalmente. Desplazamiento de sombra y, la distancia vertical también será de dos píxeles. Esto puede ser valores positivos o negativos, por cierto, dependiendo de qué lado, relativo a la forma que quieras que sea la sombra. El color de la sombra será blanco. Esto nos dará estas interesantes grietas afectan o reducen el número de líneas. Bloque de color de sombra. Puedo volver al gradiente uno, el gradiente lineal. Ahora podemos ver mejor qué está haciendo la sombra y cómo resalta los bordes. Si tienes algún problema de rendimiento y caídas de FPS, la forma más rápida de solucionarlo es reducir el número de líneas que estás animando. Y también puedes desactivar estas sombras. Suministro y ancho a un valor menor. Nuestra tormenta relámpago arcoíris puede tomar muchas formas, y creo que ahora tienes muchas herramientas para ajustarla y hacerla tuya. Hagamos algo completamente diferente con esto. Ahora. ¿Qué tal en lugar de relámpagos, quiero espirales Hablemos de trigonometría. Como siempre, es posible que desee crear una copia de su código para guardar este efecto para una referencia futura, haremos cambios radicales en el código ahora y lo transformaremos lo transformaremos una obra de arte generativa completamente diferente. 16. Trigonometría: La trigonometría tiene que ver con los ángulos. Quiero que cada objeto de línea tenga su propia propiedad de ángulo. Entonces lo defino aquí. Por cada fotograma de animación, estaré aumentando sin cesar ese valor de ángulo en 0.1. Este valor representará radianes. Entonces, en lugar de hacer este efecto de aligeramiento aquí, voy a aumentar x por signo Masdar y le paso este valor de ángulo cada vez mayor. Esto creará un movimiento horizontal a la izquierda y a la derecha como este. El análisis y cada aumento en el valor a metóxido simplemente mapearán estos valores a lo largo de una onda sinusoidal. ¿Y si quiero que las olas vayan más a la izquierda y a la derecha? Creo una propiedad llamada esta curva punteada y la puse en 30. Por defecto, el método seno es ciclo entre menos uno y más uno. Si multiplico ese valor por esta curva punteada, aumentamos ese rango. Y este es el resultado. Quiero líneas suaves, así que elimino esta parte del código aquí. Trate de usar un valor diferente para la curva. Si necesitas más claridad sobre cómo este valor afecta el movimiento de nuestras líneas. Y si quisiera curvar para comenzar en un valor muy pequeño y poco a poco aumentar, la curva inicial será 0.1. Y Vc, la velocidad a la que estará cada vez más será de 0.25. Dentro del método de actualización para cada fotograma de animación, quería aumentar la curva por VC así. Y cuando las líneas se reinician, quiero que el ángulo y la curva vuelvan a cero. Efecto interesante. Podemos hacer tantas cosas diferentes con él ahora. 17. efecto de garabatas en el caos: Y si también aumentara la coordenada y vertical por seno de la curva de tiempos de ángulo, obtenemos este extraño movimiento de ida y vuelta. Pero si uso coseno en lugar de seno y coseno, trabajaremos juntos para mapear un camino a lo largo de un radio de círculo. Y debido a que la curva va aumentando a medida que se ejecuta la animación, no obtenemos Circle. De hecho, obtenemos espirales. Dije VC, velocidad de curva a un valor mucho menor. Ahora estamos dibujando espirales así. También puedo hacer que sea un valor aleatorio entre -0.2 y más 0.2 menos los valores se moverán en la dirección opuesta. A lo mejor también quiero aleatorizar qué tan rápido aumenta el ángulo. Va, La velocidad del ángulo será un valor aleatorio entre -0.25 y más 0.25. Entonces lo uso aquí en lugar del valor codificado duro. La velocidad a la que aumenta el ángulo afectará qué tan compacta es la curva, qué tan rápido se extiende. Esto es simetría. Quiero agregar un poco de caos ahora para este sencillo proyecto de arte, o imaginar que alguien está dibujando estas hermosas espirales simétricas. Pero en cierto punto se enojan y empiezan a garabatear al azar y rompen la forma de espiral. Digamos que si el temporizador es más de la mitad de la vida útil, la segunda mitad del ciclo de vida de las líneas comienza a multiplicar va por menos uno, cambiándolo al valor opuesto cada vez que toma un nuevo fotograma de animación, cada vez que se dibuja un nuevo segmento. Esto romperá la espiral con esta forma. Tenemos un camino que comienza como una espiral y luego se convierte en una línea discontinua. Yo quería que la línea estuviera cada vez más rota. Necesitamos más caos al final. Sí. Cambiemos esto a 0.9. La mayoría de las veces será simetría. El último 10% será un caos porque estamos modificando valor va y no lo estamos trayendo de vuelta a su gama original. Las líneas dejan de hacer espirales como deberían. A medida que las líneas se restablecen, necesitamos ser también reseteados y el valor va. Copio la línea 48 y la pego aquí abajo dentro del método de reset. Bonito. Empezamos con la simetría y terminamos en el caos. Exactamente como yo un sábado por la noche. Constantemente estamos calculando tiempos de vida 0.9 porque este cálculo ocurre muy a menudo para facilitar que JavaScript ejecute este código y ayude un poco al rendimiento. Podemos precalcular esto solo una vez en el constructor de clase, y luego usaremos ese valor precalculado aquí. Lo llamaré e.g Este punto de ruptura de punto y será tiempos de vida útil 0.85. Entonces puedo usar este punto de ruptura aquí. Y en lugar de calcular esto 60 veces por segundo para cada objeto de línea, ahora, solo lo estamos calculando una vez para cada línea en el punto donde cada objeto de línea se crea usando el constructor de clase. Hago las líneas más anchas. Dije lienzo de fondo a negro. Sí, este es el efecto que quería. Comento el estilo de trazo en la línea 54. Ahora el trazo es negro así que no vemos nada. Se lo puedo dar al color blanco. Ahora podemos volver a ver cómo las sombras le dan un efecto 3D muy sutil. Dije número de líneas, 250. Ten cuidado aquí. Puede ser demasiado para computadoras más antiguas y es posible que obtenga un FPS más bajo. Yo hago 100, ahora solo estoy experimentando. Puedo establecer el estilo de trazo al degradado lineal que definimos en la línea 15 solo para ver cómo se ve eso. ¿Qué tal si uso gradiente radial? Para este, definitivamente debería elegir diferentes colores para que se vea bien. También puedo volver a usar el patrón de imagen aquí. Interesante. ¿Has visto este gran método de patrón que se usa antes o es tu primera vez? Ahora tienes todas las herramientas que necesitas para crear campos de flujo completamente animados y hermosos, echa un vistazo a los enlaces en la descripción y únete a mí en una clase avanzada donde utilizamos las técnicas que aprendimos hoy para crear arte más generativo. 18. ¿Qué es un campo de flujo: Aquí hay una cuadrícula de ángulos. También podemos llamarlo campo vectorial si agregamos sistema de partículas encima de él y hacemos que las partículas fluyan sobre la cuadrícula. Su movimiento está influenciado por el vector de campo. La dirección y velocidad de movimiento estarán influenciadas por el valor del ángulo almacenado en la celda sobre la que se mueve actualmente cada partícula. Esta clase es para personas creativas que quieren entender cómo funciona el código bajo el capó. No olvides consultar la sección de recursos para descargar el código fuente si quieres compararlo con el mío. Incluí múltiples descargas de código fuente en puntos clave del proyecto a medida que avanzamos con la clase en caso de que quieras inspeccionar mi código y compararlo con el tuyo. Creé una página web genérica con elemento HTML canvas en ella. Vinculé a los archivos style.css y script.js. Yo hice un reinicio global de CSS y le di al elemento canvas un fondo negro. 19. Configuración de lienzo HTML: Después de una sencilla configuración de HTML y CSS, todo lo demás en el proyecto será manejado por JavaScript aquí dentro del archivo script.js. Como siempre, necesito configurar mi Canvas variable personalizada llamada cannabis será documento, get element by ID e ID I gave it was canvas one. El contexto ctx es ese lienzo variable punto getContext. Y lo paso a la para crear una instancia de canvas rendering context object. Ahora, el CTX contiene todo integrado en los métodos de dibujo y propiedades que cualquier navegador web puede entender. Quiero que hoy tengas un efecto a pantalla completa. Así que el ancho será ventana en un rave y la altura del lienzo es ventana en su altura. No estoy seguro si lo puedes ver, pero al hacer esto le dio a mi página web barras de desplazamiento. No los quiero tan fácil arreglar es darle a la lona elemento posición absoluta, así, bonito. Entonces toda esta zona negra es nuestro Lienzo, nuestro tablero de dibujo. Puedo usar la variable ctx de la herramienta de línea para dibujar algo. Ahora, si me consola puerta, podemos ver los ajustes por defecto. Por ejemplo, I. Podemos ver que el tipo predeterminado de como FillStyle es negro para asegurarnos de que las formas dibujamos nuestras visibles contra el fondo negro. Dije FillStyle a blanco. 20. Dibujo en forma en lienzo: Aquí abajo podemos ver todos los métodos de dibujo de Canvas incorporados, por ejemplo , el método de arco, que se puede usar para crear un arco o un círculo completo. Si tuviéramos más formas en Canvas, tendré que llamar a comenzar camino. Pero ahora puedo saltarlo. Y digamos que quiero un círculo con un punto central en las coordenadas 100 horizontalmente desde el borde izquierdo de Canvas, 100 verticalmente desde el borde superior. El radio del círculo será de 50 píxeles. El ángulo de inicio del arco será de 0 rad. Y como quiero dibujar un círculo completo, el ángulo final será math.pi por dos, que es aproximadamente 6.28 rad o 360 grados. Círculo completo. El método Arc funciona con un camino, por lo que no renderiza directamente nada en el cannabis. Simplemente posicionó un camino invisible. Podemos elegir trazar ese trazado o rellenar esa forma con color. Entonces llamo método de relleno incorporado como este. Puedo mover el punto central del círculo alrededor. Puedo cambiar el radio. Incluso puedo cambiar el ángulo final o el ángulo de inicio para obtener una forma diferente. Bien, entonces nuestro Canvas está configurado y lo probamos dibujando una forma. En esta área, mantendré mi configuración global de Canvas para mantener nuestro código organizado. Hoy en día, estamos construyendo campo de flujo animado. Se hará a partir de líneas individuales. Entonces, ¿cómo dibujamos una línea simple en Canvas? Comenzamos por Colin, incorporado y comenzamos el método path. Esto iniciará un nuevo camino así como vestirá todos los caminos anteriores. Si hay alguno, llamamos movido al método para establecer las coordenadas x e y de inicio de la línea. Llamamos a una línea a método para establecer el final en coordenadas. O podemos encadenar múltiples líneas a, para crear una forma más compleja, que es lo que vamos a estar haciendo hoy. Igual que el método del arco. Mover a la línea final dos métodos que acabamos de decir anteriormente. No renderizan directamente nada en Canvas. Ahora tenemos que elegir si queremos trazar el trazado o si queremos rellenar esa forma con color, llamaré método de trazo incorporado para dibujar el trazado. estilo de trazo predeterminado es negro, por lo que no es visible contra el fondo negro. Voy hasta aquí y le dije estilo trazo al blanco. Ahora podemos ver que estamos dibujando una línea a partir de las coordenadas 100, 202, coordenadas 400, 500. Por defecto, la línea tiene un píxel de ancho. Puedo usar la propiedad de ancho de línea para establecerla en diez píxeles o 100. También puedo usar la brecha de línea y configurarla para redondear, p. ej. 21. Programación orientada a objetos en JavaScript: Bien, Así es como dibujamos y diseñamos líneas sobre lienzo HTML. Esto es todo lo que necesitamos saber para crear una amplia variedad de efectos. Quería crear muchas líneas animadas que fluirán alrededor de nuestro Canvas. Voy a usar la clase JavaScript llamada particle. Así. Cada partícula se moverá y conectaremos sus posiciones con una línea. Las clases de Javascript son blueprints para crear muchos objetos similares. Y estamos a punto de construir un llamado sistema de partículas hecho de muchas partículas. También voy a tener una clase llamada efecto. Esto podría haber sido solo un objeto simple porque solo tendremos una instancia de esta clase. Será el cerebro principal de nuestra base de código. Entonces tenemos clase de partículas, un blueprint que usaremos siempre que necesitemos crear un nuevo objeto de partícula. Y tendremos clase de efecto que manejará todo el efecto, todas las partículas a la vez. Estoy usando clases y programación orientada a objetos para mantener nuestro código limpio, bien organizado y fácil de leer. Este es un tutorial para principiantes, así que quiero que todo esté limpio y lo más fácil de entender posible. Es mi principal objetivo. clase de afecto deberá estar al tanto del espacio disponible en el cannabis. Entonces el constructor esperará que width y height vengan como argumentos desde el exterior cuando se crea una instancia de esta clase usando la nueva palabra clave dentro, convertí estos argumentos en propiedades de clase. Tome con pasado como argumento aquí y conviértelo a propiedad width en esta instancia de affect class, mismo para height. La clase de efecto tendrá método inicializado. Este método se ejecutará solo una vez para configurarlo todo. Tendremos esta propiedad de partículas de perro. Esta será una matriz que contiene todos los objetos de partículas actualmente activos. Entonces, cuando inicializamos este efecto, queremos tomar esta matriz de partículas de carga y queremos usar método de empuje de matriz incorporado para empujar una nueva partícula en la matriz. Esa partícula se creará usando la clase que definimos en la línea 11. Entonces escribamos esa clase de partículas ahora mismo. Cada partícula también necesitará ser consciente del ancho y alto del lienzo porque necesita saber cuándo se mueve fuera del área del lienzo para mantener nuestro código modular en lugar del tamaño de lienzo booleano de las líneas 3.4, tomaré ese valor de la clase de efecto principal. Quería acceder a estos inmuebles desde las líneas 920. Voy a dar acceso a la clase de partículas a toda la clase de efectos. constructor de clase de partículas esperará efecto como argumento y en su interior lo convertiremos en una propiedad de clase. Entonces aquí estamos apuntando hacia el objeto principal del efecto. Tenga en cuenta que los objetos en JavaScript son llamados para hacer referencia a los tipos de datos. No estamos creando una copia del objeto efecto. Cada vez que creamos una nueva partícula, solo estamos apuntando a ese mismo espacio en la memoria que contiene la clase de efecto de todos los objetos de partículas. De esa manera, las partículas tienen acceso a todos los métodos y propiedades en el vidrio de efecto principal. Y también si alguna de estas propiedades actualiza porque solo estamos apuntando a ese objeto, cualquier cambio en el objeto efecto será inmediatamente visible desde los objetos de partículas, lo que nos será muy útil hoy en día. Como dije antes, vamos a tener un efecto objeto para gestionar todo. Y vamos a tener muchas partículas, cientos o tal vez miles. Veamos cómo va. Cada partícula tendrá coordenada x e y inicial. coordenada x horizontal será un valor aleatorio entre cero y este efecto de punto a partir de la línea 13 ancho de punto, estamos accediendo a esta propiedad desde la línea 20. coordenada y vertical será un valor aleatorio entre cero y esta altura de punto con efecto de punto. Para evitar valores de subpíxeles, es una buena práctica usar enteros, números enteros sin puntos decimales envolviéndolo en Math.floor, esto redondeará el valor al entero inferior más cercano. Cada partícula tendrá un método de sorteo público. Este método esperará contextos como argumento para especificar en qué tipo de nosotros queríamos basarnos. Lo paso como un argumento como este para mantener nuestro código más modular y menos dependiente del entorno exterior. Entonces tomamos ese contexto y llamamos método de rectángulo de relleno incorporado. El método de relleno de rectángulo es muy sencillo. Simplemente tomará estas coordenadas X e Y aleatorias que acabamos de definir, y ahí dibujará un rectángulo. Su ancho y alto serán, por ejemplo, diez veces diez píxeles. Tenemos nuestra clase de partículas y tenemos clase de afecto. Quería crear una instancia de clase de efecto. Creo una variable personalizada que llamo por ejemplo efecto, y será igual a un nuevo efecto como este. La nueva palabra clave buscará clase con ese nombre. Lo encuentra aquí arriba y activará su constructor de clase en línea 23. Podemos ver que efecto espera ancho y alto como argumentos. Entonces lo pasamos ancho de lona desde la línea tres. Y algo así como la altura de la línea cuatro, así. Ahora, puedo tomar que afecte a la variable y llamar al método init que definimos en la línea 28. El método Init tomará la matriz de partículas y empujará un nuevo objeto de partícula en la matriz. Obtenemos un error porque aquí en la línea 12, se puede ver que el constructor de clase de partículas espera una referencia a la clase de efecto principal como argumento, luego usa esa referencia para acceder a las propiedades width y height de Canvas. Ya que estamos creando esa partícula dentro de la propia clase de efecto, le paso esta palabra clave, que en esta área se refiere a toda la clase de efecto. Bonito. Entonces, después de que creamos una instancia de vidrio de efecto, y después de que llamemos a este método init, espero que la matriz de partículas de la línea 26 contenga un objeto de partícula. Consola registro el cristal de efecto a comprobar. Puedo ver el objeto efecto. Tiene propiedades de anchura y altura. Y si abro esta matriz de partículas, puedo ver que hay un objeto de partícula dentro. Compruebo si todas las propiedades tienen valores. Si veo indefinido o no en alguna parte , indicaría un problema. Todo está bien aquí. Ahora, necesito una manera de dibujar realmente mi efecto en Canvas. Le daré otro método al que llamo, por ejemplo, render dentro de nuestro ciclo sobre todos los objetos de partículas dentro usando array para cada método. Por ahora sabemos que solo hay un objeto de partícula en su interior. Para cada objeto de partícula dentro de la matriz de partículas, llamo a su método de retirada asociado. Definimos ese método de dibujo en la línea 17 y podemos ver que espera contexto como argumento. Entonces tomo método render y lo llamo necesitamos este contexto. Entonces tomo CTX de la línea dos. Lo paso para renderizar. Dentro del render se esperará como contexto. Y pasamos esa referencia de contexto para dibujar método porque sabemos que se espera en la línea 17. A partir de ahí, se llama al método del rectángulo de relleno y se dibuja nuestra partícula. Bonito. Puedo cambiar el ancho y altura cuando actualizo la ventana del navegador, coordenadas x e y de las líneas 14.15 se aleatorizan y se dibujan partículas. 22. Dibujo de sistemas de partículas: La clase de efecto principal creo una propiedad que llamo número de partículas. El método inicializado se ejecutará, solo quiere configurar nuestro efecto dentro. Voy a crear estas 50 partículas. Puedo hacer eso usando un bucle for. Se ejecutará 50 veces, y cada vez que se ejecute, tomará matriz de partículas, y empujará una nueva partícula con coordenadas x e y aleatorias dentro. Y así es como se crea un sistema de partículas simple. Si lo deseas, puedes guardar este código como un boilerplate en una carpeta diferente porque puedes usarlo para tantos experimentos diferentes, afectos y obras de arte generativas. Estoy llamando al método init desde aquí en la primera carga de la página. También puedo eliminar este código y lo llamo this.in desde dentro del constructor de clase de efecto. Porque cuando creamos una instancia de una clase usando la nueva palabra clave constructor se ejecutará todo el código en el blueprint línea por línea. Podemos aprovechar ese comportamiento poniendo aquí cualquier código que queramos ejecutar en el mismo punto cuando se crea una instancia de esta clase. 23. Animación de sistemas de partículas: Estamos construyendo un campo de flujo. Quiero que estas partículas se muevan y dejen líneas de senderos detrás de ellas. Animemos esta velocidad X la velocidad horizontal será una. Las partículas se moverán un píxel por fotograma de animación en la dirección positiva. En el eje x horizontal, se moverán hacia la derecha. Velocidad. Y también será un píxel por fotograma. La dirección positiva en el eje y vertical significa hacia abajo. Dado que ambas fuerzas se aplicarán a la partícula al mismo tiempo, esperaba que las partículas se movieran hacia la esquina inferior derecha de Canvas. A ver. El movimiento se manejará dentro del método de actualización. Este método definirá un solo paso en la animación. Y cuando llamamos a este método de actualización 62 veces por segundo, creará una ilusión de movimiento. Por cada fotograma de animación, quiero aumentar la posición x horizontal de esta partícula desde la línea 14 por el valor de velocidad x desde la línea 16. También quiero aumentar la posición vertical por velocidad. ¿Por qué? Aquí dentro de render, a medida que recorremos todas las partículas, activamos ahí método draw y también llamamos al método update que acabamos de escribir. Esto se llama, solo quiere así que no hay movimiento. Y va a llamar a este método de render una y otra vez. Quería dibujar partículas, actualizar sus posiciones, volver a dibujarlas en esas posiciones actualizadas, actualizarlas nuevamente, dibujarlas nuevamente, y así sucesivamente. Llamando a esto una y otra vez, crearemos animación, una ilusión de movimiento. Necesitamos bucle de animación. Creo una función personalizada a la que llamo, por ejemplo animar desde dentro de nuestra llamada render para dibujar y actualizar todas las partículas. Y luego llamo incorporado Request Animation Frame y método. Lo paso, animo el nombre de su función padre. Así animate runs, render se llama particles are drawn and updated and then request animation frame and method calls animate. Nuevamente, tenemos un método de marco de animación de solicitud de bucle diseñado para este propósito, y tiene características especiales como todo para generar las etiquetas de tiempo para nosotros. Y también se ajusta a la frecuencia de actualización de la pantalla. Tengo una pantalla normal, así que mis animaciones funcionan a 60 fotogramas por segundo. Si tienes un juego y una pantalla de alta frecuencia de actualización, tus animaciones se ejecutarán más rápido. Puede usar fácilmente el marco de animación de solicitud y su marca de tiempo generada automáticamente para establecer velocidad de animación que desee. Ahora todo está listo y puedo llamar animar nuestras esperadas todas las partículas para mover un píxel a la derecha y un píxel allá abajo marco de animación. Están dejando senderos porque podemos ver pintura vieja, sus posiciones anteriores. Si quería ver solo el fotograma de animación actual, necesito eliminar Canvas entre cada fotograma usando el método de rectángulo claro. Quiero borrar todo el lienzo desde las coordenadas cero-cero hasta el ancho del lienzo, la altura del lienzo. Bonito. Estamos animando. Cambio de velocidades. La relación entre velocidad x y velocidad. ¿Por qué? Definiremos la dirección y velocidad del movimiento. También podemos aleatorizar la velocidad de cada partícula. ¿Qué tal un valor aleatorio entre -2.5 y más 2.5 menos el valor se moverá hacia la izquierda, más los valores a la derecha En el eje vertical, los valores negativos moverán las partículas hacia arriba. Los valores positivos moverán las partículas hacia abajo. La relación entre la velocidad x aleatoria y la velocidad. ¿Por qué determinará la dirección final del movimiento? Y ahora las partículas se mueven en todas las direcciones posibles. Puedo hacer las partículas más pequeñas. 24. Líneas y senderos para dibujar: En realidad quiero dibujar líneas. Yo llamo método Big Bath para decirle a JavaScript que quería iniciar un nuevo camino. A medida que la partícula se mueve alrededor Canvas para cada fotograma de animación, actualizará su posición x e y. Y haré un seguimiento de esas posiciones como objetos simples con propiedades x e y dentro del array history. Al principio, a cada partícula se le asignará una posición x e y aleatoria en algún lugar dentro del área del lienzo. Y usamos estos valores como el primer objeto, el primer elemento con un índice de cero dentro del array history. El punto de inicio de la línea se guardará por el método move to. Queremos comenzar desde las coordenadas x e y del primer objeto dentro del objeto array history con un índice de cero. Luego creamos un bucle for. Se ejecutará siempre y cuando haya más elementos en la matriz de historia. Por cada objeto, todos estos objetos se ven así. Para cada objeto de posición dentro de la matriz de historia, tomaremos las coordenadas x e y de un objeto en ese índice. A medida que los ciclos de bucle for sobre la matriz, pasamos sus coordenadas x e y a la línea dos métodos. Entonces punto de inicio de la línea. Después recorremos todas las posiciones dentro la matriz de historia y las conectamos con una línea. Entonces recorremos ese camino para dibujarlo realmente en Canvas. Ahora necesito asegurarme de que se agreguen posiciones a la matriz de historia a medida que la partícula viaja alrededor. Cada vez que actualizamos la posición de las partículas, tomamos esta matriz de historial de puntos y empujamos un objeto como este con estos valores x e y actualizados dentro. Bonito, Parece que es solo una línea recta, pero en realidad es una forma hecha de muchos segmentos de línea más pequeños. Puedo, por ejemplo, hacer que se mueva agregando un valor aleatorio entre -1.5 y más 1.5. Esto debería dejar más claro visualmente que estas líneas están hechas de segmentos. Puedo hacer lo mismo verticalmente. Puedo aumentar el rango aleatorio puede ser de -2.5 a más 2.5. Puedo aumentar aún más el rango. Un valor aleatorio entre -7.5 y más 7.5. Por último, esto empieza a parecer interesante. ¿Correcto? Ahora. Estos son simplemente crecer sin cesar en líneas. ¿Y si quiero definir la longitud máxima de una línea? En este caso, esto significará el número máximo de segmentos. Dentro del método de actualización. Digo que si la longitud de la matriz de historia es mayor que maxlength, llame al método de desplazamiento de matriz incorporado. Así que tenemos dos métodos de matriz aquí. El método Push agrega un nuevo elemento al final de una matriz. El método Shift elimina un elemento desde el principio. Porque estamos agregando nuevos elementos al final de la matriz. El método Shift elimina el segmento más antiguo. Entonces las aerolíneas se arrastran así. Pueden parecer pequeñas criaturas bajo el microscopio. Podría simplemente darles algo de IA y convertir esto en un juego. Puedo aumentar la longitud máxima de la línea a 100s segmentos. O puedo hacer un valor aleatorio 10-110. Ahora, algunos de ellos tienen colas cortas y otras muy largas. 25. Patrones de movimiento con trigonometría: También puedo aplicar trigonometría, que partícula tendrá propiedad angulada que inicialmente comenzará en cero. Por cada fotograma de animación, aumentaré el ángulo en algún valor pequeño. El valor del ángulo está en radianes. Entonces puedo pasar ese ángulo cada vez mayor al signo de Martha, que automáticamente mapeará estos valores a lo largo de una onda sinusoidal. Esto le dará a la coordenada horizontal una emoción de onda irregular. Mira lo que pasa cuando hago esto para la posición vertical también. En lugar de agregar aquí, intento y multiplicar. Lo hago tanto por combinación de seno como de coseno. Mapearemos las posiciones a lo largo del radio de un círculo, multiplicándolo por un valor como este aumentará el radio. Puedes intentar usar diferentes combinaciones de valores y aplicar distintas operaciones si quieres experimentar, hay muchas cosas que se pueden hacer aquí. Básicamente, construimos un sistema de partículas donde cada partícula dibuja una línea detrás de ella. Comento una línea 69 por un tiempo. 26. Creación de un campo de vector: Ahora mi objetivo es hacer que estas líneas viajen alrededor del lienzo siguiendo un orden específico para crear un efecto de campo de flujo. El campo de flujo se basa alrededor de una cuadrícula de ángulos. Cada celda de la cuadrícula almacena y el valor del ángulo. Y cada celda en esta cuadrícula en el campo de flujo tiene una relación con sus celdas vecinas. No son al azar. Aumentan o disminuyen gradualmente. Y a medida que la partícula viaja sobre la cuadrícula, celda por celda, velocidad de partícula y dirección de movimiento se ve influenciada por estos valores de ángulo, creando un patrón de movimiento. Algoritmo muy común para generar valores de ángulo para un campo de flujo es el ruido de Perlin. Crea un ruido de gradiente que cambia gradualmente los valores de manera aleatoria. El efecto resultante se ve muy natural y puede ser utilizado para generar texturas para serina generada por o muchas otras cosas. Hoy generaremos un campo de flujo espiral donde usaremos valores de seno y coseno y los adjuntamos a coordenadas verticales y horizontales de cada punto de cada celda. Esto crea un hermoso patrón repetitivo simétrico. Seremos capaces de acercar y alejar el patrón para resultados muy diferentes y. Vamos a tomarlo paso a paso y quedará claro de lo que estoy hablando a medida que lo construimos. Nuestro objetivo ahora es crear una cuadrícula que divida todo el lienzo en celdas individuales. Digamos que quiero vender el tamaño cada celda para que sea 20 veces 20 pixeles. Esto dividirá el lienzo en filas y columnas. El número de filas y columnas dependerá del ancho y alto de Canvas y de este tamaño de celda. Podría calcular aquí el número de filas y columnas. Pero como quiero que este efecto sea sensible, voy a calcular ese método de init interior. Entonces podemos llamar a ese método init cada vez que ocurre un evento de redimensionamiento para recalcular correctamente toda la cuadrícula de campo de flujo. Este campo de flujo de carga será una matriz que contiene valores de ángulo para celdas individuales en la cuadrícula. El número de filas será la altura del área del lienzo dividida por el tamaño de celda. El número de columnas se dividirá por onda por tamaño de celda. También estableceremos el campo de flujo en una matriz vacía en caso de que se llame a este método init al cambiar el tamaño de Canvas. De esa manera, se eliminarán todos los valores antiguos y podremos recalcular los nuevos valores. Ahora, quiero viajar sobre esa cuadrícula siempre que haya un gran involucrado, la forma más fácil de manejarlo es con dos bucles for anidados, el bucle for externo, el ciclo sobre la cuadrícula, fila por fila desde la fila cero, siempre y cuando haya más filas. El bucle for interno viajará sobre cada fila de izquierda a derecha. Entonces entramos en el bucle exterior, estamos en la fila cero. Entramos en el bucle interno y circulamos por las celdas de esa fila una por una. Llegamos al final, salimos del bucle interno. Entramos en el bucle exterior, Y aumenta, e ingresamos a la siguiente fila. Otra vez. Pasamos en ciclo por todas las posiciones de esa fila una por una. Repetimos este proceso fila por fila hasta cubrir todo el Lienzo. Cada vez que ingresamos a una nueva celda, creamos un valor de ángulo. Aquí podemos hacer diferentes cosas. Simplemente ataré las coordenadas x e y al seno y al coseno y al coseno para crear un patrón en espiral. Sabemos que si pasamos un aumento en el valor del ángulo a seno o coseno, estos métodos mapearán este aumento de valores a lo largo de una onda. En este caso, esos valores crecientes son las posiciones x e y de las celdas en la cuadrícula. Entonces a medida que nos movemos a lo largo de la cuadrícula, creamos espirales y curvas. Cada vez que generamos un nuevo valor de ángulo, lo empujamos a la matriz de campo de flujo. tener en cuenta que estamos ciclando, integramos fila por fila, generando estos valores, pero los estamos almacenando en una matriz como una única secuencia continua de valores. Debemos tener esto en cuenta cuando necesitamos extraer de nuevo estos valores de ángulo, para que coincidan correctamente con posición actual x e y de las partículas. Entonces, en este punto, la matriz de campos de flujo debe llenarse con valores de ángulo. Así que vamos a registrarlo en consola. En realidad estoy en el registro de consola después de cada fila, debería haber puesto el registro de la consola aquí después de que todo esté hecho, pero no importa. Podemos ver que se están generando valores de ángulo. Perfecto. Entonces giramos sobre el lienzo, integramos, y para cada celda en esa cuadrícula, generamos valor de ángulo y comenzamos todos estos valores de ángulo dentro de la matriz de campo de flujo. Debido a que pasamos este aumento gradual en los valores x e y a seno y coseno, creamos un hermoso patrón simétrico. El patrón se revelará cuando dibujemos el campo de flujo. Entonces hagámoslo. Ya tenemos partículas que se mueven sobre Canvas y arrastran líneas detrás de ellas. Actualmente, estamos usando esta lógica para moverlos. Alejemos todo esto y cambiemos completamente este código en el método de actualización aquí quiero que las partículas se muevan y la dirección de su movimiento dependerá de la posición de la partícula medida que viaja sobre diferentes celdas en el campo de flujo. Los valores de ángulo en el campo de flujo cambian celda por celda. Y este ángulo determinará el movimiento de la partícula que actualmente fluye sobre esa celda. Hay muchas formas diferentes de hacer esto. Voy a crear una variable auxiliar temporal x, y será igual a la exposición actual de partículas dividida por tamaño de celda. Básicamente, estoy diciendo cuántas celdas hay en nuestra cuadrícula desde el borde izquierdo de Canvas, esta partícula actualmente está, en qué columna estamos actualmente. Recuerda que el tamaño de celda se fijó en 20. Quiero enteros aquí, así redondearé el valor a la baja. variable y auxiliar será la posición actual de las partículas y dividida por el tamaño de la celda. ¿Cuántas células? Desde arriba estamos en qué fila. Ahora puedo usar estos valores para mapear las coordenadas x e y de una partícula a un índice en la matriz de campos de flujo. Básicamente tengo una partícula con cierta posición x e y en una cuadrícula bidimensional. Y tengo una matriz que representa esa cuadrícula, pero es solo un largo conjunto de números. Entonces, lo que estoy tratando de hacer ahora es mapear esa posición x e y a ese índice para poder extraer el valor de ángulo correcto. La rejilla de nanopartículas actual posición vertical y horizontal. Y sé sobre qué columna y fila en la cuadrícula de campo de flujo se está moviendo actualmente. Ahora necesito usar este valor de columna y fila para obtener el valor de ángulo de la celda de la matriz de campo de flujo. Esto es un poco complicado visualizar si eres principiante, así que no te preocupes demasiado para obtener índice de disposición de matriz llena de fluido, tomo el número de fila que calculamos aquí, y lo multiplico por el número de columnas que calcula este bloque filas, términos, celdas por fila básicamente necesita saber en qué celda estamos actualmente porque agregamos un valor de ángulo por celda en matriz de campo de flujo. Entonces agregamos por muchas celdas que estemos en la fila actual en la cuadrícula así. Esto nos da índice dentro de la matriz de campo de flujo que contiene el valor de ángulo de la celda sobre la que nos estamos moviendo actualmente. Luego establecemos el valor de ángulo de esta partícula al índice dentro de la matriz de campo de flujo que acabamos de calcular. 27. Cómo crear un campo de flujo: Ahora tenemos múltiples opciones diferentes de cómo usarlo para lograr diferentes patrones. Voy a establecer la velocidad x dos coseno del ángulo al principio. Velocidad y será el signo del mismo valor que acabamos de extraer en línea 35. Entonces tomo la posición horizontal tamizada de partículas, y la aumento en ese nuevo valor de velocidad. Y hago lo mismo para la posición vertical, aumentándola por velocidad vertical. Elimino este código. Entonces nos cortamos en una cuadrícula invisible. Cada celda tiene 20 veces 20 píxeles y tiene un valor de ángulo específico. Calculamos qué columna y qué fila de esta cuadrícula se mueve actualmente la partícula. Mapeamos ese valor de columna y fila para indexar en matriz de campo de flujo para extraer valor de ángulo que pertenece a la celda que necesitamos, aumentamos la velocidad x por coseno de esa velocidad de ángulo. ¿Por qué por señal? Esto nos dará una dirección de movimiento dependiendo de ese ángulo. Después aumentamos las partículas en la posición X e Y. Por estas velocidades. Empujamos esta nueva posición de partículas dentro matrices de historia para que podamos animar su cola, la línea que cada partícula droga sola. Si la longitud de la línea es mayor que maxlength, eliminamos el segmento más antiguo. Yo descomentado render para ver qué movimiento obtenemos. No lo parece, pero ya tenemos un campo de flujo de trabajo con patrón de espiral sinusoidal y coseno. Simplemente estamos alejados muy lejos de él. Tendrá más sentido ya que jugamos con el código ahora. Entonces la idea base es que analizando un valor de ángulo cada vez mayor a seno y coseno, haremos que los valores circulen periódicamente entre menos uno y más uno. Utilizamos las posiciones X e Y de cada partícula ya que éstas aumentan en los valores de ángulo. Entonces el patrón estará atado a las coordenadas de esa manera. Cierro esto entre paréntesis y lo multiplico por dos. Esto aumentará el radio de la curva. Elimino el rectángulo. Yo sólo quería líneas. Hago que la longitud máxima de la línea sea un valor aleatorio, 10-210 segmentos. Puedo usar diferentes valores aquí. Aumentemos el número de partículas para que podamos ver mejor el patrón. Mira lo que pasa si poco a poco aumento este valor, 0.5. Puedo ir mucho más alto que esto. Pienso alrededor de las diez. Pongamos este valor en variable, en una propiedad de clase. A esto lo llamo la curva punteada. Te voy a mostrar por qué lo llamo curva en un minuto. Será claro. Yo uso esa propiedad aquí. ¿Bien? También puedo multiplicar x e y por un valor. Si los valores son iguales, obtendremos un zoom simétrico en ese patrón. Aún no es del todo obvio, pero de esto surgirá un patrón claro. Tómate conmigo. Quiero que estos valores sean idénticos para la simetría, y los pondré en una propiedad de clase. A esto lo llamo Zoom. Dije esto el Zoom al punto cero. Para tener en cuenta que curva Zoom también está conectada al tamaño de celda debido a cómo atamos la curva sinusoidal y coseno a una posición en un gran cambio en tamaño de celda afectará el patrón. Afectará al Zoom. Creo que en este punto ya podemos llamarlo campo de flujo. Aumenta lentamente el zoom para mostrarte cómo ese valor afecta el patrón. Puedo entrar realmente en el patrón, acercarme el zoom y despacio, lo alejo. Aún así. No creo que sea obvio cuál es el patrón. Subamos aquí al constructor de clase de partículas. Puedo eliminar estos valores iniciales de velocidad x y velocidad. ¿Por qué? Porque se sobrescriben de inmediato aquí dentro del método de actualización. Quiero que cada línea se mueva a una velocidad diferente. Entonces voy a dar a cada partícula una propiedad modificadora de velocidad, y será un entero aleatorio 1-3. Aquí abajo, multiplico la velocidad x y la velocidad. Por que por ese modificador de velocidad. Ahora algunas líneas se mueven más despacio o más rápido. Aumentemos la velocidad. Modificar organizar. Para mostrarte claramente cómo la curva y el zoom afectan el patrón. Necesitamos líneas para resetear cuando terminen su secuencia de animación. Creo un método al que llamo por ejemplo reset. Cuando el reset dije x e y coordinan a una nueva posición aleatoria en algún lugar alrededor del lienzo. Y también necesito establecer el array histórico a estos nuevos valores como la posición inicial con un índice de cero. este momento, la lista interminable de movimientos más grandes en algún lugar lejos de la pantalla. Voy a crear una propiedad a la que llamo, por ejemplo, temporizador. Será la longitud máxima de la línea por dos. Por cada tick de animación, disminuiré el temporizador en uno. El temporizador comienza como un valor igual a maxlength. Los términos a ello disminuyen en uno por cada fotograma de animación. Siempre y cuando el temporizador sea más o igual a uno, animaremos la línea y haremos gatear como un polvo. Ya. Cuando el temporizador llegue a uno, las líneas se congelarán en su lugar así. En este punto, queremos ejecute una sentencia else que comenzará a eliminar un segmento antiguo de cada línea uno por uno, haciendo que la línea desaparezca del final. Eso lo hago llamando a shift en el array de historia. Esto nos dará un error cuando eliminemos todo del array history, pero aun así intentamos dibujarlo. Por lo que sólo voy a ejecutar esta declaración else. Si la matriz historia contiene más de un elemento, sólo entonces eliminar todos los segmentos de la línea. Las líneas fluyen alrededor. Cuando el temporizador llega a cero, comenzamos a eliminar todos los segmentos hasta que no queden más segmentos. Perfecto. En ese punto, quiero que la línea se reinicie y vuelva a repetir este ciclo de animación. Así que de lo contrario llamar a este método de restablecimiento de puntos que acabamos de definir en la línea 56. Bien, no está funcionando porque también necesito restablecer el temporizador a su valor original. Enhorabuena, construyes un campo de flujo. Esta es una base de código muy sólida y podemos hacer tantas cosas con ella. Por fin es hora de usar correctamente Curve y zoom para mostrarte el patrón del que estaba hablando. 28. experimentos de campo de flujo: Como decíamos, el ruido de Berlín creará un aspecto natural en el patrón de ruido degradado. Estamos calculando valores de ángulo para nuestro campo de flujo en línea 85 usando trigonometría. Entonces, aunque no lo parezca, ahora, este es un patrón matemático muy simétrico que se repite sin cesar en todas las direcciones. Déjame mostrarte a lo que me refiero. Mira lo que pasa cuando aumento el valor de curva. Disfruto mucho viendo este efecto. Hay algo muy relajado y sobre esto, creo que ahora se puede ver un poquito que tenemos un patrón repetitivo. Cambio el zoom y me alejo de él para ver claramente la repetición. También puedo acercarme mucho al patrón y solo miramos la pequeña parte del mismo. Parece que el flujo es en realidad aleatorio, pero sabemos que no lo es. Voy a incrementar el número de partículas. Mi computadora puede manejar esto, pero debes ajustar el número de partículas para asegurarte de que tu computadora pueda animarlo sin problemas para que no tengas que usar 2000 partículas aquí. Pruebe diferentes valores y vea. No recomiendo ir mucho más 2000 a menos que tengas una computadora muy potente. Los campos de flujo son un efecto tan hermoso. Y ahora ya sabes cómo construir uno tú mismo. Aquí solo estamos jugando con el patrón de seno y coseno, pero podemos usar este código para cambiar el flujo y hacer que siga muchos patrones diferentes. Mira lo que pasa cuando cambio la curva de valor. A medida que el valor aumenta, comenzará a emerger un patrón en espiral. Esa rodilla va un poco más alta. Aquí comenzará a curvarse en espiral. Y a medida que aumento el valor, se hace una espiral cada vez más. Creará una especie de caracol en forma de caracol si vamos lo suficientemente altos. Ahora es cada vez más obvio. Y aún más, la curva apenas se enrolla en espiral sobre sí misma. Interesante, ¿no? Entonces ahora creo que es muy obvio cómo afecta la curva a la forma espiral del campo de flujo. Este patrón se repite sin cesar en todas las direcciones y podemos acercarlo y alejarlo cambiando los valores que usamos como este zoom de punto en la línea 75, puedo acercar mucho al patrón. Y a medida que aumento este valor, lentamente estamos alejando el zoom. En este punto podemos ver la naturaleza repetida de este patrón. Como asumimos lo suficientemente lejos. Voy aún más lejos. Puedo hacerla espiral más. Ya ves como el patrón es dentado y no muy liso. Esto es exponer la naturaleza similar a una cuadrícula del campo de flujo ya que el ángulo solo cambia cada 20 píxeles, puedo reducir el tamaño de la celda para hacer que el flujo sea más suave. Y básicamente cortando cannabis en trozos más pequeños, cinco por cinco píxeles. Como ahora podemos colocar más columnas en el área de lienzo disponible, cambio en el tamaño de celda también se alejó muy lejos del patrón. Ahora podemos ver claramente cómo se repite sin cesar. No es aleatorio como el ruido de Perlin. Es muy matemático y simétrico. Acerco un poco más. Creo que está claro cómo funciona esto. Ahora, siéntete libre de jugar con él y hacer tus propios experimentos. 29. Modo de grid y depuración: Ambos nodos son básicamente una cuadrícula de ángulos. Visualicemos esa cuadrícula para dejar claro cómo funciona exactamente. Vamos a crear un modo de depuración en la clase de efecto principal, creo un método al que llamo por ejemplo dibujar una cuadrícula. Esperará contextos como argumento dentro creo un for-loop. Primero, dibujemos líneas verticales, columnas. Esta propiedad de llamadas de punto ya tiene un valor que representa el número de columnas en la cuadrícula. Entonces lo usamos aquí. Cada vez que entramos en una nueva columna, llamamos start path. Quería trazar una línea vertical. Mover al método para definir las coordenadas x e y iniciales de la línea. Cada línea comenzará en posición horizontal dinámica, tamaño de celda, el ancho de una sola celda multiplicado por el número de la columna en la que nos encontramos actualmente. Todas las líneas verticales comenzarán en la parte superior desde la coordenada y cero. línea dos determinará las coordenadas x e y finales de nuestras líneas de cuadrícula. posición horizontal volverá a ser tamaño de celda multiplicado por el número de columna. Y quiero que las líneas terminen todo el camino en la parte inferior del área del lienzo. Entonces esta altura de punto. Después acariciamos líneas. Veamos lo que tenemos hasta ahora por Colin dibujar método grid desde dentro del método render. Bonito. Vemos líneas verticales que representan columnas en nuestro campo de flujo. El tamaño de celda es de solo cinco, así vemos línea cada cinco píxeles, cambio a un 30. Como puede ver, esto también afectó el zoom en el patrón. A medida que aumenta el tamaño de las celdas, podemos caber menos celdas por fila, lo que significa que las espirales creadas por seno y coseno en línea 85 tienen menos tiempo para desarrollarse. Todo es porque ajustamos el valor del ángulo, pasamos al seno y al coseno a los números de columna y fila, menos columnas, menor rango de valores pasados como ángulo a seno y coseno en línea 85, lo que afecta al patrón. Siempre puedo compensarlo ajustando esta propiedad de zoom en la línea 75. Bien, estamos dibujando líneas verticales. Dibujemos también líneas horizontales, las filas, para completar nuestra cuadrícula. Nuevamente, comenzamos por comenzar camino comenzando las coordenadas x e y de cada línea horizontal serán cero horizontalmente. Entonces desde el borde izquierdo de Canvas y verticalmente será el tamaño de celda multiplicado por el número de fila. El punto final de cada línea será el borde derecho de Canvas. Por lo que este ancho de punto horizontal, punto final vertical será de nuevo tamaño de celda veces el número de fila. Yo acaricio las líneas. Perfecto. Ahora podemos ver la grilla completa. Mira de cerca las líneas. ¿Ves cómo el valor del ángulo, la dirección de la línea cambia en los puntos a medida que las líneas ingresan nuevas celdas en la cuadrícula Cada celda en el campo de flujo tiene asignado un valor de ángulo diferente, y las líneas siguen esos ángulos para darles dirección de movimiento. Este visual debería ayudarte a entender cómo funcionan más bien los campos de flujo. Y si estás codificando, puedes inspeccionarlo de cerca en tu computadora y ver realmente lo que está sucediendo. Cambiar el valor del tamaño de celda, dos, número aún mayor, y el misterio de hacer campos de flujo debe ser resuelto. Quería que las líneas de la rejilla fueran más delgadas, pero no quiero que este cambio afecte el ancho de línea de las líneas que fluyen. Por esa razón, envolveré todo este bloque de código entre safe y restore. Estos dos métodos de Canvas incorporados, asegúrese de que cualquier cambio que hagamos a un estado se mantendrá limitado a un área específica. Esos cambios pueden incluir cualquier tipo de configuración como FillStyle, estilo de trazo, ancho de línea, opacidad, alfa global, así como cosas como rotación y escalado, que no estamos usando hoy en día. Si querías saber cómo usar rotar y escalar, puedes consultar mi clase sobre fructosa. Si configuro el estilo de trazo para escribir, solo afectará el grado, no las líneas que fluyen, no el sistema de partículas. El método Save crea un punto seguro, como en un videojuego, podemos hacer los cambios que queramos aquí, por ejemplo, ancho de línea, solo 0.3 píxeles. Estos cambios afectarán este código de dibujo y luego restaurarán. Reiniciaremos todos los cambios realizados aquí hasta el punto en que fue cuando lo llamamos seguro. Debido a eso, cuando luego dibujamos las líneas fluidas, el sistema de partículas usando método de dibujo en la clase de partícula, no se verán afectadas por este estilo de trazo y este ancho de línea en absoluto. Quería mantener la grilla en nuestro proyecto, pero quiero una forma para que el usuario pueda ocultarla y mostrarla fácilmente. Creo una propiedad de modo de depuración llamada este punto d back se establecerá en true inicialmente, igual que lo hicimos con Colin en ella aquí. Cuando se instancie la clase de efecto, se ejecutará todo el código dentro del constructor. De hecho, puedo poner cualquier código que quiera aquí, incluso un oyente de eventos, cuando creamos una instancia de clase de efecto usando la nueva palabra clave, en ese punto, quiero se aplique un oyente de eventos para el evento key down. Necesito asegurarme de que todavía tengo acceso a las propiedades en el constructor de clases, específicamente esta propiedad de depuración desde el interior de este oyente de eventos. Si usas una función de devolución de llamada regular, tendrás que vincularla. Alternativamente, puedo usar la función de flecha ES6. Estas funciones heredan automáticamente el ensartado de su ámbito padre. Entonces, incluso cuando este oyente de eventos se ejecute más tarde, aún podrá recordar que originalmente se definió aquí, y podrá controlar esta propiedad de depuración de puntos para nosotros. Si usa la función de devolución de llamada regular aquí, obtendrá un error porque esta palabra clave se volverá indefinida. Cuando ocurre el evento key down, consola registramos este objeto de evento generado automáticamente. Decidí llamarlo por una variable nombre E, pero puedes llamarlo como quieras. Si abro este objeto de evento aquí abajo, puedo ver que contiene la propiedad key que nos dice qué tecla se presionó. Eso es exactamente lo que necesito. Si la clave de punto E es triple, igual al operador de comparación a D, establezca esto en valor de depuración en su opuesto. Si actualmente es falso, póngalo en true. Si actualmente es cierto, póngalo en falso. Esta es una línea de código muy útil que nos permite alternar entre verdadero y falso fácilmente. Solo quiero que este código se ejecute si el modo de depuración es verdadero, solo quería ver este campo de flujo degradarse cuando el modo de depuración está activo. Ahora, si haces clic en Canvas y presionas la letra D en tu teclado una y otra vez, estás habilitando y desactivando el modo de depuración. Volveremos a usar este modo de depuración en la clase avanzada donde te muestro cómo trazar formas e imágenes de letras. Ahora que las celdas individuales en el campo de flujo son relativamente grandes, podemos ver claramente que las líneas se rompen y cambian de dirección en los límites de cada celda. Porque cada celda contiene un valor de ángulo diferente, influyendo en el movimiento de estas líneas. Siéntete libre de jugar con el código, dale diferente valor al tamaño de celda en línea 70. Y luego puedes ajustar para ese cambio ajustando este Zoom en línea 75, puedes llegar a algunas combinaciones interesantes. Como aquí donde tengo un patrón bastante interesante que se ve claramente afectado por el hecho de que las celdas individuales en el campo de flujo son 50 veces 50 píxeles. Poco a poco aumentaré la curva, la espiral interna de nuestro campo de flujo de seno coseno. Belleza de las matemáticas. ¿Sabías que podrías hacer arte con las matemáticas así? 30. Colores aleatorios: Abro otra ventana del navegador y voy a Google Color Picker. Estoy buscando algo como esto donde pueda hacer click quiera y me va a dar ese valor de color. Puedes entrar en cualquier gama de colores que quieras. Tomo este color copiando su valor hexadecimal. Lo asigno como esta propiedad de color de punto en la clase de partículas. Dentro del método de dibujo en clase de partículas, dije estilo de trazo a este color de punto. Si todo el campo de flujo era un solo color como este, no hay un estilo de trazo de Colin de punto una y otra vez. Yo lo declararía en alguna parte, así que solo se ejecuta una vez en la primera página de carga para mejorar el rendimiento. Pero aquí estoy tratando de darle a nuestras partículas una gama de colores aleatorios. Yo creo una matriz, a esto lo llamo colores de punto. Pongo este valor dentro así. Vuelvo a mi recogedor de color. Empecé de un color oscuro, así que voy un poco más claro en esta dirección, por ejemplo y de nuevo, copio este valor hexadecimal. También puse ese color similar pero más claro en la matriz. Este color de punto será un color elegido aleatoriamente de esta matriz de colores de puntos. Puedo acceder a ellos a través de sus índices. Este índice de color de punto cero es este. Este índice de color de nodo uno es este. Tomemos otro color y lo agreguemos a la matriz. Elijo un color más, entro aún más claro. Yo elijo uno más. Esta vez, va a ser muy ligero. Puedes elegir tantos colores como quieras. No importa cuántos colores agregues a esta matriz. Quiero que a cada partícula se le asigne aleatoriamente un índice de esta matriz. ¿Cómo hago eso? Por supuesto, mediante el uso de Math.random entre cero y la longitud de esta matriz de colores de punto. Sin embargo, Math.random, nos da unos valores de punto flotante. No hay índice 1.5 en esta matriz, así que necesito enteros. Envuelvo todo esto en Math.floor. Y así es como puedes asignar aleatoriamente un valor de una matriz de valores disponibles a cada objeto creado por una clase. Se puede ver que cada línea tiene asignado un valor aleatorio, y nuestro efecto se ve más interesante. Siéntase libre de volver al seleccionador de color y elegir su propia gama de colores. Probablemente sería interesante crear deslizadores para este zoom de puntos para que los usuarios puedan controlarlo fácilmente. Puedes hacerlo como un reto al final si quieres. 31. Diseño adaptable: Si cambio el tamaño de la ventana del navegador, como con cada proyecto de Canvas, el elemento canvas no cambiará el tamaño automáticamente. De la misma manera estamos aplicando EventListener para el evento keydown aquí en el constructor de clases de efectos secundarios. También puedo crear resize windows event listener. Estamos dentro de una clase, así que no quiero estar tirando ancho y alto desde el exterior. Así que vamos a registrar en la consola este objeto de evento generado automáticamente. Elimino este registro de consola. Y también me quito esta. Así que somos objeto de evento de inicio de sesión de consola que se generó automáticamente cuando cambiamos el tamaño de la ventana del navegador y activamos resize event listener. En el interior puedo ver el objetivo del evento, en este caso el objeto de ventana del navegador. Y dentro de eso, podemos ver lo nuevo actualizado en tu altura y ancho. Entonces solo usaremos estos valores. Consola log e punto objetivo punto ancho interior, y E punto objetivo punto altura interior. Ahora puedo cambiar el tamaño de la ventana del navegador y puedo ver el nuevo ancho y alto. Perfecto. Entonces, cuando cambiamos el tamaño, quería establecer ancho y alto del efecto a estos valores. El problema es que también necesitamos cambiar el tamaño del elemento canvas en sí. Y nuevamente tendría que llegar fuera de mi clase para agarrarlo. Quería mantener mis clases modulares. Necesito una referencia al elemento canvas dentro de mi clase, refactorial este efecto de código solo esperaré Canvas como argumento dentro, lo convertimos a una propiedad de clase. Y de este lienzo de puntos, ahora podemos tomar ancho y alto así. Tengo 69 años, ahora nos da acceso al propio elemento canvas. Cierro la consola. Necesito tomar esta variable canvas de la línea uno, y necesito pasarla para afectar al constructor de clase en el punto en que creamos una instancia de affect class usando la nueva palabra clave aquí en la línea 135. En el interior, se convierte a esta propiedad dot Canvas. Y de su anchura y altura se extrae. Entonces ahora cuando se dispara el evento de redimensionamiento, llamaré a este método de redimensionamiento de puntos, que vamos a escribir. Siguiente. Le paso el nuevo ancho y alto del redimensionar la ventana del navegador. Obtenemos estos valores de este objeto de evento autogenerado. Voy a escribir este método aquí abajo. Dentro de la clase de efectos. Sabemos que espera el nuevo ancho y alto redimensionados como argumentos. Tenemos una referencia al elemento lienzo real aquí en la línea 69. Entonces lo tomo, y también tomo ancho y alto. Copio estas tres líneas y las pego aquí abajo. Cuando cambiamos el tamaño de la ventana del navegador, obtenemos un nuevo ancho y alto. Establecimos el ancho del elemento de lienzo al nuevo ancho. Dijimos altura del elemento de lona a la nueva altura. Luego establecemos las propiedades width y height del efecto a estos nuevos valores actualizados. Si cambio el tamaño de la ventana del navegador, se ve interesante, pero no estoy seguro si no estamos desperdiciando memoria así. Si vuelvo a un tamaño más pequeño, las líneas eventualmente deberían volver al área disponible más pequeña. Y luego cuando obtengan más espacio, el patrón debería expandirse al espacio más grande. De nuevo, creo que la forma que prefiero hacer esto es llamar al método init. Nuevamente, después de cambiar el tamaño de la ventana. No hagas lo que estoy haciendo ahora. No ejecutes este código porque si llamo a this.in desde el método de resize y redimensiono la ventana del navegador. Algo muy malo pasa. Estamos empujando cada vez más partículas en esta matriz de partículas de puntos, y el efecto se ralentiza considerablemente. Si subo al método init, puedes ver que cada vez que se ejecuta el método init, eliminamos la matriz de campo de flujo y rellenamos con nueva cuadrícula de ángulos. Necesito hacer lo mismo con las partículas. Ponemos estas partículas de punto en una matriz vacía, eliminamos un viejo objeto de partícula dentro, y creamos un nuevo conjunto de partículas. En cuanto al rendimiento, esta no es la mejor solución. No necesitamos partículas nuevas. Podría haber creado un método de reinicio en cada partícula. Y podría haber restablecido aquí las posiciones de las partículas en lugar de eliminarlas todas y crear otras nuevas para reemplazarlas. También podríamos usar la técnica de pooling de objetos aquí si necesitamos aumentar y disminuir el número de partículas dependiendo del tamaño del lienzo que estoy haciendo ahora funciona porque estoy llamando a este método punto init desde dentro resize en la línea 126. Cuando cambiamos el tamaño, eliminamos el campo de flujo antiguo, degradamos y lo reemplazamos con un nuevo conjunto de ángulos ahora ajustados al nuevo ancho y alto del lienzo. Y también eliminamos todas las partículas. Y creamos un nuevo conjunto con posiciones aleatorias repartidas sobre la nueva área de lienzo disponible. Por supuesto, para que esto funcione, necesitamos asegurarnos de que llamamos a this.in it desde el método de resize aquí, supongo que la mayoría de los usuarios no serán redimensionados y la página una y otra vez. Entonces la solución está perfectamente bien. 32. Experimentación con patrones de campo de flujo: La forma del campo de flujo es lo que llamo Seno y Coseno de patrón de curva espiral, un poco de trabalenguas para personas con un fondo de lenguaje suave. No estoy seguro si esta forma tiene nombre oficial. Si lo hace, hágamelo saber, por favor. Es el patrón que obtienes cuando usas aumento de posiciones en una cuadrícula bidimensional como valores de ángulo pasados a seno y coseno. Vemos la fórmula aquí. Esta línea de código que determina la forma del patrón. Podemos jugar con él de muchas maneras diferentes y obtener resultados muy diferentes. Mira lo que pasa si sustituyo la multiplicación por la suma aquí. ¿O qué pasa si hago eso aquí? ¿O intento esto? Yo ajusto el zoom. Interesante. También puedo ajustar la curva. Puedes simplemente cambiar aleatoriamente los operadores aquí y tal vez te encuentres con algo interesante que no he probado. Nuevamente, así es como puedo alejar lentamente el patrón. Puedo aumentar la curva. Y debido a los cambios al operador que hicimos al calcular una cuadrícula angular ahora cambia la dirección de todo el patrón. Esto se ve bien. Tal vez podría usar este efecto para el fondo espacial en la próxima clase de desarrollo de juegos. Incluso podría hacer que esto reaccionara a algunos objetos. Aprenderemos más sobre eso en la siguiente parte, donde te muestro cómo hacer que las líneas fluyan alrededor del texto. Sorprendentemente, hacer menos iguales aquí también cambiará el patrón. Se hará más evidente cuando me aleje. Creo que esto se debe a que cambiamos en cuyo punto las celdas de la cuadrícula se rompen a una nueva fila. Si vuelvo a la multiplicación aquí estamos de vuelta al patrón espiral habitual. Ahora sólo estoy jugando con él. Intento cambiar en Zoom. Cambio de curva. También puedo hacer ambas firmas aquí. O puedo intercambiar seno y coseno. Creo que está claro cómo funciona esto. Ahora, siéntete libre de jugar con él y hacer tus propios experimentos. 33. Dibujo de texto: Aquí abajo en el cristal de efecto principal, tenemos el método init. Se divide en una cuadrícula y crea valores de ángulo usando esta fórmula trigonométrica. Todavía quería dividirme primero en grilla. Entonces en lugar de este algoritmo, quiero dibujar texto en Canvas y calcular los valores de ángulo de la cuadrícula de campo vectorial a partir de ahí. Dibujemos ese texto primero. Para mayor claridad, pondré ese código en un método separado. Yo lo llamaré dibujar texto. Voy a necesitar acceso al objeto de contexto CTX desde aquí para que pueda sentar las propiedades de Canvas desde aquí. Al principio, simplemente sacaré variable CTX directamente de la línea dos. Refaccionaremos esto en un minuto. A partir de ahí, accedo a la propiedad de fuente y la configuro a 500 píxeles de impacto. Quiero letras grandes en negrita. Entonces llamo al método filtText incorporado, que espera al menos tres argumentos, el texto a dibujar y coordenadas x e y donde dibujarlo. El texto que quiero dibujar es el JS, porque hoy estamos aprendiendo sobre JavaScript. Coordenada horizontal será este ancho de punto, el ancho de Lona veces 0.5. El centro del lienzo horizontalmente, coordenada vertical y será esta altura de punto veces 0.5, la mitad del lienzo verticalmente. Como pueden ver, estoy tirando de la variable CTX de línea a directamente dentro de mi clase. Quiero seguir buenas prácticas y mantener nuestras clases autónomas. Entonces voy a refaccionarlo. Voy a necesitar acceso a CTX desde el método Draw text así como desde el método init porque ahí es donde se llamará al método de texto dibujado. También necesito acceder a ese mismo contexto desde dibujar un método de cuadrícula. Dado que necesitamos CTX en tantos lugares diferentes en toda la clase de efectos, elegiré esta siguiente solución. Tenemos ctx aquí en la línea dos. Me aseguraré de afectar al constructor de clase esperado como argumento. Y dentro lo convertiré una propiedad de clase llamada este contexto de punto. Así. Usaremos este contexto de punto aquí y aquí dentro del método draw text. Dentro de la tasa de drogas también, ya no se esperará como argumento proveniente del exterior. En cambio, en todos estos lugares, usaré esta propiedad de clase de contexto de punto que acabamos de crear. También usamos contexto dentro del render. Ya no esperará el contexto como argumento. También voy a eliminar contextos argumento pasado para dibujar método en partículas y aquí pasado para dibujar una cuadrícula. Creo que aquí cometí algunos errores. Tened un segundo conmigo, por favor. De hecho tengo que pasar este contexto de ley para dibujar método sobre partículas como esta. Bien, ejecuto el código, me sale un error. Abro el constructor de clase de efecto de consola del navegador expect CTX y lo convierte en esta propiedad de contextos de punto. Necesito asegurarme de pasarlo CTX aquí abajo en la línea ciento 51 cuando creo una instancia de esa clase, además, ya no necesito pasar CTX para renderizar método. Aquí. Tomo el método draw text y lo llamo desde dentro del render así. Cuando pasamos las coordenadas x e y al método filtText, estas coordenadas establecen el punto de anclaje de ese texto donde se dibuja el texto en relación con ese punto de anclaje depende del valor de los textos, la línea y las propiedades del lienzo de línea base del texto. La alineación de texto maneja la alineación horizontal. Ponemos el punto de anclaje del texto a la mitad del cannabis. Así que mira lo que sucede cuando pongo la línea de texto al centro. También puedo usar la propiedad de línea base de texto para alinear el texto verticalmente en relación con esas coordenadas de punto de anclaje. Lo puse en medio. Una vez más. Cuando dibujas texto sobre cannabis, los valores que pasas a coordenadas filtText x e y definieron el punto de anclaje donde se asienta el texto en relación con ese punto de anclaje depende qué valores le des a las propiedades de texto, línea y línea base de texto. Por defecto, el texto se alinea a la izquierda horizontalmente y la línea base alfabética verticalmente. Los colocamos a centro, medio para obtener texto centrado así. Esto es muy importante de entender si alguna vez necesitas trabajar con texto en lienzo HTML, estableceré el debug en true para habilitar el modo de depuración, quiero que este texto sea visible cuando esté en modo de depuración. Oh, tengo un error. La consola me está diciendo que está aquí. Necesito usar este contexto de punto aquí también para dibujar mi cuadrícula. Probablemente ya lo noté antes. Entonces cuando estamos en modo de depuración, quiero ver degradar el campo vectorial. Y quiero que veas estas grandes letras blancas que determinarán la forma del campo de flujo. Al poder mostrar y ocultar este texto fácilmente presionando la letra D en el teclado, al ingresar al modo de depuración hará que el efecto sea más fácil de entender y modificar. Render interior. Digo si esto es el debug es verdadero, solo entonces dibuja una cuadrícula y dibuja texto. Ahora, puede presionar la letra D una y otra vez para activar y desactivar el modo de depuración. 34. Qué son los datos de píxeles: Dentro del método init, quiero dibujar a x en este punto. Recuerda que el método init se ejecutará una sola vez en la primera carga de la página y creará un campo vectorial y un sistema de partículas para nosotros. Después de dibujar estas grandes letras blancas sobre Lienzo, quiero que escaneen Canvas en busca de datos de píxeles. Mi objetivo final es saber qué celdas de la cuadrícula son formas de letras vencidas y qué celdas de cuadrícula contienen solo el fondo vacío negro. Lo hago escaneando cannabis en busca datos de píxeles después de dibujar ese texto en él. Y analizaré esos datos de píxeles y los mapearé en la cuadrícula. Voy a llamar incorporado get imageData método. Este método devuelve un objeto de datos de imagen generado automáticamente que representa los datos de píxeles subyacentes para una porción específica de cannabis. Se esperan cuatro argumentos para especificar qué porción de cannabis queremos analizar. Quiero pixel de datos de todo el elemento canvas. Entonces, desde la coordenada cero-cero hasta este ancho de punto, esta altura de punto. En otras palabras, obtener ImageData. Escanearé una porción específica de cannabis en busca de datos de píxeles, podemos extraer colores y coordenadas de cada píxel de ella. Hacer eso, necesito entender cómo se organizan los datos en este objeto de datos de imagen autogenerado? Asignaré esto a una variable constante que llamo por ejemplo píxeles, y nuestra consola la registrará. Puedo ver el objeto de datos de imagen aquí en la consola. Lo abro y puedo ver que tiene ancho y alto del área escaneada. Esto es importante. Necesitamos conocer estos valores para que podamos extraer las coordenadas x e y de cada píxel de este. Si conocemos el ancho, cuántos píxeles tenemos, muy fila de datos, sabemos después de cuántos píxeles esta matriz rompe a otra línea. Se escanea el lienzo. Y en el mismo orden creamos nuestra cuadrícula angular fila por fila de arriba a abajo, yendo de izquierda a derecha en cada fila. Si abro esta matriz de datos, aquí es donde se almacena toda la información de píxeles. En realidad es muy sencillo. Simplemente tiene una larga secuencia de enteros. consola de mi navegador divide esta matriz extremadamente larga en bloques, pero en realidad es una larga línea de números. ¿Cómo se traduce eso en píxeles? Puedo ver que este es un tipo especial de matriz llamada UI y T8 clamped array. Solo puede contener enteros de ocho bits sin signo sujetos para organizar 0-255. Sabemos por la declaración de color RGBA en CSS que cada color puede ser representado por una combinación de rojo, verde y azul. Cada color tiene un valor 0-255. Y diferentes combinaciones de estas nos permiten crear cualquier color en CSS RGBA declaración de color. El valor de opacidad Alfa es 0-1. Aquí en esta matriz de píxeles, alfa también se representa por un valor 0-255. Debemos recordar que la matriz de datos de píxeles es una línea extremadamente larga de números donde cada cuatro valores representan rojo, verde, azul y Alfa sobre un píxel, un solo píxel. Entonces este es el píxel uno. Los siguientes cuatro valores, nuestro píxel dos, y así sucesivamente. Puedo ver que el ancho del área escaneada es 528 píxeles y la altura es de 464 píxeles. 528 veces 464 es 244,992 pixeles totales escaneados. Y sabemos que cada uno de estos píxeles está representado por cuatro valores en píxeles. Matriz. Valor para rojo, verde, azul y Alfa. 244,992 veces cuatro es 979,968. Aquí podemos ver que la matriz de datos de píxeles tiene exactamente 979.968 elementos. Así que eso echa un vistazo. Si miro en algún lugar en el medio de la matriz, debería poder encontrar estos píxeles blancos que componen las formas de las letras. Aquí puedo ver que tenemos de 55 a 55 a 55, que es blanco, y 2554 alfa totalmente visible. Sabemos que estos cuatro píxeles con índice 533,600 en matriz de datos de píxeles representan píxeles en algún lugar de esta área blanca. Si también cambio el estilo de relleno, ¿verdad? Abrí la matriz. En su mayoría veo píxeles negros son ceros, ceros 00 opacidad porque el fondo de nuestro lienzo es transparente. Aquí puedo ver esos píxeles rojos a 55 leer cero, verde, cero azul a 55 Alfa. Estos valores representan un píxel rojo completamente visible, en algún lugar del área roja, sabemos que estos píxeles son el texto dibujado en Lienzo. 35. Manejo de datos de píxeles: Bien, entonces el método init ejecutará todos los que están en la primera carga de página y en su interior estamos tratando de crear una cuadrícula de ángulos, un campo vectorial. Dibujamos texto y nos escaneamos con ese texto dibujado en él con el método get ImageData incorporado. Ahora, estamos manteniendo todos los valores de píxel dentro de esta variable de píxeles. Voy a comentar este código que calcula los ángulos espirales para cada celda de la cuadrícula usando nuestra fórmula especial de seno y coseno. En cambio, haré la forma del texto de las letras para determinar los ángulos retenidos en cada celda del campo vectorial. Para ello, necesitamos usar bucles anidados for. Nuevamente, el bucle for exterior recorrerá Canvas fila por fila, saltando por tamaño de celda. Cada vez que ingresamos a una nueva fila, establecemos el tamaño de celda en 20 píxeles. Aquí en la línea 75, puedo mostrar y ocultar esta cuadrícula hecha de 20 veces 20 celdas presionando la letra D en mi teclado. el interior, el bucle for interno recorrerá cada fila horizontalmente de izquierda a derecha. También saltando de celda a celda por valor de tamaño de celda. Ojalá ahora entendamos cómo estos dos anidados para ciclo ciclo sobre el lienzo fila por fila de arriba a abajo. Cada vez que ingresamos a una nueva celda en la cuadrícula, necesitamos calcular un índice. Ya calculamos el índice aquí arriba en la línea 40. Esta fórmula nos ayuda a convertir las coordenadas x e y en un solo valor que representa el índice en una matriz. A medida que recorremos la cuadrícula celda por celda, fila por fila, quiero hacer coincidir esa posición de celda con un índice correspondiente a estas coordenadas en matriz de píxeles para que sepa qué datos de píxeles se escanearon para esta celda en particular. Una coincidencia en las coordenadas x e y de la celda. Actualmente estoy recorriendo con estos bucles anidados for a un índice específico en matriz de píxeles para extraer datos de píxeles para esta área de lienzo. Nuevamente, esta es esa fórmula donde multiplicamos el número de fila por el ancho. Entonces obtenemos píxeles por fila más x, lo que representa sin embargo muchos píxeles estamos actualmente en nueva fila. Esta vez, estamos tratando de hacer coincidir el índice en matriz de datos de píxeles. Sabemos que cada partícula está representada por cuatro elementos, cuatro enteros, 0-255, representados en rojo, verde, azul y Alfa. Entonces, para obtener ese índice correcto, multiplica esto por cuatro. Ahora conozco el índice en matriz de píxeles que corresponde a las coordenadas x e y de esta celda en particular en el campo vectorial, el grado. Quiero el color con el que empiezo, ¿no? El rojo será matriz de píxeles en ese índice. Verde será el único índice que viene después. Entonces índice de píxeles más uno. El azul es índice más dos. Entonces tenemos Alfa, índice más tres. Entonces obtenemos el valor rojo del siguiente píxel, verde, azul, alfa, y así sucesivamente y así sucesivamente. Entonces tenemos rojo, verde y azul de cada píxel. La combinación de estos valores nos dará el color del píxel subyacente. Ahora mismo, todos los píxeles de texto son rojos, pero eso lo cambiaremos pronto. 36. Conversión de colores en ángulos: Mi objetivo ahora es hacer que el color de las letras afecte la dirección del flujo, el ángulo en la cuadrícula del campo vectorial, por ejemplo, los píxeles rojos empujan el flujo hacia la derecha. color azul fluye hacia abajo, color verde fluye hacia la izquierda, por ejemplo, y todos los valores de color intermedios nos dan un ángulo en algún lugar entre estas direcciones. Hay muchas maneras en las que puedo convertir colores en ángulos, y podemos lograr muchos efectos diferentes aquí. La forma más fácil sería convertir de alguna manera los tres valores de rojo, verde y azul en un solo número. Puedo, por ejemplo generar un valor en escala de grises a partir de este RGB, los colores se calibran manera que cuando los tres colores para rojo, verde y azul son iguales, el color resultante es un tono de gris. El color está en algún lugar del espectro de la escala de grises sin un sesgo hacia la vista roja, verde o azul. Podemos convertir a escala de grises obteniendo el promedio de los tres, rojo más verde más azul dividido por tres. Ahora, podría crear un efecto de escala de grises a partir de esto tomando ese valor promedio y aplicándolo nuevo al rojo, verde y azul. Pero en realidad solo quería tomar ese único valor promedio y quiero convertirlo a un valor de ángulo. Tenemos una gama de colores en escala de grises que va 0-255. Y quiero mapear estos valores dos ángulos, 0-6, 0.28 rad, 6.28 rad convertir a 360 grados, un círculo completo. Por lo que los colores pueden fluir en cualquier dirección dependiendo del valor de la escala de grises de esa área, ya que sólo estamos operando en valores positivos. Entonces la fórmula es muy sencilla. Toma la relación entre la escala de grises actual de esta celda en el campo vectorial y el valor máximo. Y aplicar esa relación a ese valor de ángulo. Digamos que si la escala de grises es 127.5, eso es a mitad de 50 por ciento entre el valor mínimo de cero y el valor máximo de 250. 527 punto 5/255 es 0.5. Tenemos la relación, y ahora la multiplico por el rango angular máximo de 6.28 rad, lo que nos dará la mitad de ese valor, 3.14. 3.14 es pi semicírculo. Por cierto, si la escala de grises es por ejemplo 63.75, 63.75 dividido por el valor máximo 255 nos da una relación de 0.25, 25 por ciento hacia el valor máximo, un cuarto. Aplicamos la misma relación al valor de ángulo máximo 0.25 veces 6.28 nos da 1.57 rad medio círculo por cuarto. Básicamente estoy tomando la relación, relación entre el valor actual en escala de grises y el valor máximo de color posible de 255. Y estoy aplicando esa relación al rango de ángulo 0-6, 0.28 rad. Debido a que usamos la escala de grises así, el flujo resultante estará influenciado por cuán claros u oscuros son los colores en el espectro de escala de grises. Te voy a mostrar a lo que me refiero cuando pongamos en marcha la animación. Quiero limitar la cantidad de decimales que obtenemos aquí ya que no hay necesidad de calcular valores de ángulo minúsculos. Dos decimales están bien. Puse toda la expresión entre paréntesis, así puedo llamar a JavaScript incorporado al método fijo en él. Se lo paso a, quiero sólo dos decimales. Bien, entonces a medida que se ejecuta el método init, establecemos el campo de flujo en una matriz vacía. Aquí abajo, llenaré la matriz con una cuadrícula de valores de ángulo método de empuje de matriz incorporado. Y vamos a empujar un objeto con la propiedad x establecida en la coordenada x, coordenada horizontal desde el bucle for interno a medida que saltamos por tamaño de celda dentro de cada fila celda compra-venta, y será el índice y desde el bucle for exterior a medida que saltamos por valor de tamaño de celda sobre cannabis fila por fila de arriba a abajo. El valor del ángulo de color es esta gama de colores en escala de grises convertida en un valor de ángulo en radianes, lo que asegurará que las partículas fluyan en una dirección diferente sobre diferentes colores. En consola, podemos ver ese objeto de datos de imagen. De hecho, no quiero que apunte a todo el objeto, sino solo a la matriz de píxeles, que se mantiene aquí dentro de la propiedad data. píxeles serán objeto ImageData devuelto por obtener ImageData método incorporado datos de punto. Estamos apuntando directamente a esta matriz ahora. Ahora lo vemos en la consola aquí. matriz de campos de flujo ahora contiene objetos con propiedades de ángulo x, y y de color para cada celda de la cuadrícula de campo vectorial. Tenemos que asegurarnos de tener en cuenta este cambio cuando la actualización las posiciones de las partículas aparecen dentro del método de actualización en la clase de partículas. Aquí estamos tirando del valor del ángulo de la matriz de campo de flujo dependiente de la corriente de partículas X e Y posición en Canvas. Ahora, hay un objeto con tres propiedades en cada índice, así que necesito acceder a su propiedad angulada de color aquí. Así, bonito, algo está pasando. Tenemos dos problemas que resolver. Solo quiero ejecutar este bloque de código que coincida con la posición de la partícula con un objeto que representa una celda en el campo de flujo. Si hay un objeto en ese índice en el Dan tiró del ángulo de color, eso solucionará el problema donde las partículas se mueven fuera de los límites de Canvas entre recites. El segundo número, si estás codificando a lo largo, puedes alejar el zoom y puedes ver que ya estamos dibujando en un campo de flujo con forma de letras JS, pero por alguna razón está sesgado a la derecha. ¿Por qué es eso? Voy a hacer la fuente más pequeña para que podamos ver que tenemos la forma, pero ¿por qué está distorsionada así? Estoy haciendo la celda más pequeña. Ahora podemos ver claramente el campo de flujo tiene forma de letras JS, pero está sesgado de una manera extraña. De hecho, me tomó unos minutos darme cuenta de lo que está pasando, pero avancemos rápidamente a la solución. Si sabes por qué está haciendo eso antes de que lo revele, pausa el video y escríbalo en los comentarios. Ahora mismo, ves aquí arriba estamos configurando ancho y alto del lienzo al ancho y alto actuales de la ventana del navegador. El problema es que cuando creamos el campo de flujo, si el valor del tamaño de celda en la clase de efecto principal, el ancho y alto de cada celda en la cuadrícula no es un número por el que el ancho del lienzo se pueda dividir. Sin ningún resto, obtendremos algunos píxeles sobrantes cuando rompamos línea a medida que escaneamos Canvas fila por fila de arriba a abajo. A medida que bajamos fila por fila, esos píxeles sobrantes al final de cada fila se acumulan hasta que el campo de flujo se degrada. Y el campo de flujo se degrada. El número de elementos allí no coincide exactamente con el número de celdas que podemos caber en Canvas. Entonces las filas se empujan cada vez más hacia la derecha. Hay múltiples formas de resolver esto. Solo tenemos que asegurarnos de que el ancho del lienzo sea divisible por tamaño de celda sin ningún resto, sin ningún valor sobrante. Lo solucionaré estableciendo el ancho del lienzo a un tamaño específico. Pero también puedes usar una fórmula dinámica aquí usando el operador resto. Si querías mantenerlo a pantalla completa, si quieres mantener la funcionalidad responsive. Dije ancho de lienzo a 600 píxeles. Y debido a que el tamaño de celda en la línea 75 se establece en 20 píxeles, 600 es divisible por 20 sin ningún resto, lo que estamos obteniendo la forma correcta. También estableceré la altura del lienzo en 600 píxeles, o tal vez 500 veces 500. Cuando cambio el tamaño de Canvas, nuestro método de cambio de tamaño del cliente se activa y vuelve a romper la forma porque permite que el ancho del lienzo sea algo que no es directamente divisible por el tamaño de celda sin un resto, directamente divisible por el tamaño de celda sin un resto, puedo asegurarme de que solo investigue poco el tamaño si el nuevo ancho es divisible por tamaño de celda. O simplemente puedo comentarlo por ahora, aquí abajo en línea y 92. Y debido a que Canvas es 500 veces 500 píxeles, quiero que esté centrado exactamente en la mitad de la página. Eso lo puedo hacer con CSS. Ya se ha posicionado absoluto, así que le doy un top 50 por ciento, izquierda 50 por ciento, y transformar traducir -50% -50 por ciento. Por supuesto, puedes posicionarlo de una manera diferente dependiendo de dónde lo desees. Ahora solo pondré el fondo en el elemento body en negro. Creo que esto se ve bien por ahora. Aumento el tamaño de la fuente. 450 tal vez. Sí, estamos convirtiendo el color a un ángulo. Entonces mira por dónde fluyen las partículas cuando el texto es correcto. Y mira lo que pasa con su dirección de movimiento. Cuando cambio el color a verde. El ángulo azul en realidad es similar a leerlo porque no estamos extendiendo la gama de colores en sí, sino que lo estamos convirtiendo primero a escala de grises, y luego estamos convirtiendo eso en ángulo. Parece que el azul y el rojo tienen un valor de escala de grises muy similar. Verás la mayor diferencia en ángulos al usar colores que sean claros u oscuros. Colores que están muy separados en el espectro de escala de grises. Marrón. Probemos algo mucho más ligero, amarillo. Podemos ver claramente que la dirección del flujo está influenciada por el color, por el color del texto, perfecto. 37. Flujo y degradación: Podría dejarlo aquí, pero estaba jugando con él y se me ocurrieron más cosas realmente geniales que quiero compartir contigo. Esta es siempre mi parte favorita donde tenemos toda la lógica en su lugar. El efecto está corriendo y puedo experimentar. Sabemos que los diferentes colores empujan el flujo de partículas en diferentes direcciones. Entonces veamos qué sucede cuando el relleno del texto no es solo de un color, sino un degradado que transita de color a color. Me pregunto cómo será eso. Una variable personalizada llamada el gradiente uno, y yo llamo a Canvas incorporado create linear gradient method. Espera cuatro argumentos, x e y del punto inicial, y x e y del punto final. El degradado se dibujará a lo largo de una línea entre estos dos puntos. Quiero un degradado desde las coordenadas de esquina superior izquierda, cero-cero hacia las coordenadas de la esquina inferior derecha efecto ancho y altura de efecto, que son lo mismo que ancho y alto del lienzo. Ahora puedo tomar ese gradiente una variable y llamo incorporado agregar el método de parada de color de ella. En el desplazamiento 0.2, el color será blanco, por ejemplo 0.8 offset. Intento azul completo. Ahora solo puedo establecer FillStyle a esta variable de gradiente uno. Impresionante, esto es tan genial, como se curva el flujo a medida que pasamos del azul al blanco. Ahora que entendemos esto, podemos experimentar con diferentes rangos de color y diferentes gradientes. Agrego otra parada de color en el punto cero para el color amarillo. 0.6 será, por ejemplo, verde. Sólo puedo jugar con los valores de color para ver qué flujo obtengo. Es interesante cómo cambia la dirección del flujo a medida que los colores transitan siguiendo el degradado. Olvidé mencionar una característica importante de filtText y trazo de texto incorporado en los métodos Canvas, podemos pasarles quinto argumento opcional para definir el ancho máximo del texto. Diré que el ancho máximo del texto es el peso del lienzo. Ahora bien, si el texto es más largo, se aplastará para encajar en el área. Si quiero algunos de márgenes, puedo decir este ancho de punto veces 0.8. Y el texto tomará el máximo del 80 por ciento de Canvas. Tomará un 80 por ciento si le damos más espacio ajustando el ancho del lienzo a un valor mayor. Vuelvo a Tamaño de lienzo 500 veces 500 pixeles. Cambié la palabra para fluir. Podemos cambiar la fuente a Helvetica, por ejemplo, volver al impacto. Y los textos serán JS. Quiero que fluya para curvar más a la derecha. Entonces juego con los valores de color para conseguir que el gradiente influya en la dirección del campo de flujo. Esto se ve bien. Copo este bloque de código y también renombro todos estos gradientes. Y lo uso como FillStyle online 112th. Vuelvo a jugar con los valores para ver qué pasa. Sé más o menos en qué dirección fluye cada color, pero en su mayoría es de prueba y error. Esto se ve interesante. Creo un degradado tres copiando este bloque de código y usando eso como FillStyle en línea ciento 18. Esta vez será un gradiente radial, por lo que necesitamos pasarle seis argumentos, x e y del punto central del círculo interno. Es radio. Así que quería que el círculo interno comenzara exactamente en medio del lienzo horizontal y verticalmente. Y el radio será de diez pixeles. El borde exterior del círculo de gradiente radial volverá a estar desde la mitad de Canvas y el radio será un ancho de escritorio. Interesante. Ajusto los colores para ver qué forma obtengo. Se puede ver como el gradiente radial afecta el flujo de una manera diferente. Este me gusta mucho. Voy a mantener los tres gradientes que definí para poder intercambiar entre ellos más tarde si quiero. 38. Consejos, trucos y experimentos: Cuando los ángulos cambian de dirección, es un giro brusco. Podría funcionar para usted, pero tal vez queremos que las líneas giren más gradualmente cuando cambie el ángulo en el campo vectorial. Estamos manteniendo el valor del ángulo actual para cada partícula aquí en la clase de partícula principal. Estamos cambiando este valor dentro del método de actualización para que coincida con el valor de ángulo de la cuadrícula en el campo de flujo. Voy a crear otra propiedad aquí llamada new angle. Y voy a comprobar la diferencia entre el ángulo actual y el nuevo ángulo. Y en lugar de cambiar a ese nuevo ángulo instantáneamente, cuando las partículas ingresen a una nueva celda en la cuadrícula del campo de flujo, simplemente empujaremos las partículas hacia ese nuevo ángulo en cierta fracción de su diferencia. O para reducir los cálculos necesarios, en lugar de calcular la fracción de la diferencia entre el ángulo existente y el nuevo ángulo, solo puedo tener un valor establecido llamado carácter de ángulo. Será un pequeño valor en radianes. Aquí abajo en el método de actualización, dije nuevo ángulo dos, un ángulo almacenado en la celda del campo vectorial. Y digo si el ángulo actual de la partícula es más que nuevo ángulo, reducir el valor de ángulo de la partícula por el valor de carácter de ángulo que definimos, mover el ángulo existente un paso más cerca del nuevo ángulo, elijo hacerlo de esta manera para ahorrar rendimiento. También se puede decir cambiar el valor del ángulo una décima parte de la diferencia entre ángulo y nuevo ángulo, lo que le dará curvas más graduales a expensas del rendimiento porque se requieren más cálculos. De lo contrario, si el ángulo es menor que el ángulo u, aumente el valor del ángulo por carácter de ángulo. Uno más en otro lugar establecemos ángulo a nuevo ángulo. Ahora puedes ver que los giros bruscos se han ido y solo estamos empujando suavemente las partículas hacia ciertos valores de ángulo. Ajusto el valor del carácter del ángulo para empujarlos un poco más fuerte. O podemos hacer un valor aleatorio aquí entre algún rango pequeño para que cada partícula se curva de manera diferente. Puedo ajustar maxlength. Puedo cambiar el modificador de velocidad. Tenemos toda la lógica en su lugar. Si quieres, puedes jugar con él para ver qué variaciones de este efecto te pueden llegar a ocurrir. Entonces esta es mi manera eficiente de rendimiento muy básico, cómo hacer que las partículas cambien de dirección más gradualmente a medida que el flujo sobre la rejilla de celdas en el campo de flujo. También me gustaría poder controlar cuántas partículas fluyen dentro las formas de letras y cuántas fluyen en el área fuera de las letras. Ahora, es completamente aleatorio, pero no tiene por qué serlo cuando las partículas se reinician. Quería comprobar si se está restableciendo dentro de las formas de las letras o fuera de ella, en algún lugar del área transparente alrededor de la letra. Si está fuera de las letras, quería volver a intentarlo. Voy a tener una variable llamada intento. Comenzará en cero. Al principio. Voy a tener una bandera llamada reset success. Inicialmente será falso. Cuando las partículas se reinicien dentro de las formas de las letras, cambiaremos esto a true. Voy a tener un bucle while. Cuando las partículas se restablecen, quería probar cinco veces. Hará cinco intentos de elegir aleatoriamente una posición en algún lugar de Canvas para intentar restablecer dentro de las formas de las letras. Siempre y cuando los intentos sean menores cinco y mientras el éxito de reinicio sea falso, crearé un índice de prueba. Será una celda aleatoria en algún lugar de la matriz de campo de flujo. Compruebo si este índice de prueba tiene alfa más que cero, lo que significaría que es la celda en el campo de flujo la que tiene algún color visible en sus datos de píxeles, lo que significaría que es una de las letras. Alternativamente, será transparente, lo que significaría que es el fondo vacío alrededor de las letras. Si tiene Alfa más de cero, significa que encontramos una de las celdas de letras. Entonces establecemos las posiciones x e y de la partícula a las posiciones x e y de la celda en el campo de flujo. La grilla. Aquí abajo puedo ver que las celdas llenas de fluido, los objetos dentro de la matriz de campos de flujo contienen valores de ángulo x, y y de color. Entonces esta X e Y vendrán de ahí. Dije que esas coordenadas x e y son el primer punto en el camino al agregarlo a la matriz de historia. Y reinicié el temporizador de nuevo a términos maxlength dos. También estableceré reset success a true. Es importante destacar que necesito asegurarme de que cada vez que intentemos hacer esto, aumentemos el intento por uno para que cuando lleguemos a cinco, este bucle while, y no queremos crear un bucle while interminable. Continuará sólo mientras ambas condiciones sean ciertas. Entonces solo cuando los intentos son menores a cinco y al mismo tiempo, siempre y cuando el éxito del reset sea falso. Si ejecuto el código, no se restablece en absoluto. Entonces eso indica que esta condición en la línea 78 siempre está devolviendo falso. Es porque no estamos empujando este valor Alpha en nuestros objetos de celda de campo de flujo. Cambié los intentos aquí arriba a 50. Entonces aquí abajo estoy calculando alfa en línea 160. Necesito asegurarme de que el valor realmente termine dentro de la matriz de campo de flujo. Así. Las líneas perfectas se restablecen dentro de las letras. Dije max, intento volver a cuatro después de que el bucle while haya terminado. Si después de intentar restablecer cuatro veces, todavía no hemos encontrado una celda con alfa más de cero y reset, el éxito sigue siendo falso. Reiniciaremos las coordenadas x e y de esa partícula en algún lugar aleatoriamente alrededor del lienzo. Todavía no está restableciendo partículas fuera de las formas de letras. Incluso cuando baje a sólo dos intentos. ¿Qué tal un solo intento? Voy a resolver esto. Sólo dame un segundo, ¿verdad? Tengo que poner estas nuevas posiciones dentro de la matriz de historia. Y lo más importante, tengo que restablecer el temporizador de nuevo a maxlength veces dos para que las partículas se animen. Bonito. Entonces ahora cuando las partículas se restablecen, este código intentará una cierta cantidad de veces restablecer las partículas dentro de las formas de las letras. Y si no encuentra que la celda en cierta cantidad de intentos, simplemente restablecerá la partícula algún lugar aleatoriamente alrededor de Canvas. Podemos ajustar cuántas partículas queremos restablecer dentro y fuera de las formas de letras cambiando el número de intentos en la línea 75. El último intento, las partículas menos probables son encontrar las formas de las letras en el tiempo. Así que podrían resetear afuera. Puedo aumentar el número de partículas y aumentar el tamaño de las celdas. Podemos ver que la mayoría de las partículas ahora se restablecen dentro de las formas de letras, pero ocasionalmente obtenemos un reinicio en otro lugar, en algún lugar afuera, puedes ajustar el número de partículas y tamaño de celda a lo que quieras y a lo que sea que tu computadora pueda manejar aquí. Puedo eliminar este código. Creo que ahora todos entendemos cómo estos valores afectan a la animación. Tal vez 2000 partículas. ¿Qué pasa si agrego color blanco a la matriz de colores para algunos reflejos? Interesante, lo vuelvo a quitar. Intento el gradiente uno para cambiar la dirección del campo de flujo. Degradado también. Creo que mi favorito es el gradiente tres. ¿Cuál prefieres? Yo aumento maxlength, lo que sí tiene efecto en el rendimiento. Las líneas más largas toman más potencia informática para dibujar. Entonces creamos una cuadrícula, dibujamos texto en Lienzo. Analizamos ese tipo de nosotros con textos dibujados en él. Para los datos de píxeles, recorrimos esos datos de píxeles en una cuadrícula para extraer los valores de color y las coordenadas de cada píxel. Y convertimos estos resultados en colores en ángulos. A partir de esa información, creamos un campo de flujo, una cuadrícula de ángulos, donde la dirección de los ángulos es influenciada por el texto que se dibujó en Canvas. Puedo eliminar este bloque de código. Entonces creamos un sistema de partículas aquí. A lo mejor quería que las partículas comenzaran a fluir desde las formas de las letras incluso en la primera carga de página. Entonces activaré manualmente el método de reinicio en cada partícula a medida que las cree, lo que los obligará a hacer algunos intentos de encontrar celdas en el campo de flujo que contenga algunos valores de color, celdas que están sobre las formas de letras. Cambié el texto para que fluyera. puede ver que se mete con el gradiente radial, que se espera. Aumenta el ancho del lienzo a 1500s píxeles. Puedo crear max-width del texto aquí abajo. Puedo usar gradientes para, para cambiar la dirección del flujo. Esto se ve interesante. ¿Qué tal el gradiente uno? Probablemente te diste cuenta de que esto funcionaría en imágenes así como solo estoy usando get ImageData para obtener formas de letras que fueron dibujadas en Canvas. ¿Quieres aprender a usar esto en las imágenes? Te voy a mostrar exactamente cómo hacer eso en la siguiente parte. Espero que te estés divirtiendo. 39. Los campos de flujo de imágenes explicados: Entonces construimos un campo de flujo de texto y experimentamos con él. Vuelvo a poner el texto a js mayúscula para que encaje en la pantalla y podamos verlo todo. Puedes descargar imágenes que estaré usando en la sección de recursos a continuación, o puedes usar las tuyas propias. Estaré usando imágenes pequeñas, 200, 200 píxeles con un tamaño alrededor de 10 kb. El tamaño de las imágenes es importante para el rendimiento. Entonces, si estás usando tus propias imágenes, piensa en eso y optimiza las imágenes antes de usarlas para este proyecto, si quieres que tu animación funcione sin problemas, este efecto se ve muy bien con algunas imágenes específicas. Desde mi experiencia, el mejor resultado es con formas simples que tienen colores degradados, ya que esto hará que la curva de flujo a su alrededor sea muy agradable. En index.HTML, creo un elemento IMG con un ID de estrella y la fuente apuntará hacia esa imagen. Si recuerdas de la parte anterior, el truco fue dibujar texto en Canvas y luego analizar esos datos de píxeles y crear un campo vectorial, una cuadrícula de ángulos a partir de esa forma. Yo quiero hacer lo mismo aquí con una imagen. Ahora, quería dibujar esta imagen en Canvas y luego quiero escanearnos eso un poco con esta imagen dibujada en ella. El problema es que hay algunas limitaciones a este Cross-Origin Resource Sharing es una medida de seguridad que no nos permite dibujar ninguna imagen aleatoria en Canvas y luego escanear ese Canvas en busca de datos de píxeles. Si la imagen no es del mismo origen, ese tipo de nosotros se considera contaminado por datos de origen cruzado. Y tu código terminará con un error de consola para dibujar imagen en Canvas y la escanearla con get ImageData, esa imagen necesita ser considerada del mismo origen. Si está ejecutando su código desde un servidor y la fuente de la imagen aquí apunta a una imagen almacenada en la misma dirección del servidor. Entonces va a funcionar. Quiero que esta base de código sea flexible y que funcione fácilmente a nivel local. No quiero repasar la configuración de un servidor local en este momento. Entonces, una posible solución alternativa es convertir la imagen en sí misma en una llamada cadena de datos base 64. Para ello, podemos usar URL de datos construida en el método JavaScript, o hay muchos sitios web que lo harán por nosotros en segundos. En resumen, para evitar problemas de uso compartido de recursos de origen cruzado, estoy convirtiendo el archivo de imagen en sí mismo en una cadena de datos, y luego usaré esa cadena de datos como fuente de imagen. Yo hago eso por Google y P y G, dos base-64. Tenga en cuenta que la imagen no tiene que ser PNG. También trabajará con otros formatos. Voy a elegir por ejemplo este sitio web en línea PNG tools.com. Pero los otros sitios funcionarán de manera similar. Arrastre y suelte la imagen que quiero convertir desde mi computadora a este campo. Y convertirá instantáneamente todo el archivo de imagen en una línea de código muy larga. Utilizar una imagen pequeña como sea posible en términos de ancho y alto, así como kilobytes. De lo contrario, este código será demasiado largo y causará problemas de rendimiento cuando lo animemos en un minuto. Idealmente, utilizar las imágenes y proporcionar. Y luego una vez que tengas un efecto de trabajo, puedes cambiar a un archivo de imagen diferente. Esta cadena de datos base 64 necesita comenzar como esta imagen de dos puntos de datos. Si no es para ti, haz clic en esta casilla de verificación para convertirla a un formato específico que necesitemos. Copio esta línea de código extremadamente larga y la pego como atributo fuente aquí. En Visual Studio Code, puedo hacer clic en Ver y ajuste de palabras para que el archivo de código sea más manejable. Como puede ver, estamos dibujando esa imagen de estrella, pero nunca usamos el archivo de imagen real. Esta larga cadena de código reemplaza completamente el archivo de imagen en sí. Y como todo ese código está dentro de nuestro archivo HTML índice, se considera el mismo origen en todas las circunstancias. Y por lo tanto podemos hacer operaciones avanzadas de píxeles en él con lienzo HTML sin desencadenar un error de Canvas contaminado. Déjame mostrarte. Es fácil conseguir que esto funcione ahora, realmente no quiero dibujar el elemento image en sí, así que tomo su id y lo escondo con CSS. En cambio, quiero dibujarlo en Canvas donde el JavaScript, voy al efecto principal de clase y creo una nueva propiedad llamada esta imagen de punto. Señalé esta variable a ese elemento de imagen usando su ID como de costumbre. Entonces tenemos una variable apuntando a la imagen estelar aquí en la línea 110. Dibujémoslo en Lienzo. Aquí arriba dije lienzo ancho a 500 pixeles. Igual que tengo este método de dibujar texto. Para mantener nuestro código organizado, crearé un método separado para dibujar la imagen. No quiero llamarlo una imagen de dibujo porque ese nombre ya existe para un método Canvas incorporado, llamaré a este método personalizado por ejemplo dibujar una imagen de campo de flujo para mayor claridad. En el interior, tomo estos contextos de punto y llamo método de imagen de dibujo incorporado. Necesita al menos tres argumentos, la imagen a dibujar y las coordenadas x e y donde dibujarla. Para probarlo, llamaré draw flow field image from inside render porque no soy un definido en ancho y alto en línea 148, la imagen se está dibujando en su tamaño original. Podemos redimensionarlo o estirarlo pasando en valores para ancho y alto, 300 con 100 de altura. ¿Qué tal ancho completo y altura total del lienzo? Bonito. Y si quisiera que la imagen se centrara exactamente en el medio del cannabis, independientemente del tamaño que elija. Eso también es muy fácil. Creo una variable auxiliar llamada tamaño de imagen. Digamos que quiero que el ancho y el alto de la imagen sean 70% del ancho del lienzo. Lo uso aquí como ancho y alto. Sí. Ahora dije coordenada x a la mitad del cannabis. Entonces este ancho de punto veces 0.5 y hago menos la mitad del tamaño de la imagen. La imagen está centrada horizontalmente. Para coordenada y vertical, hago altura de Lona veces 0.5. El medio de una especie de como verticalmente menos Tamaño de la imagen veces 0.5. Perfecto. Esta es una fórmula muy simple para centrar la imagen en medio del lienzo HTML. Cuenta el hecho de que imágenes en Lienzo se dibujan igual los rectángulos de la esquina superior izquierda yendo a la derecha y hacia abajo, dependiendo de su anchura y altura. Si lo redimensiono ahora a cualquier tamaño, siempre se dibujará en medio de Canvas. Voy a hacer el 80 por ciento del ancho del lienzo, por ejemplo como ya expliqué antes, aquí creamos un campo de flujo degradado, dibujamos algo en Canvas. Luego analizamos ese tipo de nosotros con ese texto o esa forma o imagen dibujada en él para datos de píxeles para crear una cuadrícula de campo vectorial a partir de él convirtiendo colores en ángulos. Ya tenemos toda esta lógica de la parte anterior en su lugar. Entonces todo lo que tengo que hacer aquí es reemplazar esta parte donde dibujamos texto con código que dibuja la imagen. Yo llamo dibujar imagen de campo de flujo aquí y aquí vamos. Eso fue fácil. Realmente no quiero dibujar la imagen real de la estrella sobre ella así. En cambio, lo tomo de aquí y quiero dibujarlo detrás de las partículas solo cuando el modo de depuración esté activo. Entonces, desde dentro de este bloque de código, ahora podemos activar y desactivar el modo de depuración presionando letra D en el teclado para mostrar y ocultar el campo vectorial, la cuadrícula y la imagen de origen. Puedo cambiar el tamaño de la imagen. Podemos ver que siempre se mantiene centrado y que todo funciona bien. Si cambio el tamaño de Canvas , cambiará el tamaño de la imagen con él. Porque dije que el tamaño de la imagen estelar para ser del 80 por ciento del ancho del lienzo. 40. Trucos de manipulación de colores: No podría dejar esto y dejarte hacer tus propios experimentos. Pero de nuevo, estaba jugando mucho con el código y me preguntaba, cómo puedo conservar y usar los colores originales de la imagen fuente. ¿Correcto? Ahora, estamos usando colores de esta matriz de colores de puntos en la línea 25, los colores de la imagen fuente en sí no son visibles. Aparte de utilizarlos para determinar ángulos del campo de flujo. Ya estamos escaneando esa imagen en busca de datos de píxeles, así que ¿por qué no intentar usarla? Escribí múltiples soluciones diferentes para este fin. Decidí mostrarte esta por las razones que voy a explicar como implementamos, si tienes algunas ideas de cómo mejorar esta base de código, por favor házmelo saber. En cada objeto de partícula, almacenaré una propiedad separada para rojo, verde y azul. Esto no es necesario si me acaban de tomar los colores como son de la imagen original. Pero cuando veas cómo se ve eso, probablemente estarás de acuerdo en que necesitamos una forma de hacer una transición dinámica y gradual entre colores a medida que las partículas y líneas viajan de celda a celda sobre el campo de flujo. Por eso voy a necesitar los tres colores por separado así. Déjame mostrarte por qué. Voy a concatenar declaración de color RGB aquí. Siéntase libre de usar una plantilla literales aquí en su lugar, si esa es su sintaxis preferida, simplemente haré RGB plus, más coma, más verde más coma, más bu más corchete de cierre. Ahora, podemos cambiar el color de las partículas ahí dentro estableciendo estos dos valores diferentes. Bien, eso funciona bien. Voy aquí dentro del método init donde dibujamos ese archivo de imagen original en Canvas y lo escaneamos para obtener datos de píxeles. Voy a necesitar tres valores para rojo, verde y azul. Así que los pongo a disposición empujándolos como propiedades adicionales dentro de la matriz de campo de flujo. Así que ahora es una especie de escaneado para datos de píxeles celda por celda, fila por fila. Cada vez que ingresemos a una nueva celda en la degradación del campo de flujo, almacenaremos todos estos datos para cada celda en la cuadrícula dentro de nuestra matriz de campo de flujo. Ahora sé cuál es el valor rojo, verde y azul de cada celda individual en la cuadrícula. Así puedo hacer coincidir el color de las partículas con estos valores a medida que las partículas fluyen sobre Canvas. Dentro del método de actualización en la clase de partículas. En esta área, extraigo el elemento en este índice particular dentro matriz de campos de flujo en una variable solo porque quería que la sintaxis en este bloque de código fuera más fácil de leer. Y también para el rendimiento, saqué ese índice de la matriz solo una vez, y luego uso esa referencia existente en múltiples lugares. Ahora puedo reemplazarlo aquí y aquí. Este es el mismo código. Simplemente lo refactorizamos. Entonces, en esta área, extraemos el valor del ángulo de matriz satisfecha para manejar el movimiento de las partículas. En esta área, extraeré los valores de color de esa celda en el campo de flujo. Yo solo quería las celdas que contienen datos de píxeles de la imagen si tienen alfa más de cero, porque conozco las celdas transparentes con cero alfa o el fondo alrededor de la imagen. No nos importan los de aquí. Entonces, si esta celda no es transparente, tome esta propiedad de lectura de puntos en este objeto de partícula. Definimos en la línea 25 y la configuramos para leer la propiedad que acabamos de extraer de propiedad de lectura del campo de flujo contenida en esta celda en particular en el campo de flujo sobre el que la partícula se está moviendo actualmente. Haremos lo mismo por este verde oscuro y este azul oscuro. Ahora, quiero usar estos valores de color actualizados para construir una cadena de colores RGB nuevamente. Entonces copio la línea 28 y la uso aquí abajo en la línea 62. Bonito. Estamos viendo los colores reales de la imagen. Hacer esto como una gran cantidad de cálculos adicionales por fotograma de animación a nuestro efecto. Pero depende de ti decidir si vale la pena o si prefieres usar colores predefinidos como lo hicimos antes, solo te estoy mostrando lo que es posible. Como es habitual, todo esto se puede optimizar de muchas maneras diferentes. Las técnicas avanzadas de optimización están fuera del alcance de esta clase, pero podemos hablar de ello más adelante en algún otro curso. Se puede ver que las líneas están parpadeando. ¿Sabes por qué es eso? Es porque cuando la partícula viaja de celda azul a celda blanca, por ejemplo, el color de toda la línea larga que la partícula está arrastrando detrás de ella cambiará a ese nuevo color instantáneamente. Cambiará instantáneamente el color de toda la línea porque cada línea es solo una llamada de dibujo. Así que podemos simplemente cambiar el color de una parte de esa línea con el código que escribimos hasta ahora. Nuevamente, múltiples soluciones aquí. Podría ajustar nuestro código para verificar si el color cambió. Y luego usa ese color actualizado solo para algunos segmentos de línea. O lo que voy a hacer aquí, voy a cambiar el color de toda la línea. Pero en lugar de que ese cambio de color ocurra instantáneamente, voy a calcular gradualmente la diferencia entre los dos colores sobre múltiples pasos de animación. Por lo que los colores no solo se intercambiarán instantáneamente, van a hacer una transición lenta. ¿Cómo lo hacemos con código? Ya que estamos en la sección avanzada, utilizaré una sintaxis simplificada más avanzada. Esto se llama operador ternario, el único operador JavaScript con tres operandos. Lo usaremos aquí como una simple declaración de una línea if else. Definir una condición, una expresión a evaluar. Si es verdad. Signo de interrogación, haz esto. De lo contrario, si es falso, colon, haga esto. Entonces, a medida que las partículas fluyen sobre la cuadrícula del campo de flujo y extraen valores de color de esas celdas. Compruebo si el valor rojo de la partícula es el mismo que el valor rojo de la celda en el campo de flujo en este índice. Si lo es, simplemente no hagas nada y déjalo en paz. Si el valor rojo no es el mismo, en lugar de reasignarlo instantáneamente al nuevo valor rojo actualizado, simplemente aumentaré o disminuiré gradualmente valor rojo en una fracción de su diferencia. Digamos por una décima parte de la diferencia. Podríamos haber hecho lo mismo con los valores de ángulo aquí, pero decidí que es más eficiente en el rendimiento usar un valor establecido almacenado dentro del carácter de ángulo, aunque usar diferencias de ángulo graduales crearía curvas más naturales en el movimiento de las partículas. Puedes probarlo más tarde si quieres. En fin, verifico si el rojo es lo mismo que el rojo nuevo. Si es así, déjalo en paz. Si no lo es, acercarlos un paso más, pero no del todo a la vez para conseguir una transición gradual. No puedo ver si esto está funcionando o no. Entonces hagamos lo mismo por el verde. Así. Tengo que tener cuidado con la sintaxis aquí. Creo que está funcionando. Hagámoslo también por el azul. Así. Solo estoy revisando mi código para ver si todo está bien después de todo eso copiando y pegando. Sí, esto es bueno. Estoy usando 0.1 aquí. Este valor determinará qué tan agudo o gradual será el cambio de color, qué tan rápido pasarán los colores del color existente al nuevo color objetivo. Antes de que la transición de color ocurriera instantáneamente para toda la línea de partículas multisegmentadas. Ahora sucedieron poco a poco y el efecto se ve bien. Creo que esto es muy especial. No puedo creer que pasáramos de dibujar una sola línea animada a doblar formas de campo de flujo alrededor de las imágenes. Si seguiste todo el camino hasta aquí, este es un gran logro, bien hecho, y felicidades por tu dedicación al aprendizaje. Seguro que eres un codificador creativo. Aquí en la línea 86, puedo controlar cuántas partículas se reinician dentro de la forma y cuántas se reinician fuera de ella cambiando cuántos intentos le damos a cada partícula para tratar encontrar esa forma entre reinicios. Para asegurarnos de que esto funcione, podemos usar una imagen diferente. De nuevo, ten en cuenta imágenes demasiado pequeñas si es posible. Las formas simples como las estrellas funcionan muy bien para este efecto. Puedes descargar la otra imagen que te proporcioné en la sección de recursos, o puedes usar tu propia imagen. Ahora, copio esta línea de código extremadamente larga y voy a indexar HTML. Necesitamos líneas para estar rompiendo para reemplazar la fuente. Entonces, si todo está en una línea para ti, puedes ir a Ver envoltura de palabras para hacer líneas de freno VS Code Editor así. Para reemplazar la cadena de datos. En Visual Studio Code, sólo puedo seleccionar el inicio de esta cadena muy larga. Me desplazo hasta el final. Presiono la tecla Mayús en mi teclado. Y mientras mantengo presionada la tecla Mayús, hago clic donde quiero que termine la selección. Destacará todos los textos intermedios y puedo presionar Eliminar. Bonito. Ahora que sé que eliminé la imagen antigua, pego la nueva cadena de datos base 64 de la nueva imagen. Yo lo guardo. Y aquí vamos, estamos dibujando una imagen diferente y podemos ver los colores se están extrayendo correctamente de los datos de píxeles de origen. Puedes consultar el código fuente en la sección de recursos a continuación. También jugaré con el código ahora e incluiré algunos de mis otros experimentos de bonificación para que los descargues e inspecciones si quieres inspiración sobre dónde llevar este efecto más lejos. Me gustan los proyectos de codificación creativa porque estamos aprendiendo sobre animación así como el programa general y principios. Hicimos muchas funciones de manipulación de matrices y para bucles hoy en día, por ejemplo, todas estas son muy importantes en todas las ramas de la codificación, no solo para la animación. Muchas gracias por pasar el tiempo conmigo. Espero que hoy tengas mucho valor. Te veré más tarde.