soy Kseso y esto EsCSS

Javascript con Furoya: Pseudo borde circular de caracteres tipográficos

Una forma sencilla y elegante para distribuir, con javascript y css, caracteres tipográficos formando un borde circular alrededor de un elemento sin necesidad de añadir elementos ni marcado en el Html

Javascript con Furoya: Pseudo borde circular de caracteres tipográficos

✎ 0
COLABORACIÓN AUTOR INVITADO

Hace unos días Kseso trajo a portada del blog de su #olvidoteca css un ingenioso método para acomodar en círculos una serie de elementos: Secuencias progresivas en Transformaciones y otras propiedades Css.

El fin último era mostrar caracteres de un texto acomodados en ronda, y aquí también vemos el inconveniente para el CSS : no se puede dar formato de forma independiente a cada letra, hay que meter cada una en algún elemento html y actuar sobre ellos. Por supuesto, el texto queda destruído.

Javascript con Furoya: Pseudo borde circular de caracteres tipográficos

Hay otro caso similar donde se usan elementos y hasta caracteres de modo puramente ornamental, y nunca es conveniente poner esos falsos textos en el HTML para que no sean leídos por buscadores o texttovoices, o lisa y llanamente para que no lo ensucien. Los pseudoelementos ayudan bastante con estos temas, hasta que hay que meter elementos HTM adentro. Por supuesto, eso no se puede.

En el artículo anterior sobre Javascript mostraba cómo capturar texto y procesarlo fuera del código fuente agregando etiquetas entre los caracteres. Hoy vamos a presentar una variante de ese ejemplo, pero poniendo nuestros propios caracteres para que nunca se vean en el documento original.

Seguramente esta situación es poco probable, pero a los efectos del artículo califica sobradamente. Vamos a simular un borde decorado con caracteres dispuestos en círculo, y vemos que el HTML contiene escritos a todos.

See the Pen Fake circular border with characters. (1) by Kseso (@Kseso) on CodePen.

Ver Demo a Full

Ni hablar que es una demo despojada, básica, casi sin formato para estudiar el método. Que por otro lado, ya está bien descrito en el enlace del comienzo.

La idea es eliminar del código fuente el contenido de figure, que no es relevante sino estético. Y como no hay una cadena de texto original para cortar, aquí ya tenemos la primera dificultad para usar al viejo conocido textContent().split(""). Ahora necesitamos un javascript que escriba una serie de —en nuestro ejemplo— 24 caracteres iguales separados por la etiqueta de apertura <span>. Y después agregarle una cadena con los 24 cierres </span> seguidos, al final.

Para eso tenemos una función (más exactamente, una sentencia) llamada for(). Existen variantes como for...in, for...each o for...of, entre otras, pero en principio todas trabajan un loop o bucle dependiendo de las expresiones o argumentos que tenga entre los paréntesis. Por lo general, usa tres:

  1. una variable de inicio
  2. una condición
  3. y una instrucción final.

Y el bucle itera hasta que alguna no se cumpla. De esa forma, la sentencia que contenga for(){} entre las llaves se repite cíclicamente hasta que le pongamos un límite. Y así es como repetimos 24 veces la cadena </span> mencionada antes.

Tomemeos el siguiente código Html como base para crear el efecto. Es básicamente el mismo del pen anterior pero límpio, sin los caracteres textuales de figure

<!DOCTYPE html> <html lang="es-ar"> <head> <meta charset="utf-8" /> <style type="text/css"> body { background-color: mistyrose; } #bordeado { position: relative; width: 13em; height: 13em; margin: auto; font-size: 2em; color: crimson; background: url(ruta/img.ext) center; background-size: cover; border-radius: 100%; box-shadow: inset 0 0 0 1em rgba(255,180,180,.7); /*DECORATIVO*/ overflow: hidden; } #bordeado span { position: absolute; display: block; width: 1em; text-align: center; line-height: 1.55em; /*AJUSTE FINO DE "RADIO" DEL FALSO BORDE*/ /*transform-origin: -1.1em .6em; AJUSTE FINO DE "RADIO" DEL FALSO BORDE*/ transform: rotate(15deg); /*15deg = 360 GRADOS ENTRE 24 CARACTERES DE BORDE*/ /*border: 1px solid black;*/ } #bordeado > span:first-child { top: 6.5em; left: 12em; /*POSICIÓN DEL span PADRE (REFERENCIA PARA LOS HIJOS)*/ } </style> </head> <body> <h1>Falso borde circular con caracteres.</h1> <figure id=bordeado></figure> </body> </html>

Y aquí es donde creamos es script para añadir los caractéres tipográficos sin necesidad de incluirlos en el Html:

