logo

midulive


Transcribed podcasts: 605
Time transcribed: 13d 3h 7m 36s

This graph shows how many times the word ______ has been mentioned throughout the history of the program.

Amigos, vamos a hacer un Tier Maker.
Un Tier Maker, no sé si lo conocéis.
Hostia, mira, uno de waifus, la madre que los parió.
Un Tier Maker es esto, ¿vale?
Un Tier Maker es que tú tienes diferentes niveles
y arrastras, arrastras esto aquí.
Se supone, porque yo no sé por qué a mí no me funciona,
no sé si es que hay que iniciar sesión.
Es un poco, da mucha rabia.
Pues el nuestro no habrá que iniciar sesión.
Pero bueno, se supone que tú lo que haces
es mover a los personajillos
en el nivel que tú creas.
Y la verdad es que está muy chulo.
Pero esto, en lugar de hacerlo...
Mira, este está muy gracioso.
En lugar de hacerlo con RIA, con cosas...
Lo vamos a hacer con JavaScript puro
y vamos a aprender la API de drag and drop.
Que vas a ver que es muy fácil de utilizar
y vamos a hacer cosas de verdad
que te van a volar la cabeza.
¿Por qué?
Porque con drag and drop
vamos a estar creando también la previsualización.
Vamos a hacer que te puedas descargar
la imagen final, ¿vale?
O sea, que cuando tú, una vez que hayas botado,
que esto se genere una imagen, ¿vale?
Pero esto lo vamos a hacer así, sería algo así.
Pero lo vamos a hacer con JavaScript.
En esto sí que utilizaremos una dependencia
muy pequeñita, ¿vale?
Pero lo vamos a hacer con una dependencia
porque es muy difícil hacerlo a mano.
Se puede hacer, ¿eh?
Se puede hacer porque yo lo he llegado a hacer.
Pero es bastante complejo.
Si queréis os explico un poco por encima
después cómo se hace.
Pero es bastante más difícil de lo que parece.
Pero vamos a hacer que podáis descargar
con una imagen el tier list que habéis hecho.
Y además, también vamos a hacer otra cosa
que está muy chula,
que es que vais a poder arrastrar imágenes.
Que por cierto, estoy pensando,
tengo las imágenes, tengo imágenes preparadas por aquí.
Utilizaremos estas imágenes que tenemos por aquí.
Lo que vamos a poder hacer es seleccionar las imágenes,
arrastrarlas y que se creen los ítems en un momento.
Vais a alucinar.
Es que vamos a aprender un montón de cosas en un momento
y todo con puro JavaScript.
El proyecto que vamos a hacer hoy
es parte de esta iniciativa
que tenemos de 100 proyectos de JavaScript, ¿vale?
Ya teníamos aquí 100 proyectos.
Bueno, 100 proyectos no tenemos.
Tenemos 6 por ahora.
Vamos a ver.
Vamos poco a poco.
Hoy hacemos el séptimo.
Y en cada proyecto se aprende pues algo.
Y tenéis, de cada proyecto tenéis una demostración
para ver cómo funciona.
Tenéis el vídeo donde lo desarrollamos, ¿vale?
Para que veáis paso a paso cómo lo hicimos.
Y tenéis todo el código disponible.
Y que todos los proyectos que estamos haciendo
los estamos haciendo con HTML, CSS y JavaScript.
Sin dependencias, ¿vale?
¿Por qué me parece interesante que seas independencia?
Porque todo lo que vas a aprender hoy
lo podrías aplicar a React, a Angular, a Vue,
a cualquier cosa.
Sin importar el framework que vayas a utilizar.
Y porque JavaScript es importantísimo entenderlo
y conocerlo en condiciones, ¿vale?
Así que vamos a darle caña.
Y para eso, mira, vamos a irnos aquí.
Este es el proyecto de 100 proyectos de JavaScript.
¿Veis que aquí tengo todos los proyectos?
5, 1, 2, 3, 4, 5, 6.
Pues vamos a crear uno nuevo, que es 0, 7, tier maker.
Y dentro vamos a crear un index.html.
Y vamos a rellenarlo ya con el HTML mínimo.
Vamos a poner, a ver cómo pone aquí Tetris en JavaScript.
Bueno, vamos a poner aquí tier maker, ¿vale?
Y aquí, aquí vamos a hacer, aquí va la magia.
Aquí va la magia.
Entonces, yo lo que utilizo, como siempre, es esta extensión maravillosa
que me ha dejado fatal.
Hola.
Iniciar del servidor.
Ostras, que no me inicia el...
¿Por qué no me inicia el servidor?
No sé por qué no lo hace.
A ver, voy a volver.
Vamos a intentar abrirlo otra vez.
A ver qué raro, ¿no?
Normalmente funciona, ¿eh?
Normalmente funciona.
Pero que si no, lo haremos de otra forma.
Ahora.
Vale, ahora sí.
Ahora sí.
Vale, aquí va la magia.
Y si vamos cambiando, vale, ya funciona.
Ya está, ya funciona.
No sé, le ha pasado algo raro.
Le ha pasado, se ha quedado tonto.
Se ha quedado ahí en pajaritos.
Cosas, cosas que pasan, cosas que pasan.
Vale, pues lo que vamos a hacer es en nuestro tier maker.
De nuevo, si no sabéis lo que es un tier maker,
es una de estas listas en las que el usuario,
arrastrando cada una de las cosas,
las puede poner en la posición que quiera.
Y al final, pues te queda una cosa así.
Que está muy bien.
Y son como imágenes y todo esto.
Y esto justamente es lo que vamos a hacer.
Y está muy bien porque vamos a aprender el drag and drop.
Que normalmente es una cosa que no se suele ver.
Y la gente se cree que se necesitan bibliotecas.
¿Vale?
Así que, oye, gracias general.
Cost por esos bits.
¿Cómo se puede configurar Slim y Pritter igual al tuyo?
Pues en cualquier vídeo que hemos hecho,
lo puedes ver igual que como lo configuro.
No tiene mucha más historia.
No hemos hecho nada raro.
¿Vale?
Entonces, vamos a poner, bueno, unos estilos básicos al menos.
Vamos a poner aquí unos estilos básicos.
Vamos a poner body.
Vamos a poner un background.
Luego igual lo cambiamos.
Pero al menos por ahora.
Phone family, system.
Vamos a poner display grid para que quede todo en el centro.
Center.
Pondremos aquí que como mínimo alto.
Bueno, no vamos a poner display grid porque esto puede quedar un poco raro.
Por ahora vamos a dejarlo, creo que lo vamos a dejar así.
¿Vale?
Lo que voy a poner es el típico CSS reset.
Ahora aquí vamos a poner header.
Y voy a borrar, voy a borrar, voy a robar, voy a robar esta imagen.
Que me parece que está muy bien esta imagen.
La vamos a robar.
Imagen, source, tal.
Básicamente para que podamos aquí crear nuestro header.
Header, ¿cómo le llamo?
Header, no sé cómo llamarme.
Top header.
Venga, top header.
Top header.
¿Vale?
Top header.
Display flex.
Justify content center.
Y aquí vamos a decirle que la imagen como máximo sea de 150 píxeles.
Y vale, algo así.
¿Vale?
Al menos para empezar, para tener algo ahí y listo.
Y esto, esto no será necesario, pero bueno.
Vale, ya tenemos, ya hemos terminado nuestro tier maker.
Sería buenísimo, sería buenísimo.
Bueno, voy a darle un poquito más de espacio a esto.
Padding block 8 píxeles, ¿vale?
El block sería, en nuestro caso, sería vertical.
Vale, inline sería horizontal.
Vale, pues con esto ya tendríamos, voy a hacer un poco más pequeño esto.
Vale, pues con esto tenemos un poco lo mínimo que necesitamos.
No sé si algún estilo, sí, vamos a hacer que esto sea margin.
Vamos a centrar el contenido.
Le vamos a poner que como máximo sean 500 píxeles para que nuestro tier maker no se nos vaya mucho por las manos.
Le pondremos horizontalmente.
Este padding inline es como poner padding left 32 píxeles, padding right 32 píxeles.
Vale, aunque el inline, esto es muy interesante porque el inline en realidad depende del idioma, va a ser en línea, va a ser horizontal o va a ser vertical.
En nuestro caso, que escribimos de izquierda a derecha y de arriba a abajo, el inline sería en línea al texto.
O sea, sería horizontalmente.
Vale, pero tened en cuenta que en otros lenguajes el inline se vería diferente, ¿vale?
Pero en nuestro caso, el inline sería como poner este left y right de 32 píxeles.
Y queda mucho más corto, queda mucho mejor.
Y ya está, vamos a poner user select none para que el usuario no pueda seleccionar el texto.
Vale, y aquí vamos a crear nuestro tier list.
Ahí es donde vamos a empezar con nuestro tier.
Aquí va la magia, ¿vale?
Vamos a poner el color en blanco, ¿vale?
¿Veis que no puedo seleccionar?
Si le quito esto, se puede seleccionar el texto.
Y si lo pongo, no se puede seleccionar.
¿Por qué voy a hacer esto?
No lo hago por nada y normalmente os digo que es una mala práctica hacer esto.
Esto lo vamos a hacer porque cuando normalmente se trabaja con un drag and drop, ¿qué es lo que pasa?
Que claro, el drag and drop, cuando tú arrastras algo, seguro que te ha pasado.
Seguro que te ha pasado alguna vez.
Que tú has hecho el drag and drop en una página web y empiezas a seleccionar todo el texto como si no hubiera un mañana.
Entonces, para evitar eso, lo que deberías hacer es poner el user select en aquellos sitios
donde se vaya a trabajar con el drag and drop, ¿vale?
Así que si alguna vez ves este error vas a decir, eso es que no has utilizado el user select, ¿vale?
Por eso lo hago.
Pero luego, lo ideal no sería ponerlo a todo el body, sino ponerlo en esos sitios en concreto que vale la pena.
Pero en nuestro caso, como la aplicación, no va a tener texto, sino que va a ser solo eso.
Por eso lo hago, ¿vale?
Ahí lo tendríamos.
Vale, pues con esto al menos ya tenemos una parte.
Vamos a ponernos con el tier, ¿vale?
El tier.
A ver, para los primeros estilos.
Ah, los primeros estilos.
Me voy a copiar, a ver dónde tengo por aquí.
Vale, me voy a copiar una cosa.
Y es que fijaos que en el tier list tenemos aquí como diferentes niveles.
Que este es de color rojo, esto es como naranja, amarillo, más amarillo, verde, ¿vale?
Pues he recopilado, para no tener que hacerlo delante tuyo, aunque es muy fácil hacerlo.
O sea, tampoco es nada del otro mundo.
He recopilado ya los colores en variables de CSS.
¿Cómo lo he hecho?
Para que lo sepas rápidamente.
He ido aquí, ¿vale?
Que he visto que aquí estaba el colorcito.
Le he dado a inspeccionar.
Y ves aquí...
Bueno, no sé si lo ves porque igual estoy yo encima.
A ver, ¿estoy encima o no estoy encima?
Vale, ¿ves aquí que está el color?
Vale, pues le he dado.
Y aquí aparece el color.
Pero este color, como es RGB, es un poco complicado.
Entonces, le voy a poner en hexadecimal.
¡Pum!
Y ahora aquí ya tengo el hexadecimal.
Y luego, para sacar todos y cada uno, le he dado a este y le he dado al colorcito.
¡Pum!
Y me ha aparecido.
Y luego al siguiente.
¡Pum!
Y esto lo he repetido hasta que he tenido todos los colores y los he puesto cada uno en una custom property.
Aprovechando que también tenés esto, vamos a poner un poco de reset de CSS para que el box sizing no nos moleste, ¿vale?
El box sizing este, el poner border box, es para que si...
Bueno, es que esto ya lo he explicado muchas veces, no quiero repetirme.
Pero básicamente, esto lo que te ayuda es a que, como se calcula el ancho y alto de tus cajas, tenga en cuenta el padding.
Porque si no, es un jaleo.
Es un jaleo.
Tengo un vídeo en YouTube donde te lo explico.
Pero normalmente esto ya te lo añade Tailwind o muchos frameworks automáticamente y por eso no te das cuenta.
Y también vamos a resetear los botones, que más adelante, pues esto lo vamos a necesitar.
Vamos a poner botones transparentes, sin borde y también color esto y cursor pointer y ya está.
Luego haremos los botones, ¿vale?
Vale, pues vamos a crear el HTML mínimo, ¿vale?
El HTML mínimo vamos a tener dentro del tier, que podríamos poner que esto es un section.
Vamos a poner un section aquí, ¿vale?
Dentro de cada uno...
Olvide poner el mensaje.
Cara sonriendo con sudor frío.
Buen día, Midu.
Emocionado por este proyecto.
Se ve interesante.
Además, súper vayas a estar en Colombia.
Me alegro.
Ahí nos vemos.
En Colombia nos vemos.
Vale, pues vamos a poner aquí, por ejemplo, la S, ¿vale?
La S.
Ahí tenemos la S.
Ahora, el label, ahora lo estilaremos.
Pero el label, una cosa interesante que vamos a poder hacer es que le podamos cambiar porque no siempre quieres que ponga S.
Entonces, lo que puedes hacer aquí es decir que esto sea content editable y ponerlo a true.
Y entonces, puedes hacer un clic y cambiar lo que tú quieras, ¿vale?
Esto luego lo veremos.
Mira, ahora se me ha quedado el...
Esto lo odio.
Lo odio porque cuando se me pone esa selección no lo puedo quitar.
Bueno, pero luego lo arreglo.
Ahora os enseñaré mejor eso, cómo se puede hacer.
Pero tú a cualquier cosa le pones un content editable y ya puedes escribir lo que te dé la gana.
No sé si lo sabías, pero está bastante chulo.
Entonces, vamos a tener el de la S.
Bueno, voy a hacer solo la S primero.
Estilo la S y así luego vemos cómo quedan todos.
Vámonos a los estilos.
En cada tier vamos a poner que esto tiene un borde de color así como oscurito.
Igual un poco oscurito.
A ver si lo ponemos blanco.
¿En qué color?
O sea, es que no se ve.
A ver.
Ah, claro.
Es que a lo mejor tiene que ser algo más así.
Vale.
Pues lo ponemos así.
Le ponemos un display flex.
Vale.
Esto aquí es la letra que ahora tendrá cada uno en color.
No te preocupes.
Y un flex direction column.
¿Vale?
Porque va a ser de arriba a abajo los niveles.
Y le vamos a poner un background para que se vea un poquito más, a ver, diferente.
Vale.
Algo así me parece perfecto.
Y ahora cada una de las filas.
Y cada una de las filas, pues de nuevo, display flex.
La fila sería, o sea, el tier serían todos los niveles y la fila sería un nivel.
Le he puesto row, pero podríamos haberle llamado level.
Bueno, row está bien.
¿Vale?
Le ponemos row.
Y aquí la dirección va a ser en filas.
O sea, va a ser, no va a ser de arriba a abajo, sino que sería de izquierda a derecha.
¿Vale?
Las vamos a estar apilando de izquierda a derecha.
¿Por qué?
Porque es a la derecha de esta letra donde vamos a tener las imágenes del tier list.
Y debajo de cada nivel vamos a ponerle una pequeña separación.
Vamos a ponerlo, a ver, el 1, 1, ¿cómo queda?
Vale.
Perfecto.
Más o menos.
Y vamos a, bueno, las transiciones las ponemos después.
Lo importante es que con todo esto vamos a poder estirar el label.
Y así ahora lo verás mucho mejor.
Vamos a ponerle un cursor pointer para que ahí se note que le puede hacer clic para cambiarle el texto.
Y vamos a poner que tenga un background.
Ahora le podría poner que el background sea el del color, la color ese.
¿Vale?
Y ves que ya queda así.
¿Vale?
Esto tiene que tener el color oscuro para que quede como esto.
Vamos a poner que esto sea una negrita.
Esto que quede así como cuadrado.
¿Vale?
Display flex.
Para que se centre todo.
Center.
Justify content center.
¿Vale?
Ya empieza a quedar ahí.
Ya empieza a verse un poquito esto.
Y cuando le das un clic, ¿ves que hace eso?
Voy a intentar que cuando está el span, está con focus, el outline sea diferente porque queda un poco raro ese que te pone por defecto.
Vale.
Yo creo que así mejor.
¿Vale?
Y se podrá cambiar.
Esto básicamente estará bien porque podrás poner...
Ah, bueno.
No sé por qué.
Pero a ver.
Aquí.
Aquí.
Podrás poner un fueguecito, por ejemplo.
Fire.
¿Vale?
Y lo que tú quieras.
Entonces puede quedar bastante bonito.
Vale.
Pues tenemos la S.
Ahora que tenemos la S, lo que deberíamos hacer aquí sería poner todos, ¿no?
Pero antes, ¿qué pasa?
Que el background va a cambiar para cada letra.
El tema es que aquí muchas veces la gente...
Imaginad que tenemos ahora cinco niveles y cada nivel es un color diferente, ¿no?
Entonces, lo que podría ocurrir aquí es que la gente lo que normalmente hace es crear una clase para cada uno, ¿no?
O sea, para el nivel S, la clase S, no sé qué, no hagas eso.
Utiliza custom properties para eso, ¿vale?
Por ejemplo, o sea, lo que digo es que mucha gente haría, vale, para el label que tiene el level S, entonces el background es de color rojo.
Esto está mal.
O sea, no hagáis esto, no hagáis esto.
Que esto ahora, hoy en día, ya no es necesario.
Mirad, lo que se puede hacer, lo que se puede hacer es decir, oye, esta el label tiene un background que va a ser del color de la custom property level.
Y por defecto le puedes poner el color que tú quieras, ¿vale?
De forma que si esta custom property no existe, pues va a recuperar por defecto este valor de aquí, ¿vale?
Pero una vez que has hecho esto, y esto es lo más maravilloso que tienen las custom properties,
es que tú vas aquí y le pones style y le dices que esto, el level, es del valor color S.
¡Hola! ¿Qué ha pasado?
Está guapísimo.
Está guapísimo.
Está muy guapo.
Y aquí también podríamos empezar a hacer esto, ¿no?
Con la A, y aquí le ponemos la A, ¿vale?
Esto está chulísimo, porque ahora, sin haber escrito ni una línea de CSS más,
sino que simplemente estamos utilizando las que ya tenemos...
Esto nos lo enseña en cualquier sitio, ¿verdad?
¿Ah? ¿Qué pasa? ¿Qué pasa?
¿Dónde está vuestro dios ahora?
¿Eh?
¿Esto qué? ¿Os lo ha enseñado algún streamer?
¿Te ha enseñado el PrimeHin ese?
¿Eh? ¿Eh?
Es broma, hombre, que el PrimeHin me encanta.
Pero ahora os lo explico, ahora os lo explico, que está muy chulo.
El tema es, es que estas cosas solo, una la aprende después de trabajar muchos años con CSS.
Bueno, con CSS, que es Custom Property y ya tiene un tiempo, ¿eh?
Pero que es verdad que esto yo no lo he visto mucho de que la gente lo explique.
A ver, que a lo mejor ahora me está viendo alguien y dice,
¡Ah, eso es una tontería, ya lo sabía!
Bueno, obviamente, es una parte del...
Es algo del...
De CSS de hace mucho, mucho tiempo.
Entonces es normal que lo pudiera saber.
Pero no lo sabe tanta gente.
Porque la verdad es que es una cosa...
Vale.
Ah, el color, ¿eh?
No lo tengo.
Ah, fíjate, el color, ¿eh?
Ah, sí, sí que está aquí.
Entonces, ¿por qué me está pillando el por defecto?
Color, ¿eh?
Ah, porque he copiado esto dos veces.
Vale, ya lo tendríamos, ¿eh?
Eso ya lo hacía Python hace tiempo, ¿eh?
Técnicamente es una pasada, pero meter estilos en línea no me gusta mucho.
Sí y no, pero te voy a explicar por qué meter estilos en línea aquí puede tener bastante sentido, ¿no?
El tema es que en estos casos, pensad que este caso, yo porque ahora lo estoy haciendo así.
Pero el tema es que sería muy bonito que todos estos colores fuesen personalizables, ¿vale?
Y que los puedas cambiar y tal.
Y entonces a lo mejor, pues a veces puede tener sentido hacerlo de ese estilo en línea.
Pero lo que yo creo que es peor, aunque sé que la gente dice, ah, es que es estilo en línea,
pero la verdad es que está bien porque lo que estás haciendo en realidad es cambiarle el valor a una variable.
O sea, como tal no es un estilo en línea, sino es redefinir el valor de una variable.
Lo cual es una cosa que es todo diferente, ¿no?
El error o lo que yo veo muchas veces que la gente hace, que se vuelve un poco loca a veces,
es el hecho de poner aquí label y que además, pues esto le dice label s.
Entonces se tiene que crear como muchas clases para hacer esto, ¿no?
¿Están los colores al revés?
No, no, están bien.
Bueno, esto es porque están los colores muertos, ¿no?
Pero a ver.
El amarillo.
No, están bien.
Me falta la f, pero bueno, la f no la he puesto.
Da igual.
Estos son los más típicos.
Entonces, ¿qué es lo que hace aquí?
Lo que estamos haciendo aquí es que la variable level la estamos redefiniendo a nivel de este elemento solo.
Por eso solo afecta a este elemento.
Y le estamos diciendo que este elemento tome el valor de color s, que es otra variable que tenemos.
Es como si yo al level le dijese, este tiene que ser 0,9f, ¿no?
Y este tiene que ser, pues, otro color, ¿no?
Y lo que estamos haciendo es redefiniendo la variable a cada nivel de ese elemento.
Entonces, por eso vemos colores distintos.
Y esto es muy interesante porque, por ejemplo, si lo comparáis con SAS, SAS no lo podéis hacer esto.
Porque en SAS las variables son estáticas.
En cambio, aquí las variables se pueden redefinir en tiempo de ejecución.
Lo cual es tremendo.
O sea, es genial, ¿eh?
Las custom properties indiscutiblemente son la repera, pero tampoco llamaría error a usar BEM.
Primero, es que no he hablado de BEM para nada.
O sea, no estoy hablando de BEM.
Eso es lo primero.
Lo que estoy diciendo, y lo segundo es que tampoco he dicho que sea un error.
Como tal.
Digo que mucha gente se vuelve loca poniendo label, punto, label, punto, level 1.
Y esto no es BEM.
Esto, BEM, no he dicho nada de BEM.
Y entonces es poner esto, ¿vale?
Label, punto, level, ah.
Y hacer background o no sé qué.
Porque esto no es que esté bien o que esté mal o que no sé qué.
Es que fíjate que aquí lo que estás haciendo en realidad es, primero, crear otra clase.
Y entonces tienes que poner la clase.
Y segundo, que en realidad estás sobrescribiendo la propiedad background.
No estás sobrescribiendo la variable.
O sea, fíjate la diferencia.
Aquí estamos sobrescribiendo la variable y queda como más declarativo el cómo utilizar el background solo una vez.
En cambio, aquí lo que estás haciendo es redefinir el valor de background, ¿vale?
Que es una cosa distinta.
Y esto lo tendrías que repetir, pues así, ¿vale?
Tantas veces como niveles tengas.
Lo cual, pues a mí la verdad, entre esto, que creo que queda bastante bien y que queda bastante cerca,
a tener que hacer esto, que además te empieza a generar cascada,
porque ya tú no tienes la visibilidad de que realmente este nivel, si tiene más prioridad que el otro y tal.
Pero bueno, que si no os gusta, hacedlo como os dé la gana.
Yo digo que este y ya está.
¿Y dónde se define level?
Lo tenéis aquí.
Level está aquí definido.
Que ya estamos definiendo la variable level y le estamos dando por defecto este valor.
Cuando la usamos, la definimos a la vez, ¿vale?
Se hace en el mismo momento.
Vale, pues venga, aquí ya tenemos esto.
Vamos a continuar.
¿Qué tendríamos que hacer primero?
De todo lo que hemos hecho, los botones...
Vale, tengo que añadir unos botones aquí abajo, ¿vale?
Lo hacemos un momento porque...
Vamos a poner aquí selector.
Necesitamos un sitio donde vamos a definir...
Vamos a poner aquí la sección que van a ser los botones.
Vamos a tener un sitio donde vamos a tener, por ejemplo, aquí un botón que sea para...
Bueno, más que un botón...
Mira, vamos a hacer otro truco.
Mira, voy a explicar otro truco.
Que esto también me lo hacéis mucho y vais a ver.
Me voy a ir a Tablet Icons.
Un momento.
Tablet Icons.
Y vamos a sacar uno que sea...
¡Ay, no!
Dios, como odio esa página.
Dios mío.
Dios mío.
Odio a esa persona.
Odio a esa persona.
¿Input?
No.
¿Add?
No sé.
Bueno, sí.
Mira, esta me gusta.
Vale, vamos a quitarle...
No, el size está bien.
Lo que hay que quitarle es stroke, ¿vale?
Vale.
Es para añadir la imagen.
Por ejemplo, este, ¿vale?
Este me parece que está bien.
Vamos a ponerlo aquí.
¡Uy!
No me lo ha copiado.
Este.
Copiar aquí.
Vale.
Ponemos esto aquí.
Vale.
Y ahí tenemos este.
Y vamos a poner otro botón que va a ser el de resetear, ¿vale?
Resetear, que no sé.
Sería un do.
A ver si sale...
Hostia.
Dios.
Arrows.
Vale.
Vale.
Este.
Este tiene buena pinta.
Pues este.
Vale.
Y este va a ser Andu.
Vale.
Este botón lo vamos a utilizar para que podamos añadir imágenes.
Que luego lo vamos a hacer con drag and drop.
O sea, lo vamos a hacer arrastrando.
Pero por ahora voy a añadir un botón, ¿vale?
Y aquí vamos a poner selector items.
Aquí es donde vamos a poner los items.
Ahora lo estilamos.
El tema es que cuando le demos a click aquí, lo que quiero es que me abra lo típico.
Un input.
Vamos a poner aquí un input type.
Bueno, vamos a poner id image input type file que solo acepte imágenes.
Bueno, eso os lo explicaré ahora.
Hidden.
¿Vale?
Otra cosa que me hacéis mucho, ¿vale?
Veis que tengo aquí un input.
Lo que quiero es que cuando le dé a este botón, cuando le dé a este botón, que le voy a llamar add image button.
Cuando le dé a este botón, quiero abrir el selector de archivos, ¿vale?
En realidad hay un montón de formas de hacer esto, pero os voy a enseñar la que yo creo que es mucho más sencilla.
Para eso necesitamos JavaScript, ¿vale?
Vamos a poner que es de tipo módulo para que se cargue cuando se tiene que cargar.
Vamos a traernos el elemento este, este botón de aquí, add image button, ¿vale?
Este selector, vamos a poner add button, document, query selector, add image button.
Vale.
Este es el error.
No es un error, pero es una cosa innecesaria.
Esto es una cosa que hace mucha gente, ¿vale?
En el que dice, vale, cuando le dé clic a este botón, voy a escuchar el clic.
Y cuando haga clic, voy a simular un clic en el input para que se abra.
Y entonces pasa esto, ¿vale?
Perfecto.
Que ahora se supone que tienes la oportunidad de seleccionar el archivo.
Y vale, está bien, pero es que todo esto no es necesario.
Porque lo que puedes hacer en realidad para simplificar todo esto es utilizar un label, meter aquí el input, ¿vale?
Lo que a lo mejor tenemos que estilar esto correctamente, pero bueno, metes un label, tienes un input, aquí se ve igual, le das un clic y ya está.
Y es lo mismo, es lo mismo.
Bueno, lo mismo.
Faltaría algún tema de accesibilidad aquí para que se entendiese de que este label en realidad hace lo que tiene que hacer, ¿vale?
Tenemos que poner temas de accesibilidad y tal.
Pero en temas de que no necesite JavaScript realmente para que ese botón haga esa magia, ¿vale?
No es necesario.
Es que a veces añadimos JavaScript que no sepa que lo añadimos.
Pero bueno, entiendo que habrá gente que también lo prefiera.
Vamos a estilar esto y así ya tendríamos todos los estilos que necesitamos para avanzar, ¿vale?
El selector, que es la parte de abajo, display flex.
Vamos a hacer que uno esté encima del otro, ¿vale?
Y así quedará un poco más.
Align, item, center.
Center.
Vamos a poner un poquito de separación.
Y un poquito de separación con esto de arriba.
Bueno, igual menos.
Y aquí ahora, selector buttons, ¿vale?
Los dos botones los estiramos un momentito.
Vale, cap 8.
Bueno, yo me voy a ir fiando un poco también de lo que me diga el...
Tampoco espero que sea el mejor diseño del mundo, ¿eh?
Entonces, vamos a estirar el botón y el label.
Y vamos a estirar los dos igual, ¿vale?
Vamos a poner que tenga el cursor pointer.
Voy a añadir esto también.
Que sea...
Que cuando hacemos hover, pues que se escale.
Scale 1.1.
Transition.
All.
3S.
¿Vale?
Vamos a dejar un poquito de espacio.
Bueno, espacio no necesita adentro.
Pues no tenemos ningún tipo de...
¿Qué le podemos poner?
Bueno, le vamos a poner un poquito de background.
Un display flex.
Justify center.
Align center.
With 24.
Vamos a hacer los cuadrados.
Vale.
Lo que me falta es que aquí le suje este.
A ver.
Vale.
Ahora uno de los dos...
Por haber hecho la tontería esta de la cosa esta.
Ahora uno de los dos me está quedando más grande que el otro.
A ver.
¿Por qué me está quedando más grande el otro?
¿Por qué me está quedando uno más grande que el otro?
Tu, tu, tu, tu, tu, tu, tu.
Button.
El label lo estoy estirando bien.
Cursor pointer.
24, 24.
Debe ser una tontería.
A ver.
Vamos a mirarlo aquí.
Un momento.
Vamos a mirarlo aquí.
No quería perder tiempo en los estilos.
Voy a aprovechar para poner un padding de 4 píxeles y hacer un poco más grande esto.
Ah.
Ah.
Ahora sí que me lo está pillando.
O sea.
Que es que ha pillado los estilos tarde.
Claro, el tema es que...
Me ha pillado los estilos tarde.
Ya decía yo que estaba alucinando.
Vale.
Pues ya está.
O sea, está perfecto.
Solo le cambio aquí el background un poquito.
Para que sea más clarito.
Y ya está.
Vale.
Vale.
Perfecto.
Pues ya tenemos los botones.
Me faltaría el tema de los items.
¿No?
O sea, cuando tengamos los items aquí debajo.
Voy a poner aquí selector items.
Donde vamos a tener las cards.
Vale.
Le voy a poner un borde para que veamos cómo quedaría.
Vale.
Vamos a poner width 100%.
Vamos a poner una altura de 200 píxeles.
Vale.
Aquí es donde tendremos los items.
Y vamos a ponerle un margin bottom 100 píxeles.
Display flex.
Y iremos poniendo que esté de izquierda a derecha.
O sea, flex.
Bueno, este da igual.
Por ahora lo dejamos así.
Vale.
Vamos a hacer esto un poco más pequeño.
Para que quepan ahí.
Y ya está.
Vale.
Pues ya tengo todos los estilos.
¿Vale?
Ahora sí que ya vamos a ponernos con más JavaScript para añadir las imágenes y entrar.
Pero por ahora alguna pregunta, amigos míos.
Para empezar con el tema del drag and drop y tal.
Si me duele agua por cada vez que diga.
Vale.
Vale.
¿En qué caso se usa la etiqueta picture?
La etiqueta picture se usa para cargar diferentes imágenes.
Diferentes versiones de la imagen.
Picture.
MDN.
Entonces lo que puedes hacer es como para contener diferentes imágenes.
¿Ves?
Picture.
Y entonces dices, vale, cárgame por defecto esta imagen.
Pero en el caso de que el dispositivo tenga esta media query, pues me cargas esta versión.
Y así pues tienes la más pequeña.
Y si es más grande, 600 píxeles, pues cargas una imagen más grande.
Pero también lo puedes hacer incluso para cargar diferentes calidades.
Puedes hacer un montón de cosas.
¿Qué son esos ampersand con los estilos?
Esto, estos ampersand, son para indicar el padre.
O sea, en lugar de escribir, para que te hagas una idea, a ver si tengo un ejemplo sencillo, este.
En lugar de escribir esto, ¿vale?
En lugar de escribir esto, que sería repetir otra vez el código, lo que puedes hacer es utilizar este selector para anidar estilos.
Entonces aquí, esto que hay aquí, sería lo mismo que hay aquí.
Solo que quedaría como más anidado dentro de este y así te refieres a este.
En realidad ahora este es opcional.
Bueno, no es opcional, sino que ahora lo han quitado.
Lo que pasa es que como todavía no está soportado por todos los navegadores, yo lo añado.
Pero la realidad es que ahora se puede utilizar así también, para que lo sepas.
Pero por eso lo hago.
Pero no todos los navegadores lo soportan.
Bueno, esto sí.
A ver, esto sí.
El nested selector lo podemos mirar, pero debe ser.
Si no, casi el 100% el 90 y pico.
Nested, CSS, a ver.
CSS Nesting, 88%.
Bueno, está muy bien.
Ya todos los navegadores modernos lo soportan.
El problemático ha sido Safari, que hasta la 17.1 no lo soportaba.
Pero todos los demás, yo creo que ya lo soportan.
CSS Nesting.
Otra cosa es sin utilizarlo con el Ampersand, que ahí creo que hay todavía menos, para que os sepáis.
Sobre el picture sería para hacer como un if.
Efectivamente, es como hacer un if.
Básicamente es como hacer un if, ¿vale?
Y Midu sube cambios para tener layout base.
Vale, venga, subo los cambios para tener layout base.
Y así lo tenéis.
Add layout base.
Por si queréis seguirlo con el...
Os recuerdo que este proyecto va a ser parte de estos 100 proyectos de JavaScript que estamos haciendo, ¿vale?
Que lo estamos haciendo con solo JavaScript.
HTML, CSS, JavaScript, sin tener ningún tipo de dependencia, ¿vale?
Y que es un repositorio de código abierto donde tenéis todo el código.
Joder, con mis ojos.
Voy a cambiar esto.
Esto es porque tuve que hacer un vídeo y me pedían que saliese en blanco.
Entonces, a ver, aquí.
Pues es un proyecto de código abierto donde estoy subiendo todo el código.
Tenéis el vídeo, tenéis todas las explicaciones.
O sea que si queréis aprender y practicar, aquí lo tenéis todo.
Y si no, podéis entrar directamente en la página y podéis ver los vídeos.
Y os recuerdo que tenemos ya la página web de la MiduConf porque el 12 de septiembre vamos a tener la MiduConf.
Ya 769 personas han conseguido su ticket y que tenemos speakers confirmados.
Vamos a tener a Guillermo Rauch, a Carmen Anzio, vamos a tener a 12SV, Alba Silvente, Peladoner, Fast, Stephanie Aguilar, ¿vale?
Vamos a tener una conferencia.
Y estos son los confirmados, que todavía nos quedan unos cuantos.
Tenemos patrocinadores y vamos a tener un montón de regalos.
Y los regalos, vamos a tener 256 regalos.
Y que para que los podáis conseguir, necesitáis el ticket, que es totalmente gratuito, ¿vale?
No tenéis que pagar absolutamente nada, ¿vale?
O sea, el ticket es gratis, gratis 100%.
Le dais a conseguir mi ticket, creo que iniciéis sesión con GitHub.
Y aquí lo podéis además personalizar como queráis.
Le podéis decir, me gusta CSS, ¿vale?
Y lo compartís, decís, oh, me encanta CSS, ¿vale?
Y aquí, pues, la gente podrá ver.
En este caso, se ha quedado cacheado por esto.
No sé por qué, porque es una cosa de Twitter que cachea la imagen.
Pero, en realidad, el vuestro sea el de CSS, ¿vale?
Así que ahí lo tendrás.
Guillermo nos dará charla de cómo ser un CEO exitoso.
Bueno, vamos a hablar de un montón de cosas.
De cosas de Vercell, de Mundo de la Programación, de un montón de cosas.
Así que, nada, no te preocupes, que también le preguntaremos también sobre eso.
Mira, 835, muchas gracias.
Y compartidlo, compartidlo con vuestros amigos, hombre, que se apunten.
Muy bien, pues, venga, vamos a continuar, que hay mucha tela que cortar,
muchas cosas que hacer y se nos va a tirar el tiempo encima y no quiero.
Venga, vamos a empezar con el JavaScript.
Yo voy a crear, yo, porque a mí me gusta, voy a crear una utilidad que le llamo miduquery, ¿vale?
El miduquery le puedes pasar el elemento y te lo devuelve.
Y también puedes hacer esto, ¿vale?
Para tener aquí el selector y devolver todos estos elementos.
¿Para qué sirve esto?
Esto es para no tener que escribir todo el rato esto.
En lugar de tener que escribir document.querySelector todo el rato,
lo que hago es crear esta función y ahora puedo decirle el imageInput, ¿vale?
Pues, imageInput, ¿vale?
Y ya está.
SelectorItemSection, ¿vale?
Pues hago el selectorItems, ¿vale?
Y ya está.
Y ahora sí no tengo que estar repitiendo todo el rato.
Es como un GQuery, pero mucho más sencillo, ¿vale?
Entonces, ahora con esto voy a poder detectar cuando cada vez que el input de la imagen que hemos creado aquí,
que aunque esté oculto, aparece, ¿vale?
Que está aquí, este input, cuando carguemos una imagen, vamos a poder detectarlo.
Vamos a decir, vale, pues cada vez que haya un cambio, vamos a hacer algo.
Vamos a hacer algo cada vez que exista un cambio.
Esto levanta un evento y del evento podemos recuperar todos los archivos.
En este caso, solo vamos a recuperar un archivo, ¿vale?
Vamos a poner aquí file.
Con este file, si tenemos un file, porque a veces a lo mejor no hay ningún file,
porque se cancela por lo que sea.
Esto es una cosa que es pura de JavaScript.
Y es que podéis crear con el objeto FileReader un lector, ¿vale?
Esto es una API de JavaScript en la que podéis leer, podéis decirle,
quiero que leas el archivo que se ha cargado como si fuese un data URL.
Esto es lo que nos va a permitir que cuando se seleccione una imagen, ¿vale?
Podamos aquí mostrar esa imagen.
Entonces, creamos el reader y vamos a decirle que el archivo que hemos seleccionado
nos lo cargue como un data URL para poder mostrarlo.
Y aquí vamos a poner un reader cuando se cargue el archivo que hemos cargado.
Vamos a recuperar aquí otro evento más, ¿vale?
Vamos a poner aquí event file, ¿vale?
Para que no lo complique, o event reader, para que no se confunda con el de fuera.
Y aquí vamos a tener ya el image element.
Vamos a crear un elemento imagen, ¿vale?
Con un document.creditelement.
Esto se podría crear de diferentes formas.
Lo podríais crear como si fuese HTML directamente y apuntar a HTML.
Pero yo creo que esta es la forma más performante, la que tiene mejor rendimiento.
Le diríamos, ¿vale?
El elemento source es del event reader punto target punto result.
Esto lo podríamos hacer así.
¿Del result?
Es que estoy pensando el result.
Estoy pensando el result.
¿Dónde deberíamos sacar?
O sea, target.
Sí, vale.
Porque hemos dicho que lo queremos leer como data URL.
Entonces, este event reader, lo vamos a...
Voy a poner un console.log para asegurarme, pero estoy bastante seguro que lo vamos a sacar así.
O sea, creo que cuando lo carguemos vamos a tener la imagen ya como parseada para ponerla en el atributo source.
O sea, estoy bastante seguro de esto.
Si no, ahora pues veremos si me equivoco o si no, pues que pete.
Y ya está.
Y vamos a poner que el elemento tenga un class name.
Esto más que nada para que nos ayude a estilarlo.
Class name, vamos a poner image, item, image, ¿vale?
Y solo nos faltaría ya añadir esta imagen que hemos creado, ¿vale?
Vamos a en el items section, append child, image element.
Y ya está.
Con esto ya tendríamos...
Podríamos...
Bueno, no podemos devolver.
Iba a decir, podemos devolver aquí la imagen, pero en realidad no tiene sentido devolverla.
Vale.
Esto debería funcionar.
Pero esto lo que debería hacer es que ahora cuando yo le dé un clic aquí y si...
A ver, un momento que no enseñe información confidencial.
Un momento.
Desktop.
Vale.
Vamos a poner esto aquí, esto aquí, esto aquí.
Vale.
A ver si ahora abre...
Vale, perfecto.
Vale, pues aquí.
Vale, pues le damos aquí.
Y ahora me va a decir que seleccione la imagen, ¿vale?
Aquí tengo diferentes imágenes.
Le voy a dar un clic aquí y ¡pum!
Bueno, más o menos.
Casi.
Casi.
No es...
O sea, la imagen ha aparecido, pero ha aparecido un poco raro.
Eso es un tema de estilos que ahora arreglaremos, ¿vale?
Vamos a mirarlo aquí un momento.
A ver si aquí...
A ver, vamos a hacer esto un poco más pequeño.
Vamos a darle aquí.
Vamos a darle tier languages.
Vamos a poner angular, open.
Bien, vale.
Y aquí puedes ver que la imagen, cargarla, la ha cargado.
Aquí está lo que te comentaba.
¿Ves el console.log que decía que iba a ser el data para que lo podamos utilizar ya directamente?
Esto es porque ha leído la imagen de forma binaria y la ha transformado en una cadena de texto
que tú puedas renderizar en una etiqueta imagen en HTML.
Lo puedes poner en el source, el data image, y entonces aparece la imagen ahí como si nada.
Pero esta imagen es la que hemos leído en nuestro ordenador.
Ahora, lo que deberíamos arreglar es que no aparecen correctamente los...
O sea, no aparece bien...
A ver, aquí en los estilos...
Ah, y espérate.
Podría también cargar otro.
Vale, aquí vemos que se cargan regulinchis, ¿vale?
Se cargan regulinchis.
Pero ahora le vamos a cambiar un poco los estilos para ver...
Selector items...
Selector items...
Y en selector items, a ver, lo que podríamos hacer...
Ah, más que selector items, lo que deberíamos a mejor es los estilos de cada...
Claro, claro.
Porque luego lo vamos a editar.
A ver, vamos aquí arriba.
¿Cómo lo hemos llamado?
Item image.
Item image.
Y aquí, pues, 100...
¿Cuánto hemos dicho?
50.
Vale, pues 50 píxeles.
50 píxeles.
Espérate, que hago esto un poquito más grande.
50 píxeles.
Altura, 50 píxeles.
Vamos a poner un object fit cover.
Porque seguramente, aunque yo lo haga cuadrado, puede ser que no todas sean cuadradas y que sea un poco rara.
Y con esto ahora sí que deberíamos poder cargar angular.
Y ahora sí que van empezando a salir ahí una detrás de otra, ¿vale?
Ahora, todavía esto no funciona, pero eso lo hacemos ahora, ¿vale?
Claro, si tengo una imagen...
No sé si tengo alguna imagen que sea transparente.
Pero por si acaso le voy a poner un background blanco.
Por si hay una imagen transparente que se vea.
Y le voy a poner el cursor grab para que la gente sepa cuando entre que se puede mover, ¿vale?
Ahora todavía no se mueve.
O sea, sí que se puede mover porque se ve que se mueve.
Pero no funciona bien del todo, ¿vale?
Pero al menos así que se vea la manita para que se entienda que vamos a poder arrastrarlo allá donde queramos, ¿vale?
Voy a hacer esto.
A lo mejor lo podría hacer así de pequeñito para que se vea que está ahí.
Os leo un momento y empezamos ya con el drag and drop que está bastante interesante ahí.
Esto funciona, ¿son importar que sean de otras dimensiones?
Sí, no habría ningún problema de las dimensiones si no tienen ningún tipo de complejidad.
¿El queries de Torol tiene un bug?
Ah, vale.
Como no he utilizado todavía...
Ah, pues mira, tienes razón.
Gracias.
¿Por qué no usas Web Components?
Porque tendría que ponerme a explicar los Web Components también y quería dedicarme a enseñar esto.
Pero igualmente uno de los proyectos que vamos a hacer va a ser crear un Web Component.
Así que ahí lo tendríamos.
Si yo hago el proyecto entero utilizando Web Components, tengo que explicar los Web Components.
Y yo siempre prefiero...
Yo sé que vosotros tenéis muchas ideas de...
¿Por qué no utilizas TypeScript?
¿Por qué no utilizas TypeScript?
Pero es que al final la idea es intentar enfocarse en un concepto en concreto y no ponerse a juntar un montón de conceptos.
Si yo me pongo a explicar los Web Components con la drag and drop, con un montón de cosas, al final como se diluye un montón lo que quieres explicar.
Entonces de Web Components haremos también uno para los proyectos, pero que esté pensado para un Web Component que sea reutilizable.
Porque en este caso además no es una cosa que vaya a ser reutilizable y tal.
Así que no te preocupes que explicaremos los Web Components.
Vale, pues venga, vamos a añadir el drag and drop.
Ahora que ya tenemos esto.
Luego además, ¿sabéis lo que haremos?
Porque fijaos que ahora, ¿veis que se puede seleccionar un archivo .zip?
Pues esto es súper fácil de arreglar porque le podéis poner aquí el atributo accept y le decís que acepte solo todas las imágenes.
Y fijaos la diferencia que ahora ya no me deja seleccionar este archivo .zip ni este .pdf, este pdf que le pasé a Ibai.
O sea, porque es del informe de la velada.
Pues ahora solo te permite seleccionar imágenes.
Incluso le puedes decir que solo aceptes pngs.
Y fíjate que ahora este que era un jpeg ya no lo puedes seleccionar.
O que solo sea en jpeg y tal.
Pero bueno, vamos a decir todas las imágenes.
¿Vale?
Vale.
Ahora, vámonos a drag and drop.
Drag and drop.
A ver.
Lo primero es que vamos a tener que indicarle que la imagen, la imagen que carguemos aquí, esta imagen, se tiene que poder arrastrar.
Para activar la API de drag and drop, le vamos a tener que indicar aquí, cuando hemos creado esto, le decimos imageelement.dragable.
¿Vale?
Esto es una propiedad que tienen los elementos en el DOM que nos permite indicar si se puede arrastrar ese elemento, si es arrastrable.
Y vamos también a indicarle dos funciones que vamos a poder escuchar ahora.
Igual que podemos escuchar el click, igual que podemos escuchar un montón de cosas, lo que vamos a hacer ahora es escuchar también, vamos a hacer imageelement, ATV en listener y vamos a poner drag start.
O sea, cuando se inicie el arrastre, vamos a poner handle drag start y cuando termine el arrastre.
Así que cuando termine es el evento drag end.
Vamos a poner handle drag end.
Y ahora con esto, solo con esto ya podemos aquí, vamos a crear dos variables que nos ayuden.
El dragged element, que por ahora será null.
Y por otro lado, no, es dragging no, el source container, para saber desde dónde estamos arrastrando.
Ahora, vamos a empezar a crear nuestras funciones, handle drag start.
Esta función es la que se llamará cuando empecemos a arrastrar esta imagen.
Esto recibe un evento que va a tener diferente información.
Vamos a tener el elemento que estamos moviendo, que está en event.target.
Esto es, el target es qué elemento es el que está emitiendo este evento o el que estamos arrastrando en este caso.
Y por otro lado, podríamos, ahora que ya tenemos el elemento que estamos arrastrando, podríamos recuperar el padre.
Y el padre sería el source container.
Desde qué sitio lo estamos arrastrando.
Y esto es interesante, ¿por qué?
Porque vamos a querer saber si lo estamos arrastrando aquí, de aquí, de aquí, de lo que sea.
Pero vamos a poner por ahora aquí un console log, con el drag start, y vamos a poner aquí event.target.
Y function handle drag end, cuando terminemos de arrastrar.
¿Qué es lo que vamos a hacer cuando terminemos de arrastrar?
Bueno, pues vamos a quitar el drag element null, porque ya no lo estamos arrastrando.
Ya no es drag, ya se acabó, ya no lo estamos arrastrando.
Y también el source container también sería null.
Vamos a poner aquí un console log, vamos a decir que ha terminado, y el evento, cuál es el elemento que hemos arrastrado.
¿Vale?
Entonces, con esto, vámonos aquí, vamos a seleccionar una imagen, vámonos a la consola.
Bueno, eso es un console log que se me ha quedado por ahí.
A ver, console log, este de aquí.
Ah, luego lo quito, porque si no ahora se me reinicia.
Y al moverlo, fíjate, que me ha puesto la consola drag start, y si ahora suelto, drag end.
¿Vale? Drag start, drag end.
¿Ves? Fíjate.
En este caso, cuando yo lo arrastro, vuelve al principio, porque yo tampoco le he indicado que tiene que terminar en cualquier otro sitio.
Pero solo con esto, puro JavaScript, ya estamos como controlando cuando estamos empezando a arrastrar y cuando lo estamos soltando.
Cuando termina, y me está diciendo qué elemento es el que, o sea, qué elemento es el que hemos estado arrastrando.
Fijaos que ha detectado que esta es la imagen, o sea, este es el elemento que he empezado a arrastrar.
Si me pongo encima, pues me está diciendo eso.
Así que esto está funcionando correctamente, vamos a quitar este console log, que no es muy útil, pero al menos ya estamos controlando cuando lo estamos arrastrando.
Ahora, lo que vamos a querer realmente es poder arrastrar esa imagen en uno de los niveles y que se quede en ese nivel.
O sea, necesitamos que se mantenga la imagen en el nivel que arrastremos.
Vamos a hacer una cosa antes de poder hacer esto, porque nos va a simplificar la vida.
Vamos a extraer esta lógica de aquí a una función que le vamos a llamar createItem, ¿vale?
Donde le pasamos el source y aquí vamos a hacer todo esto que hemos hecho aquí.
Vamos a ponerlo aquí y devolvemos el imageElement que hemos creado.
Lo importante es que este source que ahora estamos sacando de eventReader.target, esto va a venir del parámetro source.
Y aquí, en lugar de hacer todo esto, vamos a hacer el createItem de eventReader.target.resolve, que ahí es donde tenemos el source.
¿Por qué vamos a hacer esto?
Porque vamos a necesitar recrear la imagen en el sitio donde queremos que se quede en el nivel, ¿vale?
Entonces, vamos a poner este createItem, simplificamos este código un poquito y así podremos utilizar este nuevo método.
¿Dónde utilizamos el nuevo método?
Aquí y luego cuando vayamos a soltar el elemento en algún sitio.
Pero para detectar que estamos soltando ese elemento en algún sitio, vamos ahora a utilizar la otra parte del drag and drop.
O sea, tenemos el drag, que sería como el arrastrar, y el drop sería el soltar.
Fíjate que por ahora lo único que estamos escuchando aquí es cuándo empieza el arrastre y cuándo termina.
Pero no estamos como detectando cuándo lo soltamos y dónde lo soltamos.
Para eso, lo que vamos a hacer, vamos a hacerlo aquí mismo, luego ya lo haré mejor.
Vamos a recuperar todas las filas.
Todo lo que hay en el tier tenemos un row, que sería todo este HTML que tenemos aquí, a ver si tengo aquí abajo, perdón, aquí, ¿vale?
Dentro de tier tenemos row, que es donde tiene el nivel, otro row, otro row, o sea, todas las filas.
Estos serían todas las filas.
Pues vamos a detectar cada vez que se suelta el elemento en cada una de estas filas.
Así que vamos a ir por aquí, vamos a detectar cada row, y aquí, para todos los rows, para cada uno, vamos a escuchar el evento de drag start, no, inteligencia artificial, del drop, ¿vale?
Vamos a tener handle drop.
Lo mismo, row, ATV listener, drag over, este sí, ¿vale?
Cuando terminemos de arrastrar, cuando terminemos de arrastrar, no, cuando pasemos por encima la imagen.
Y esto es importante, porque cuando pasemos por encima la imagen, vamos a poder hacer una previsualización de la imagen de cómo quedaría, o incluso podríamos estilar esa fila para ver cómo queda.
O podríamos deshabilitar lo que sea, podríamos hacer un montón de cosas.
Y lo mismo deberíamos hacer cuando arrastramos y lo pasamos de largo, ¿vale?
Cuando por lo que sea salimos y ya no estamos arrastrando por encima.
Y así podremos volver para atrás.
Entonces, creamos las funciones que nos ayudan para estos eventos, el handle drop, aquí tenemos el evento, el function handle drag over, cuando pasamos por encima.
Y esto cuando dejamos de estar arrastrando encima, ¿vale?
Cuando nos vamos del arrastre.
Tenemos estos tres eventos que son los que vamos a tener que implementar para hacer la magia.
Así que vamos aquí al handle drop.
Lo primero que vamos a hacer es hacer un preview en default, porque no necesitamos que haga el comportamiento por defecto.
Y lo que podemos es recuperar del evento, podemos recuperar cuál es el elemento que está iniciando este evento.
Y además, la transferencia de los datos, o sea, qué datos se están transfiriendo.
Esto lo vamos a ver después, porque ahora mismo no es necesario.
Pero lo que podríamos es recuperar qué datos estamos transfiriendo cuando estamos haciendo ese drag.
Podremos hacer ahí lo que queramos.
Podemos transferir un JSON, un elemento, una imagen.
O sea, podemos transferir lo que queramos.
Por ahora, no es necesario, o sea, no necesitamos hacer esto del data transfer, porque el data transfer lo tenemos que iniciar en otro sitio.
O sea, tenemos que decirle qué es lo que quiere transferir.
Qué es lo que quiere transferir.
Bueno, os lo voy a poner en un console.log para que lo veamos y luego lo hacemos.
Al menos para que veáis ahí el...
Y podemos decirle cómo queremos recuperar los datos, como un texto plano, lo que sea.
De hecho, podemos ver esto ya.
O sea, que vamos a darle aquí, vamos a darle acá.
Aquí tenemos el drag start, suelto.
Vale, y me ha dejado fatal.
Handle drop, console.log, etc.
Pero esto sí que lo he hecho, ¿no?
Handle drop sí que debería...
A ver.
A ver, aquí nos debería aparecer el handle drop.
A ver si ahora...
Es que a veces me lo deja...
Vale, igual me equivocan algo.
Ahora lo miro.
Mientras os leo.
¿Qué hace?
Está redeclarando la variable.
No dará error.
En la 195 estoy redeclarando.
Handle drag start.
¿Cuál?
Aquí no.
Pero esta función no es...
Se llama diferente, ¿no?
Se llama diferente.
Está declarando dos veces source container, una como let y otra como const.
A ver, source container.
Vale.
Esto está mal, pero igualmente esto no debería ser, ¿eh?
Esto no debería ser.
Esto...
Vale.
Ahora esto ya está...
Esto está arreglado.
Igualmente el handle drop.
A ver, drop.
Esto está bien.
¿Por qué no me está entrando aquí?
Falta...
Sí.
Confetti al soltar un elemento del tier.
Lo haremos después.
Lucas CK.
¿Hace un canal de short?
Sí.
Me ha dejado fatal.
Sí.
Totalmente.
¿Debería validar que es una imagen en JavaScript?
No.
En este caso, no porque no te va a dejar seleccionar, ¿eh?
No te va a dejar seleccionar.
Claro, debería hacer el data transfer, pero es que aunque el data transfer lo haga...
O sea, en el drag start, el drag start aquí debería hacer el data transfer.
Pero el drop debería funcionar igualmente, ¿no?
O sea, aquí cuando empezamos el drag deberíamos decirle que queremos transferir los datos y decirle los datos que queremos transferir.
Pero el tema es que pensaba que íbamos a poder ver qué es lo que transfería por defecto o lo que sea.
Pero ya veo que no.
Aquí cuando hacemos el handle drag start, le tenemos que indicar cuando empezamos a arrastrar el archivo,
le tendríamos que transferir los datos que queremos poder acceder cuando hacemos el drop.
Pero pensaba que aún así, no sé si es que está petando y no aparece, pero aún así podría salir un error.
O sea, o es que si no transfieres datos es que no hace el drop directamente.
Esto sería interesante, no tenía ni idea.
Pensaba que el drop, aún así el evento...
No, ¿ves?
¿Ves?
No lo está haciendo igualmente.
O sea, este handle drop no me está funcionando y no es por eso, ¿eh?
¿Es por el prevent default?
¿Es por el prevent default?
¿Tú crees?
¿Handle drop?
¿Puede ser?
A lo mejor es que no he editado el prevent default.
A ver, no creo que sea el prevent default, la verdad, porque debería...
A ver, drag over para cada uno.
Ah, espérate, si estoy...
No, esto sí que lo está pillando bien, ¿no?
A ver, espérate, vamos a asegurarnos que estamos metiendo el...
Que estamos metiendo esto bien, ¿vale?
Tenemos el node list, ¿vale?
Y aquí en el for each, esto sí que es el for each.
O sea, esto está pillando bien correctamente esto.
Vamos a pillar el console row.
O sea, que aquí sí que lo está pillando bien.
Cuando tenemos aquí el drop, el drop también lo está haciendo bien, lo que no está...
Puedo quitar esto, ¿eh?
Pero igualmente, lo que no está haciendo aquí cuando...
A ver, tío, el languages...
Cuando suelto aquí, no me lo está pillando.
Me falta alguna tontería, alguna cosa que se me ha olvidado y que no veo, ¿vale?
A ver, esto del input, esto no lo necesitamos.
El create item, esto está bien.
El handle drop, handle drag over, esto está bien.
El leave, esto está bien.
Handle drop, este es el que nos está fallando.
El handle drag start, handle drag start.
Cuando empezamos, ¿vale?
Pues estamos haciendo ya el event data transfer.
Esto también está bien y esto nos está funcionando.
Y el handle drag end, este, cuando terminamos el drag, esto también está bien.
O sea, que lo único que me falta...
A ver si me dais alguna pista.
Debo poner el drop en los containers, no en el HTML.
No, porque esto sí que es en cada uno de ellos, ¿no?
O sea, eso está bien.
El tema es que aunque haga esto...
O sea, pongamos que quito todo esto.
El drop debería estar funcionando, ¿eh?
O sea, esto debería estar funcionando aquí.
Porque aquí, cuando hacemos el drop, cuando estamos soltando y está detectando que la imagen la estamos soltando,
debería funcionar...
A ver...
¿Ves?
No me lo está...
Espérate, si es que...
No, porque el row lo está haciendo bien.
¿Sabes?
O sea, está ahí realmente.
A ver, vamos a hacer otra cosa, porque también entendíamos el drag over.
Entonces, podemos mirar en el drag over si lo está pillando, y no solo por el drop.
El drag over, por ejemplo.
Claro, pero es que entonces no está detectando tampoco el drag over.
Vamos a quitar el prevent default.
El prevent default es necesario en todos.
O sea, que eso lo vamos a dejar porque seguro que esto es necesario.
Luego, lo que podríamos hacer en el drag over, pues nada, lo mismo.
Vamos a pillar el current target del evento.
Vamos a hacer un console log del drag over.
A ver si esto le gusta.
Y esto vamos a hacer aquí también un drag leave.
Y vamos a ver esto.
Un momento.
Cuando tenemos aquí la imagen...
¿Vale?
Drag over sí que lo está haciendo.
Y ahora me está pillando el drag.
Ya sé lo que estaba pasando.
Mira que lo he pensado.
Mira que lo he pensado.
Ya sé lo que ha pasado.
Ya sé lo que ha pasado.
Ya sé lo que ha pasado.
El problema es...
Ay, la madre que me parió.
Mira que lo quería hacer.
Mira que lo quería hacer desde el principio.
No era un F5.
No era un F5.
Ha sido culpa mía.
Es que cuando os he explicado...
Es que esto es lo malo de los directos, amigos.
Esto es lo malo de los directos.
Que uno está explicando y se le olvidan las mierdas.
El tema es...
El tema es...
¿Qué es lo que ha pasado?
El tema es que tengo que hacer un prevent default también cuando estoy haciendo el drag over y el drag leave.
Porque el comportamiento por defecto entonces se ve modificado y ya no va a hacer el drop.
El drop ocurre al final y ya la hemos liado.
Entonces, claro, por eso cuando no estaba haciendo los prevent default en el resto de métodos, ya no estaba detectando el handle drop.
¿Vale?
O sea, ese era el problema.
Ahora fijaos que está funcionando perfectamente.
Pero bueno, de todas estas cosas se aprende, amigos.
¿Ves?
Drop.
Ahí lo tenéis.
De todo se aprende.
De todo se aprende.
Necesitamos hacer el prevent default de todos.
¿Vale?
Así que ya lo sabéis.
Ya lo tenéis.
Y ya no nos pasa más.
Entonces, vamos a quitar este drag start.
¿Vale?
Ya estamos haciendo la transferencia de datos.
O sea que en el drop, ahora sí, vamos a poder acceder a la transferencia de datos.
Así que vamos al handle drop.
¿Vale?
Handle drop.
Esto es por aquí.
Vale.
No sé si alguien me lo había dicho.
Si alguien me lo había dicho, pues nada, lo siento porque no lo he visto.
Pero era un poco tricky, la verdad.
Era un poco tricky.
Y es una cosa que quería hacer desde el principio y se me ha olvidado.
Totalmente.
Entonces, cuando soltamos la imagen, cuando detectemos que lo soltamos, lo primero que vamos a hacer es que si tenemos un source container y tenemos un drag element, ¿vale?
Si realmente tenemos algún elemento de, o sea, tenemos que viene de algún sitio y estamos arrastrando un elemento, lo que vamos a hacer es primero, del elemento original, del contenedor original, vamos a eliminar el elemento, ¿vale?
Vamos a hacer un drag element.
Lo quitamos de ahí.
Y si tenemos un elemento que estamos arrastrando, entonces lo vamos a poner ahora, este image element.
Vamos a crear el item, pero vamos a utilizar, vamos a crear el source.
Lo vamos a traer del data transfer.
Leamos la data que hemos pasado, ¿vale?
Que en este caso va a ser el source, ¿vale?
Va a ser la imagen.
Aquí, como os digo, podéis enviar un objeto JSON.
Podéis enviar elementos enteros.
Podéis enviar lo que queráis.
En este caso solo necesitamos la imagen y, por lo tanto, cuando empezamos el drag, que lo estamos haciendo aquí, estamos transfiriendo como datos el source de la imagen.
Con eso nosotros vamos a tener suficiente, pero a lo mejor quieres enviar un objeto completo.
Lo que sea, ¿no?
Traemos este source, creamos este item aquí y ahora este item ya lo podemos, en el elemento actual donde hemos soltado, vamos a añadir este elemento, image element, que hemos creado con este source.
Solo con esto, si todo ha ido bien, deberíamos empezar a ver que, bueno, no sé por qué lo ha dejado.
Funciona un poco raro.
Funciona un poco raro, pero no sé si es porque hay algo raro con el zoom.
A ver.
Sí, hay algo raro con el zoom, ¿vale?
Pero fijaos que ahora ya lo podemos arrastrar, ¿vale?
Lo arrastramos, lo podemos mover uno detrás del otro, ¿vale?
Y ya lo tenemos.
Aquí todavía no lo podemos devolver, pero ahora lo podemos devolver.
Ahora lo devolveremos.
Pero ya lo podemos mover entre un lado y otro, ¿vale?
Todavía no tenemos la previsualización, que estaría bastante bonita.
Ahora la hacemos.
Ahora vamos a hacer la previsualización.
Otra cosa que es interesante es que el drag over este, podríamos aquí detectar que si es el mismo, claro, aquí, por ejemplo, fijaos que si yo arrastro el elemento en el mismo nivel, se está disparando el evento drag over.
Y esto no tiene mucho sentido.
Entonces lo que podemos hacer aquí para evitarlo es decirle que si el source container, que es el contenedor original, es igual al current target, le decimos que haga un retón, ¿vale?
Que lo ignore.
Porque no tiene sentido que miremos ahí.
Entonces ahora si movemos esto, ¿vale?
Ahora sí, pues es diferente.
Lo soltamos.
Esto es por culpa del zoom.
No sé por qué le pasa, que el zoom se vuelve loco.
¿Vale?
¿Veis?
Funciona bien, pero si el zoom está mal, como que se le va un poco la cabeza.
Pero si está en el mismo, fijaos que ahora no empieza el evento, pero si me muevo, entonces sí.
Vale.
Pues ya tenemos una cosita más.
Ya tenemos creando el elemento, evitando escuchar el evento que no es necesario.
Y lo que podríamos hacer es añadir una clase aquí.
En lugar de hacer un console log, vamos a hacer un current target, class list, add.
Vamos a poner drag over, ¿vale?
Y aquí lo mismo, vamos a quitar esta clase.
Y ahora sí, con esto podremos estilar.
Bueno, este current target lo tenemos que sacar de algún lado.
Current target, evit.
¿Vale?
Si tenemos current target, remove, drag over.
Vale.
Con esto lo que podríamos hacer básicamente es.
Ahora, en el ítem, en el row, en el row que tenemos aquí, vamos a poder estilar y decir que drag over.
Vamos a poner una scale 1.1.
Bueno, un poquito menos de escala.
Vamos a poner un background un poquito más clarito.
No me acuerdo, 5, 5, 5.
Y le vamos a poner aquí que esto tenga una transition de todos.
Así.
Entonces, así lo que hacemos es, con el elemento, ahora queda así.
¿Vale?
Y así pues se ve como mejor donde estamos soltando cada uno.
Vale.
Tenemos los estilos del drag over.
Tenemos esto.
Lo que nos faltaría es cómo devolvemos.
Ah, bueno, claro.
Ahora.
¿Ves que se ha quedado?
Porque se ha quedado.
Esto se debería quitar.
Se debería quitar con el...
Ah, porque lo he hecho en el drag leave.
Lo he hecho en el drag leave.
Que puede tener sentido.
Pero no solo debería ser en el drag leave.
Porque no se ha ido el drag nunca.
Sino que también aquí deberíamos quitarlo.
¿Vale?
Solo en el caso que lo tenga.
Para evitar que se quede ahí.
¿Vale?
Porque nunca se fue el drag.
Lo soltamos ahí.
Ahora sí.
¿Vale?
Vale.
Aparte de esto, ¿qué pasa si yo quiero devolverlo aquí?
Para devolverlo aquí, tendríamos que hacer lo mismo que hemos hecho aquí con los rows.
Pero en el items section vamos a utilizar los mismos eventos que hemos utilizado.
Porque al final todo este código es agnóstico a qué contenedor lo vas a poner.
Entonces, vamos a decirle, tanto si es el contenedor de los niveles.
Como si es el contenedor donde están los items, hace exactamente lo mismo.
Así que ahora, cuando tengamos, yo qué sé, jQuery y lo pongamos aquí, si ahora lo pongo aquí, pues se queda aquí.
Entonces, ya tenemos aquí el drag and drop funcionando como si fuese el tier maker.
¿Vale?
Y ahora vamos a añadir la previsualización para que quede ahí ya feten.
¿Ok?
Vale.
Hemos tenido ahí el asunto, hemos tenido el susto este del drop, que me ha dejado loco, ¿eh?
Lo del drop.
Pero bueno, ahora haremos la previsualización porque para que quede realmente, realmente bien, vamos a hacer la previsualización.
No entendí nada.
A ver, no me digas, no entendí nada.
Pero si me preguntas exactamente qué es lo que has preguntado, agnóstico, joder, madre mía, ya también va a tener que...
A ver, agnóstico lo que quiero decir básicamente es que no está atado directamente a esos elementos, sino que se puede utilizar en cualquier elemento.
Hace rato que dice que no entiende nada, vaya, que no entiende nada, pero está muy bien explicado.
Gracias.
Pero si me preguntáis alguna cosa en concreto que no hayáis entendido, lo puedo explicar.
O sea, si me decís, ¿qué ha pasado aquí?
Que no sé qué, no sé cuánto.
Os lo comento.
Porque si no es complicado.
Si me decís, no he entendido nada, no sé cuál es el problema de exactamente no habéis entendido.
Pero os comento un poco por encima.
A ver si es una de las cosas que no habéis entendido.
Para cada row, que cada row es lo que tenemos aquí, estamos escuchando tres eventos.
Cuando pasa por encima y estamos arrastrando, cuando soltamos y cuando dejamos de arrastrar por encima.
Entonces, el más importante es el drop.
Que cuando lo soltamos, recuperamos del evento dónde lo estamos soltando y qué datos estamos transfiriendo.
Los datos que estamos transfiriendo los tenemos que indicar cuando empezamos a arrastrar el elemento.
Que lo estábamos haciendo aquí.
Cuando empezamos a arrastrar el elemento, le estamos diciendo que nos transfiriese estos datos.
Que podemos transferir lo que queráis.
HTML, un objeto JSON, lo que queráis.
Pero lo importante es que cuando los soltamos, decimos, vale, voy a recuperar estos elementos.
Voy a eliminar el elemento que estaba arrastrando de su sitio original.
Que eso lo tenemos guardado en una variable original.
La de source container es de dónde viene este elemento.
Y si tenemos eso y el elemento que estábamos arrastrando, lo eliminamos del sitio original.
E inmediatamente después, lo que hacemos es recuperar los datos que se habían transferido.
Crear una imagen con la función createItem que habíamos creado previamente.
Y donde estamos arrastrando, donde hemos soltado ese elemento,
hacemos ahí un appendchild para añadir este nuevo HTML.
Y ya está.
Eso es lo que tendría el handle drop.
Aparte de eso, para hacerlo un poquito más bonito, mientras estamos arrastrando por encima,
hemos hecho esta función.
Para detectar dónde se está arrastrando, dónde está pasando el cursor mientras se arrastra,
para añadir una clase.
Y esto lo que nos permite es crear este efecto que, mientras se arrastra la imagen por encima,
ves que cambia el estilo, porque estamos añadiendo una clase.
Y cuando no está encima, ya no sale esa clase.
Para hacer eso, tenemos estos dos métodos.
Handle drag over, que es mientras se arrastramos por encima,
y drag leave, que es cuando ya no estamos encima.
No es que lo soltamos, sino que hemos pasado de largo.
A lo mejor estamos arrastrando, pero hemos pasado de largo.
Y ya está.
Eso es lo más complicado que realmente tiene esto.
Y ahora, al final, lo que hemos hecho es que también podamos devolver la imagen,
ves, igual que lo podemos mover, también lo podemos devolver al sitio inicial.
¿Y cómo hemos hecho eso?
Lo hemos hecho utilizando, como no hemos atado toda la lógica del handle drop,
el drag over y el drag leave a unos elementos en concreto,
sino que hemos dicho que puede ser cualquier contenedor,
hemos aprovechado y hemos dicho, vale, pues también la sección de items,
quiero que escuches también esos eventos y que sea exactamente igual,
que te comportes igual.
De esta forma, cuando arrastremos otra vez el elemento ahí,
pues no habrá ningún problema, porque ya ves tú, lo pondremos aquí y ya está.
Y para evitar, y esto es importante, para evitar que se añada más de una vez
cuando lo soltemos aquí, fijaos que lo que estamos haciendo es,
tendríamos, por un lado, estoy pensando que si lo quitamos aquí, por ejemplo,
si quitamos esto, tengo dudas, pero puede ser, no, aquí no se añadiría tampoco.
Claro, esto lo evitaría en una parte, pero por otro lado, estoy pensando,
claro, no tendríamos source container, porque estoy pensando si el source container,
si hacemos algún check, pero claro, es que tiene sentido porque no estamos empezando
a hacer el drag fuera y por lo tanto, a ver, porque funcionar funciona,
a ver aquí, drag, drag en, no, aquí no lo haríamos.
Puede ser que directamente, claro, es que como el drag and drop,
la API de drag and drop, a lo mejor automáticamente,
si estás haciendo el drop en el mismo elemento, pues igual lo ignora directamente,
porque realmente no lo estás soltando como tal.
Entonces me imagino que por ahí irían los tiros.
En este caso, lo que estábamos haciendo antes no tendría ninguna incidencia.
O sea, esto no estaría haciendo la incidencia de eso.
Esto lo que estaría evitando es realmente escuchar el evento de forma innecesaria
cuando arrastramos en el mismo nivel.
Eso sería el nivel, es lo que hace, ¿no?
Entonces, funciona porque lo quitas y lo agregas, pero estás procesándolo en vano.
Bueno, claro, puede ser, puede ser que lo esté quitando,
o sea, que visualmente lo quite y lo vuelva a poner.
También puede ser, tienes toda la razón.
O sea, puede ser que, aunque yo piense que no está haciendo nada,
en realidad esté haciendo todo esto, ¿no?
O sea, que esté haciendo todo esto.
Voy a ver, console.log, suelta, suelta, vamos a poner.
Claro, tiene sentido.
O sea, realmente lo está añadiendo y lo está soltando en el mismo sitio.
Claro, o sea, que sí, que está haciéndolo todo,
solo que lo suelta y lo pone en el mismo sitio.
Realmente lo que podríamos hacer es evitar todo este cálculo
si detectásemos que el original y el final es el mismo,
pero bueno, no tiene mucha historia.
Vamos a hacer lo de la preview para que cuando, mientras está arrastrando,
puedas ir mostrando como una previsualización donde lo estás dejando, ¿vale?
Entonces, aquí, en el drag over, aquí también puedes acceder al data transfer.
Entonces, aquí, vamos a acceder al data transfer y, además de hacer el drag over y todo esto,
podemos hacerle que si tenemos, si estamos añadiendo, si estamos arrastrando un elemento
y, vale, es que estoy pensando, claro, vale, es que estoy pensando en cosas.
Porque me imagino que si lo creamos, podríamos crear aquí un preview element,
podríamos crear un, como el create image que hemos hecho antes, lo mismo.
Pero lo que podemos simplificar aquí sería clonar el elemento.
En HTML, bueno, en el DOM, puedes tener un elemento HTML y decir,
quiero que me lo clones y, además, que me lo clones de forma profunda.
El true sería para clonarlo de forma profunda.
Entonces, podemos crear como una copia.
El elemento que estamos arrastrando lo vamos a clonar y hacemos una copia.
Pero esta copia vamos a hacer que tenga un poquito menos de opacidad.
Podemos hacer un 0.4 o lo que sea, ¿vale?
Como que tenga menos opacidad y que, además, no se pueda hacer nada con este elemento
porque, si no, la podemos liar.
Así que hacemos style, pointer events none.
A ver, que no debería pasar nada con el pointer events none,
pero puede ser problemático si intentas arrastrar encima de la previsualización.
Entonces, le ponemos un pointer events none para que no se pueda hacer absolutamente nada.
Y si no, incluso esto, podríamos simplificarlo y hacer que esto sea en un class list, ¿vale?
Hacemos ahí un add preview, drag preview.
Y así quitamos todo esto, ¿vale?
Lo hacemos mejor con estilos.
Ahora lo haremos con estilos.
Pero en el current target vamos a añadir este hijo por ahora.
Y así no ponemos estilos en línea.
Y menos en JavaScript, que no está bien.
En el image, ¿cómo lo hemos puesto?
Item image.
Aquí ahora vamos a tener este drag preview,
que le ponemos la opacidad al 0.5 y pointer events none.
MIDI está perfecto explicado.
Eres una máquina.
Igual la gente se pierde en qué es over.
Live, incluso drag and drop.
Pero es que eso debería venir aprendido de casa.
Post data.
No usaste los sprites de SuperMiduBros.
¡Ostras!
La que he liado.
Vale.
Esto tiene sentido, ¿vale?
Esto tiene sentido porque...
Muchas gracias.
Esto tiene sentido porque cuando hacemos...
Claro.
Pensad que este drag over, este evento ocurre constantemente.
Entonces, aquí, aparte de mirar si tenemos un drag element,
aquí deberíamos ver si tenemos una previsualización, drag preview.
Vamos a hacer un document query selector del drag preview.
Y aquí deberíamos mirar si estamos arrastrando un elemento
y no tenemos un drag preview,
entonces hago la previsualización.
Porque si no, claro, la podemos liar parda.
Entonces, ¿vale?
Ahí sale.
Vale.
Y ahora lo que vamos a tener que hacer...
Fíjate que ha salido en el primero, pero no en los siguientes.
Entonces, vamos poco a poco.
Vamos poco a poco.
Primero.
En el primero, bien, ¿no?
Ha salido bien.
Al menos ahora solo ha salido una vez.
Lo que vamos a tener que hacer es sacar...
Que, por ejemplo, cuando hacemos el drop, lo eliminamos.
Aquí, ¿vale?
En este, esto que habíamos hecho, el drag cover,
pues igual aquí vamos a sacar el drag preview.
Drag preview.
Cuando soltamos...
Bueno, podríamos eliminar el drag preview en general.
O sea, cuando hacemos...
Estoy pensando...
Estoy pensando...
Si el current target...
O sea...
Drag preview.
Remove.
Vale, esto seguro.
Cuando lo soltamos aquí, seguro.
Pero aparte de este, deberíamos también hacerlo en otro sitio.
O sea, también cuando hacemos el leave.
¿Vale?
O sea, cuando nos vamos aquí.
Aquí también.
Target.
Aquí también lo deberíamos eliminar.
Ponemos aquí el optional chaining,
porque puede ser que este elemento no existe.
O sea, hacemos un current target.
Vamos a mirar si tenemos una previsualización
y si la tenemos, la eliminamos.
Importante el optional chaining,
porque si no, esto nos puede petar.
¿Vale?
Así que por eso he puesto en el anterior un optional chaining.
¿Vale?
Porque puede ser que no exista por X motivo.
Así que como tag click...
No tenemos tag click y no nos avisaría.
¿Vale?
Ahí lo tenemos.
Vale, ahí tenemos cómo quedaría.
Vale, perfecto.
Y ahora...
Perfecto.
Y ahí lo tenemos también cómo quedaría.
Y lo interesante ahora es que si tenemos RIA
y lo ponemos aquí,
ahora nos queda perfecto.
¿Vale?
Ya podemos ver cómo irían quedando cada una de las imágenes
para que vaya quedando y se vayan apilando.
¿Vale?
Entonces ya tenemos esto.
Vale.
Madre mía el drag and drop.
Madre mía el drag and drop.
Vale.
Entonces,
¿cómo le indica si quieres arrastrar un botón?
Pues podrías hacerlo con...
Como he dicho,
puedes arrastrar un HTML o lo que sea.
O sea,
al final,
dragable es una propiedad que puedes utilizar en cualquier HTML.
Ahora,
es un rollo tener que ir una a una las imágenes.
Así que,
vamos a ir al input
y vamos a decirle que vamos a querer aceptar múltiples imágenes.
¿Cuál es el problema?
Que si yo intento ahora puedo seleccionar múltiples,
pero le doy a open y solo me pone una.
Porque tenemos que cambiar el código
de el JavaScript que tenemos aquí.
Aquí habíamos dicho que solo recuperaba una,
un archivo,
¿no?
Vale.
Pues aquí ahora vamos a recuperar todos los archivos
y ahora vamos a iterarlos.
Vamos a decir,
vale,
si tengo archivos
y la longitud de los archivos es mayor a cero,
pues todo esto vamos a...
Y aquí hay un tema importante.
Esto no va a funcionar.
Ya os explicaré por qué.
¿Vale?
Este files for each y tal,
esto no va a funcionar.
Esto va a petar.
Si nos vamos aquí y decimos,
vale,
quiero que me...
Todas estas imágenes.
Me dice files.foreach is not a function.
Esto es porque el files,
este files que ves aquí,
en realidad no es un array.
Es un poco tricky muchas veces,
pero en JavaScript,
especialmente con la web API
y temas del DOM,
no devuelves siempre un array,
aunque sea una lista.
Sí que tiene la propiedad length,
pero no tiene el método for each,
porque no es un array,
ni es un iterable típico,
sino que es una lista de archivos.
Entonces,
lo que sí que puedes hacer con JavaScript
es transformarlo en un array,
porque sí que es un iterable
que tiene un length y tal,
pero no tiene el método for each.
Entonces,
lo que puedes hacer
es transformar la lista de archivos
en un array
utilizando el método array from.
Y ahora vas a ver
que sí que va a funcionar esto.
Ahora,
si cargamos todo esto
y le doy a open,
¿vale?
Ahora sí que las ha cargado todas,
de una.
Así de fácil,
ya hemos cargado múltiples ficheros.
Vale.
Podríamos mejorar un poco más esto,
porque esto lo vamos a volver
a necesitar después,
porque voy a querer arrastrar.
Lo increíble sería poder hacer esto,
estar aquí,
estar aquí
y hacer esto.
¡Pum!
Y que funcionase.
Eso sería increíble.
Y lo vamos a hacer.
Y lo vamos a hacer
con la API de drag and drop también.
Así que está bastante interesante.
Vamos a irnos aquí,
aquí,
vamos a crear una función
function
use files
to create
items,
¿vale?
Donde le pasamos una lista de files
y es exactamente
esto que tenemos aquí.
Esto que tenemos aquí
lo ponemos aquí
y ahora,
en lugar de hacer todo esto,
hacemos esto
y le pasamos
los files que hemos creado.
Esto está bien
porque luego,
cuando hagamos el drag and drop,
lo necesitaremos.
Pero antes de hacer
el drag and drop,
vamos a añadir
el botón reset
porque,
bueno,
tengo el botón reset,
pero estaría bien
que,
aunque yo tenga aquí
todo esto
y haya hecho todo esto
así y así,
cuando le dé a este botón
se resetee todo,
¿no?
Vamos a irnos aquí
a JavaScript
y vamos a crear
el,
vamos a traernos,
tú, tú, tú,
a ver aquí,
quitamos este subg
que se vea más claro.
Este botón,
vamos a llamarle
reset button
o clear button
o clear button,
también estaría bien.
Reset tier button,
me gusta más.
Reset tier button,
¿vale?
Nos vamos por aquí,
nos vamos a traer el
reset button,
reset tier button
y aquí debajo del todo
vamos a hacer
reset button,
que cuando hagamos un clic,
vale,
esto es lo que sería
maravilloso hacer,
¿eh?
Esto sería buenísimo,
pero no,
no podemos hacer esto.
Tenemos que recuperar
todas las imágenes
y para eso
vamos a recuperar
de exacto.
Tenemos que traernos
todos los
item image
que existen,
todos,
¿vale?
Los tenemos que recuperar.
En lugar de hacer
un item section
query selector all,
que en realidad
lo podríamos hacer así,
o sea,
porque lo interesante
sería traerse
los que están
no en el item section,
o sea,
esto no está bien,
habría que traerse
los que tenemos
realmente en el tier list,
o sea,
los que ya hemos colocado.
Entonces,
vamos a traernos
del tier
todos los que sean
item image.
Aquí tendríamos
los items
que hemos colocado
y de todos
estos items
no los vamos
a borrar,
que también entiendo
o al menos
no tan bestia,
no por ahora,
pero lo que podríamos
hacer para cada uno
sería,
por un lado,
sí,
lo elimino,
este lo elimino,
pero por otro lado
en el item section
lo vuelvo a poner,
¿vale?
App and child
y le pongo el item.
Entonces,
sí los voy a eliminar,
pero a la vez
los voy a añadir
donde estaban.
A ver si ahora
con esto funciona
y podemos hacer
¿vale?
Ahora,
vale,
perfecto,
pues ya está.
Ahora con esto
ya podemos hacer
el reset,
muy bien.
Ahora que tenemos
el reset,
vamos a hacerlo
de añadir
las imágenes
arrastrando.
Para eso
vamos a utilizar
otra vez
el drag and drop.
O sea,
es que el drag and drop
es una maravilla
porque no solo
podemos hacerlo,
utilizar el drag and drop
lo podéis utilizar
para un montón de cosas
y me gusta mucho
este proyecto
porque aprendéis
el drag and drop
en diferentes cosas,
no solo con este ejemplo
sino con otro,
con archivos
que vienen de fuera
y hacer un drag and drop
y es muy fácil
y muy interesante.
Para hacer el drag and drop
de las imágenes,
o sea,
lo que vamos a querer
es que yo estoy aquí
y arrastro los ficheros aquí
y me aparecen
y me los carga
sin ningún tipo de problema.
Para hacer eso,
igual que hemos
hecho este item section,
drag over,
drop, drag leave,
vamos a añadir otra vez
aquí un items section
a TV listener,
drop,
¿vale?
Y aquí voy a poner
handle drop
from desktop
y item section,
section
a TV listener,
vamos a poner aquí
un drag over,
handle drag over
from desktop,
¿vale?
Como para detectar
que realmente estamos
trayéndolo desde el escritorio
y no desde otro sitio.
¿vale?
Voy a hacer esto pequeño,
que no necesitamos
que esté tan ampliado
y vamos a crear
el handle drag
from desktop,
¿vale?
No sé si eso tendrá sentido,
pero ahora lo veremos.
Creo que no tenía mucho sentido.
O sea,
es que se inventa
unas cosas a veces
en la inteligencia artificial
y este handle drop
from desktop,
¿vale?
Con el evento
y hacemos un
event.preventDefault.
¿Vale?
¿Cuál lo hacemos primero?
El primero que podríamos hacer
es detectar
si realmente
estamos trayendo
o no.
Espérate,
estoy pensando,
estoy pensando,
¿qué podríamos hacer primero?
A ver,
vamos a traernos aquí
el current target
y el data transfer
para ver esto.
console.log
current target
data transfer
y el current target
vamos a poner
class list
at drag files,
¿vale?
Y este drag files
para estilar mejor
el section este,
el,
a ver,
section,
no,
items,
selector items,
selector items,
aquí,
vamos a ponerle
drag files,
podemos hacer que cambie
un poquito
el fondo
con una cosa
más clarita
y que el borde
sea como
así,
¿vale?
border style,
creo que era,
style dash,
¿vale?
Vale,
y esto
lo cerramos aquí.
Entonces,
ahora,
al menos
cuando arrastremos,
¿vale?
¿Ves que ha cambiado,
que está detectando esto?
Fijaos que ha cambiado
los estilos,
está cambiando los estilos,
podríamos poner ahí
un texto y todo
de suelta,
¿vale?
Obviamente,
todavía no funciona,
pero sí que tenemos
aquí un montón
de información,
el current target,
porque ha detectado
dónde estábamos
intentando soltar
y una cosa interesante
es que el data transfer
ya te viene
con información.
En el data transfer
tenemos aquí
data transfer,
drop effect,
o sea,
ya nos ha rellenado
la propiedad
del data transfer
con la lista
de archivos
que le íbamos a pasar.
Así que aquí ya
en el data transfer
que tenemos aquí
en el handle dragover,
este data transfer
ya viene con la información
que necesitamos,
¿vale?
y lo más interesante
es que podríamos
ya empezar a hacer
checks,
podríamos decirle,
vale,
vamos a mirar,
esto sí que lo está
haciendo bien,
la inteligencia artificial,
vamos a mirar
si los tipos incluidos
en el data transfer
es del tipo archivo
y entonces sí que
vamos a hacer esto
y si no,
podríais estilarlo
y poner que es un prohibido,
que no se puede aceptar
y tal,
o sea,
podéis evitar
que realmente
se pueda
soltar ahí cualquier cosa
y que sólo
cuando le estéis pasando
archivos
realmente cambie
visualmente
los estilos
de ese elemento.
Esto sería
para el drag
pero necesitamos
para el drop,
o sea,
necesitamos que cuando
lo soltemos
realmente podamos
recuperar
esos archivos
y mostrarlos.
Así que hacemos
exactamente lo mismo
que ya hemos hecho
porque ya tenemos
el data transfer,
volvemos a hacer
este check
para asegurarnos
que no intentamos
que nos cuelen
cualquier cosa,
le decimos
vale,
si tienes archivos ahí
pues yo lo que voy a hacer
es recuperarlos.
Vamos a,
por un lado,
quitamos el
class list
remove
el drag files
este,
vale,
que hemos añadido
aquí en el drag over
porque ya no lo necesitamos.
Vamos a sacar
los archivos
del data transfer
que ahí es donde
tenemos toda la información
y ya podemos
utilizar otra vez
el método
use files
create items
que teníamos aquí arriba
que es el mismo
que estamos utilizando
para el input
lo estamos reutilizando
igual que lo utilizamos aquí
cuando el usuario
aquí detecta
y quiere
las imágenes
las que quiera
lo vamos a utilizar también
para cuando nos arrastre
las imágenes
utilizando ese data transfer
recuperar esa información
que es un file list
con todo lo que necesitamos
usamos exactamente
lo mismo
y la idea
es que ahora
cuando arrastremos
aparezcan ahí
y punto
hemos hecho
un drag and drop
de archivos
en nuestra página web
y esto
pues ahora ya
funcionan perfectamente
y ahora ya no necesitamos
utilizar este botón
que está bien
porque nos ha ayudado
y es interesante
porque así le damos
una oportunidad al usuario
de que vea
cómo lo puede añadir
sino que no solo eso
sino que ahora también
además lo puedes añadir
tantas veces como quieras
bueno
ahí me faltaría
un flex grab
que podemos añadir ahora
ahora añadimos
y con esto
tenemos ahí
ese selector
maravilloso
esto sería grab
vale
y habría que también
hacer que
a ver
esto sería
o sea
teníamos que calcular
para que quede exactamente
igual
pero bueno
al menos vamos a ponerle
en el selector items
vamos a poner
el flex grab
flex grab
grab
vale
qué tal
qué tal os parece
este arrastre
que hemos hecho ahí
y que en un momento
tenemos todas las imágenes
qué tal
qué pasa si alguno de esos archivos
no sea una imagen
por ejemplo
si pasas
es un texto txt
bueno
ahí está
que habría que empezar a filtrar
o sea
podéis hacer la lógica
de hecho
eso es uno
deberes que os voy a dejar
el tema de
podéis filtrar
archivos
que si hay un archivo
que no debería estar
podéis mirar el tipo del archivo
sin ningún tipo de problema
y lo podríais hacer
así que
qué pasaría
cuando el arroba
alcance el máximo de elementos visibles
podéis hacer que tenga scroll
sin ningún problema
vale
vale
esto no es todo
aún hay más
porque lo que me gustaría
aparte de esto
que esto está muy bien
pero
sabéis que
lo que me gustaría
es que
cuando estoy aquí
poder hacer una foto
de esto
y que aparezca
esta imagen
o sea
me gustaría poder hacer una foto
para poder hacer una foto
de todo esto
claro
sin utilizar la captura de pantalla
podemos utilizar
alguna dependencia
eso sí
una dependencia
porque es bastante
más complejo
pero nosotros
lo podemos hacer fácil
entonces
hay una dependencia
se llama
html
to canvas
que es muy mítica
en la que puedes hacer
screenshots de html
¿qué pasa si añades un login
and le drop
y and le drop
from desktop?
el mismo elemento
tiene dos eventos drop
¿se ejecutan ambos
o solo uno?
se ejecutan ambos
ese es el tema
o sea
se ejecutan ambos
lo que pasa es que
cada uno
funcionará cuando
con el if
que tenga dentro
o sea
estos
html listeners
vosotros podéis
añadir tantos
html listeners
como queráis
por ejemplo
un botón
puede tener
10 clics
diferentes
y de hecho
es normal
es bastante típico
un botón
puede tener
más de un html listener
y tú dirás
¿y para qué harías eso?
pues en realidad
es mucho más típico
de lo que crees
por ejemplo
imagínate
cómo funciona
google analytics
o cualquier
javascript de analíticas
pues es añadiendole
eventos
a los botones
y lo que haces
es que tú tienes
un atv listener
de ese botón
con tu click
donde hace
lo que tenga que hacer
pero google analytics
está añadiendole
otro atv listener
de ese click
sin ningún tipo
de problema
así que
tú puedes poner
tantos atv listener
como quieras
no hay ningún problema
y se van a ejecutar
los dos
uno no machaca
al otro
así que no
no te preocupes
hola midu
es mi primer mensaje
en tu chat
estoy contento
porque he conseguido
un trabajo muy bueno
después de muchas entrevistas
que grande
me alegro un montón
me alegro un montón
amigo
muy muy muy bien
tremendo
tremendo
que bien
felicidades
bueno pues vamos a hacer eso
vamos a añadir otro botón
aquí
que está
aquí
teníamos ya estos dos botones
vamos a añadir un tercero
aquí
vamos a ponerle
save
tier
vamos a guardar
los table
tabler
icons
vale
y aquí vamos a poner
save
este tiene
sentido
lo único que
vamos a cambiar
el stroke
para que sea más fino
no sé por qué
por defecto sale ese stroke
que es exagerado
es exagerado
aquí
vale
ya teníamos ahí
el save
save tier button
nos vamos para aquí
vamos a traernos este
save tier button
save button
vale
save tier button
y esto igual
que hemos hecho
por aquí
vamos aquí abajo
vamos a poner save button
atv listener
con el click
vale
vale
porque es interesante esto
esto
primero tenemos que recuperar
el elemento
que queremos
que queremos convertir
en imagen
así que vamos a traernos
el tier
donde tenemos los botos
vale
vamos a crear un canvas
tenemos que crear
un elemento
canvas
y en este canvas
tenemos que tener
el contexto
canvas
get context
porque digamos
que es donde
vamos a dibujar
el elemento
que queremos
descargarnos
vale
así que ahí tendríamos
la imagen
donde vamos a dibujar
en este canvas
¿cómo lo vamos a hacer?
aquí realmente
se puede hacer
pero tendríamos
que transformar
cada elemento
html
y recuperar
la posición
de cada elemento
html
con el
get bounding
client
rec
para dibujarlo
en el canvas
no es imposible
pero es muchísimo
trabajo
por suerte
hay una dependencia
que se llama
html
to canvas
que es la que os enseñaba
antes
que esto ya lo tiene hecho
lo único malo
la vamos a intentar utilizar
porque lo único malo
es que a veces
no está muy
no está muy actualizada
como podéis ver
hace años
que no se actualiza
y a lo mejor
a veces da algún problemilla
pero vamos a intentar esta
y si no hay otra
que es como más moderna
que funciona bastante bien
que es la de html
to canvas pro
probemos primero esta
si funciona mal
probamos la otra
y ya está
entonces
nos vamos aquí
y cargamos la versión
ESM
que es la de
enmascript modules
y es esta
la que está minificada
estoy pensando
sin necesidad
ah no
vale
esto con esta ya tendríamos
vale html to canvas
vale
que necesitamos
como solo queremos
cargar esta dependencia
cuando la queramos utilizar
vamos a utilizar
lo que se dice
un import dinámico
este módulo
lo importamos
dinámicamente
y por eso
este import
va así
vale
diferente a los típicos
simples que veis
es como un método
es como una función
que le pasas como parámetro
la url
que quieres cargar
y esto te devuelve
una promesa
y en la promesa
aquí tendríamos
que extraer el módulo
que acabamos de cargar
aquí
el módulo
por defecto
sería html
dos canvas
si fuese nombrado
pues ahí tendríamos
que sacarlo nombrado
pero es el
por defecto
el default
vale
por eso ponemos
default dos puntos
y luego le cambiamos
el nombre
html
dos canvas
dibujamos
en el canvas
vamos a dibujar
nuestra imagen
vamos a dibujar aquí
canvas
cero
cero
vale
de ambas
ay
primero tengo que utilizarlo
estoy tonto
primero tengo que utilizar
html dos canvas
vale
tier container
y ahora tenemos
el canvas
canvas
y ahora sí
ahora sí que dibujamos
ahora sí que decimos
en el contexto
draw image
canvas
y esta sería la posición
vale
este canvas
que nos está pasando
nos lo pasa html
to canvas
que es el que está
transformando el canvas
y entonces en el contexto
de nuestro elemento
es que dibujamos
lo que nos está devolviendo
el html
to canvas
que ahora veremos
si queda bien
esto
nos lo dibuja
pero no nos lo
no nos lo
descarga
no nos da la descarga
para crear la descarga
se puede hacer
de diferentes formas
lo más sencillo
es simular
un elemento
anchor
y hacerle click
vale
porque no hay forma
fácil
de descargar
un archivo
desde javascript
pero sí que se podría hacer
de decir
vale
pues ahora que ya tengo esto
vamos
primero
voy a transformar
en una imagen
el canvas
tu data url
y aquí le deberías indicar
el tipo
podría ser por ejemplo
jpeg
podría ser lo que quieras
normalmente un png
sería la mejor opción
y ahora que tenemos
la imagen
creamos
un download link
un elemento
anchor
y hacemos esto
este download
punto tier punto png
es para cambiar el nombre
aquí le podéis poner el nombre
que queráis
en el href
le pasamos la url
que hemos creado
con el canvas
y le simulamos un click
esta sería
la magia
o el truco
para poder hacer
este download
en realidad
se supone
que ya hay
download file
o sea ya hay formas
de trabajar
con archivos
el problema
de este tipo
de cosas
de poder hacer
descargas
y tal
es que no todos
los navegadores
lo soportan
y además
hay algunas cosas
hay como algunas
limitaciones
que tienen
a día de hoy
así que
esto es una forma
que suele funcionar
bastante bien
podéis probar la otra
para ver cómo funciona
pero esta sería
como la más universal
todavía
vamos a ver
si esto nos hace
la imagen
que estábamos diciendo
que nos debería hacer
vamos a utilizar
este arrastre
angular lo ponemos
en su sitio
javascript
lo ponemos
en su sitio
jquery
lo ponemos
en su sitio
react en su sitio
que broma
jquery es dios
jquery es dios
como lo vamos a poner
vamos a ponerlos
en su sitio
de verdad
venga
vamos a ponerlos
en su sitio
de verdad
venga
ahí está
ahí está
venga
ahí están
estamos contentos
con este
este sí que es
el correcto
nada lo sé
nada es broma
pero vamos a darle aquí
a ver si lo descarga
vale
ha petado
muy bien
vale
ves
atentity to parse
esto es lo que me imaginaba
que esta dependencia
html to canvas
es que
no la actualizan
y da muchos problemas
normalmente
entonces
vamos a intentar
la de html to canvas pro
que es un fork
que hicieron
vale
a ver si encontramos
la versión
esta
esm
este sería la url
esta sería la url
y a ver
que tal
a veces
no funcionan
del todo bien
o sea
que a mejor
la imagen
se ve un poco
regunichis
pero es cuestión
de ir ajustando
cosas
así que
no os preocupéis
venga
vamos a darle esto
ponemos angular
en su lugar
ya que aquí
ya me imagino
a la gente cabreada
tomándose estas cosas
en serio
venga
vamos a ponerlo así
para que no se cabree
vale
tier
venga
vamos a ver
como ha quedado esto
bueno
vale
lo único que esto
no ha quedado centrado
pero bueno
esto se podría
se podría intentar ajustar
cambiando los estilos
c6 y tal
pero fijaos
ya hemos generado
la imagen
en un momento
podríamos cambiar aquí
aquí por ejemplo
fire
no sé si se verán
los emojis
ahora lo vamos a ver
start
no sé
vamos a ver si se ven los emojis
guardamos la imagen
a veces no se ven los emojis
ese tiene que cambiar
a ver
sí que se ven los emojis
pues fijaos
ahí lo tenéis
y con esto hemos creado
en un momento
en un momento
un tier maker
con drag and drop
con también
que podrías
arrastrar imágenes
que puedes guardar
la imagen
generarla
add new project 07
y todo con puramente
javascript
html
y css
ahí lo tenéis
ahí lo tenéis
todos tienen
los colores no están al revés
esos que no habéis visto
un tier maker
desde
en vuestra vida
cosas que podéis hacer
deberes
ejercicios
para seguir practicando
y seguir mejorando
porque esto es solo principio
o sea se pueden hacer
mil millones de cosas
que podéis hacer
mira podéis hacer
que se guarde
en local storage
por ejemplo
el problema es que ahora
cuando yo me voy
pues desaparece
guardar en local storage
guardar en local storage
todo lo que
lo que tiene el usuario
en este momento
esa podría ser una
y
no solo guardarlo
sino que recuperarla
incluso como
lo que guardéis
en local storage
puede ser un json
lo que podéis hacer
es que se pueda
cargar desde aquí
otra cosa que podéis hacer
tener tier list
ya preparados
en los que
tengas aquí como
vota los mejores
lenguajes de pronunciación
vota no sé qué
y al darle click
que te aparezcan ya
las imágenes
preparadas
para poder
pues lo mejor
el videojuego
lo mejor el lenguaje
lo que sea
esa podría ser otra
luego filtrar
añadir más estados
por ejemplo
que pasa
si alguien
intenta arrastrar
algo que no es una imagen
por ejemplo
el informe de la velada
lo intenta arrastrar aquí
y fíjate que hay un error
esto se puede arreglar
¿por qué?
porque esto es porque
no hemos validado
que realmente
el tipo del archivo
sea una imagen
eso cuando lo
estamos soltando
cuando hacemos
el handle drop
aquí from desktop
aquí
si te pones a escudriñar
podría revisar
fíjate que ya hemos revisado
que realmente
estemos pasando archivos
igual que estamos
haciendo esta validación
se puedan hacer otras
e igual que
estamos haciendo
que si son archivos
que cambie este estilo
podéis hacer cualquier estilo
aquí
podéis hacer un montón
de cosas
¿vale?
otra muy interesante
ya es incluso
hacer el backend
o sea
podríais hacer el backend
de esto
de que se guarde realmente
en un backend
esta información
y que
o que sea
multiplayer
que más de una persona
pueda estar votando
¿vale?
así que
si no
me parece que ha sido
un directo
muy muy muy chulo
que el usuario
pueda elegir
la cantidad de tiers
o sea
podéis hacer
ahí un montón
de cosas
los cambios
ya están guardados
ya os tenéis guardados
los cambios
lo que muy pronto
os dejaré el proyectito
por aquí
para que lo tengáis
también aquí
los cambios
los tenéis
en el repositorio
totalmente
código abierto
fijaos
lo tenéis aquí
07 tier maker
ya lo tenéis
simplemente es un index.html
que hemos escrito
pues unas 400 líneas
de código
todos juntos
y ya lo tenéis hecho
o sea que
nada
tremendo
y solo recordaros
que estamos trabajando
en la MiduConf
el 12 de septiembre
tenemos la conferencia
de programación
que hacemos todos los años
vamos a tener
256 regalos
que para poder participar
y poder tener
tu regalo
¿vale?
para poder participar
en muchos de los sorteos
vais a necesitar
el ticket
¿vale?
el ticket que veis aquí
lo vais a necesitar
entonces
conseguid vuestro ticket
compartidlo
en las redes sociales
no
la MiduFest es en marzo
hacemos dos conferencias
en marzo
hacemos la MiduFest
que el año que viene
no hacemos MiduFest
ya os explicaré
por qué
vais a alucinar
el año que viene
no hay MiduFest
hay otra cosa
mejor todavía
entonces
la MiduFest
suele ser en marzo
y en septiembre
hacemos la MiduConf
y este año
la MiduConf
es dentro de 34 días
lo hacemos el 12 de septiembre
¿vale?
ya tenemos confirmados
a Guillermo Rauch
a Carmen Anzio
DotCSV
Alba Silvente
Peladoner
Fast
Estefany Aguilar
y un montón de gente más
¿vale?
y pronto tendréis la agenda
tendréis los regalos
pero ya podéis conseguir
vuestro ticket
así que
compartidlo con la gente
ponedos en la agenda
qué día va a ser
12 de septiembre
aquí os aparecerá
vuestro horario
¿vale?
de vuestro país
así que no os lo perdáis
que va a ser
tremendo evento
tremendo evento
este año
vamos a petarlo
pero no te vayas todavía
que llevo todo el directo
esperando a que hagas
la tier list
y pongas Angular
y React
por encima de Astro
es que Astro
no aparece
pero Astro sería
ya sabéis que para mí
la tier list
Astro sería la S
sin ninguna duda
o sea
sería la S
lo sabe Dios
es que esto no es Astro
esto es Angular
la A es de Angular
no de Astro
así que nada
ahí lo tenéis
Midu ya no supe
qué proceso seguir
para el libro digital
en Deps League
hostia Mario
escríbeme un chat
en Twitch
y ahora lo miro
que igual se me pasó
es que a veces
se me puede pasar
pero no pasa nada
me escribes
y ya está
vale pues amigos
aquí lo dejamos
disfrutad mucho
el fin de semana
desconectad amigos
que hay que descansar también
gracias por acompañarme
espero que os haya gustado
creo que estamos haciendo
unos proyectos muy chulos
para que aprendáis
JavaScript
en condiciones
no de lo típico
de esto es una variable
esto es una función
esto es una red y tal
sino pues moviendo la manita
con proyectos
que realmente
marcan bastante
la diferencia
así que
este es el séptimo
y mi idea es
que hagamos hasta 100
tengo un montón de ideas
así que a ver
tardaremos tiempo
pero lo haremos
espero que os guste
javascript 100.dev
ahí entráis
tenéis un montón de cositas
si le dejáis una estrellita
al repositorio
pues me ayudáis un montón
tenemos 1800
pues si llegamos a 5000
sería un locurón
y si llegamos a 10.000
ya
no sé qué hago
me vuelvo loco
digamos
vamos a ver
unas
3
o
6
2
2
2
2
3