<script type="text/javascript"> var borde = ""; /*CADENA DE TEXTO (INICIALMENTE VACÍA) PARA PONER LAS ETIQUETAS Y CARACTERES*/ /*CREAMOS LA CADENA CON LAS ETIQUETAS DE APERTURA DE span SEGUIDAS CADA UNA DE UN CARACTER*/ for(c=1; c!=25; c++) { /*AGREGAMOS AL FINAL DEL CONTENIDO DE borde EL TEXTO QUE ESTÁ ENTRE COMILLAS*/ borde += "<span>☻\r\n"; } //alert(borde); /*AGREGAMOS A LA CADENA LAS ETIQUETAS DE CIERRE DE span AL FINAL*/ for(s=1; s!=25; s++) { borde += "</span>"; } //alert(borde); /*METEMOS LA CADENA COMO HTML DENTRO DE figure*/ document.querySelector("#bordeado").innerHTML = borde; </script>

El script está comentado, pero como siempre, vamos a verlo paso a paso.

En primer lugar el objetivo es escribir el mismo código que estaba dentro de figure, y lo hacemos en una var borde con un texto vacío. Para llenarlo usamos el primer bucle, que tiene dentro una variable c (podemos prescindir de la declaración var) que inicialmente vale 1 (uno); luego hay un condicional c!=25, que se interpreta como si c no es igual a 25; y por último una instrucción para cuando el bucle termine cada vuelta, c++, que es una forma abreviada de escribir c=c+1, es decir, que a c le sume 1.

La "traducción" sería : « 'c' vale 1; si 1 no es igual a 25 (y no lo es), ejecuta la instrucción que está entre las llaves; y suma 1 a 'c'. En la siguiente vuelta 'c' vale 2; sigue sin ser igual a 25; otra vez ejecuta la sentencia; y suma otra vez 1 a 'c'. ... Sigue así hasta que 'c' llegue a 25; entonces compara si 25 no es igual a 25 (y ahora sí lo es), por lo que la condicion ya no se cumple y el bucle se detiene. »

Hay muchas formas de escribir el for(), en este caso le estamos poniendo un límite para que solamente se repita 24 veces, de ahí el "25", ya que de 1 a 24 son los que nos sirven, con 25 nos pasamos, y por eso usamos ese valor para que se detenga.

Cada vez que se repite, a la variable borde le "suma" otra vez la cadena de texto "<span>☻\r\n" (no la reemplaza como haría con un signo igual: poniendo un signo de suma y un signo de igualdad, la agrega al final de lo que ya hay). Lo más extraño puede ser el "\r\n". Son las formas que usa javascript para escribir en el texto un retorno de carro y un salto de nueva línea; lo mismo que si pulsáramos una vez la tecla [Enter]. Es nada más para ver ordenado el código en el mensaje de alerta y que quede igual a como está en el HTML del ejemplo anterior.

Ahora que tenemos en var borde todas las aperturas de <span> seguidas de un caracter ☻, entonces hacemos un segundo bucle, para repetir 24 veces el cierre </span>.

Y ya disponemos de la cadena completa para meterla en figure usando innerHTML.

Una vez allí, el CSS se encarga del resto para lograr el resultado final que ves en la siguiente demo:

See the Pen Fake circular border with characters. (2) by Kseso (@Kseso) on CodePen.

Ver Demo a Full

Como de costumbre, vamos a recordar que existen varias formas de conseguir el mismo fin. Y algunas, más que un método son un truco. Vean cómo se arma la cadena de texto en este pen:

See the Pen Fake circular border with characters. (3) by Kseso (@Kseso) on CodePen.

Ver Demo a Full

Aquí sí estamos usando join(). Aunque de una manera poco ortodoxa: Primero creamos un array, pero con 37 elementos vacíos Array(37) (el número es el total de elementos).

Estos elementos están declarados, lo que no hacemos es llenarlos, así que no tienen nada. Luego unimos esas cadenas vacías usando como juntura el texto "<span>►\r\n". En la práctica, solamente van a quedar esas junturas, una a continuación de la otra; pero 36 veces. La razón para que usemos un array de 37 elementos es obvia: si tenemos 2 elementos, entre ellos habrá sólo una separación, si tenemos 3 elementos, pondremos 2 junturas, y si tenemos 37 elementos, habrá 36 junturas. Que es el número que estamos necesitando para el último ejemplo (con 10 grados de separación entre espanes nos dan los 360 grados del borde).

A continuación, le agregamos otro array —el signo de 'suma' agrega o concatena textos— que crea la siguente cadena, y final, con los 36 cierres de espan. Y así obtenemos el mismo resultado que usando el bucle for(). Pero con menos código.

document.querySelector("#bordeado").innerHTML = Array(37).join("<span>►\r\n") + Array(37).join("</span>");

Autoría

Furoya: Autor del artículo

Artículo original de Furoya.
La intención del autor con sus colaboraciones no es que los artículos sirvan para hacer un copy&paste de códigos sino que comprendas y aprendas la lógica y el cómo trabaja javaScript.
Y a partir de lo expuesto experimentes tú.
El autor del post y el editor del blog te animamos a que plantees tus dudas o reflexiones y que compartas tus realizaciones en base a lo expuesto en los comentarios. Recuerda que puedes incluir pens (ejemplos en Codepen.io) en ellos.