Disporre il testo su una circonferenza con jQuery

Disporre il testo su una circonferenza con jQuery
Freia

Con questo articolo voglio spiegarvi un algoritmo, da me realizzato in jQuery, che permettere di disporre del testo su una circonferenza o, volendo generalizzare, su una curva qualsiasi.

La logica che sta dietro all’algoritmo è abbastanza lineare:

  1. Dispongo le lettere sulla circonferenza.
  2. Ruoto le lettere in modo tale da orientarle verso il centro.
passi

Come avrete sicuramente capito per raggiungere il mio obiettivo ho le necessità di giocare con qualche funzione trigonometrica di cui mi servirò per risalire alle coordinate delle singole lettere. I codici HTML e CSS non contengono nulla di particolarmente importante: il processo estrae il testo dall’elemento span da noi indicato e lo elabora. 

Codice Html e CSS

<body>
	<p class="testo n1">Testo sulla circonferenza </p>
	<label class="lettera"></label>
	<div id="circle">
	</div>
</body>

Codice CSS stile:

#circle
{
	width:500px;
	height:500px;
	border:1px solid green;
}
#circle span
{
	position: absolute;
	text-align: center;
}

.lettera,.testo
{
	display: none;
}

Passiamo invece al corpo dell’algoritmo: qui viene definita la funzione newCircle() a cui dobbiamo passare:

  • elem : l’elemento da cui estrarre il testo
  • r : il raggio
  • dim: la dimensione del font
  • font : il tipo di font
  • origineX : la coordinata X dell’origine della circonferenza
  • origineY : la coordinata Y dell’origine della circonferenza

Vi starete chiedendo, c’era bisogno anche delle caratteristiche del font?

Ebbene si, e ve lo spiego subito. Nella disposizione sulla circonferenza della lettera ho la necessità di conoscere le dimensioni di questa, dimensioni che variano in base al tipo di font e alla dimensione.

Entriamo nel dettaglio della funzione.

  1. Mi ricavo la circonferenza dal raggio secondo la funzione c = 2πR
  2. Calcolo la distanza tra una lettera e l’altra dividendo la circonferenza per il numero delle lettere totali
  3. Dalla distanza mi ricavo l’angolo che corrisponde alla distanza attraverso una sempice proporzione:circonferenza : 360 = distanza : angolo
  4. A questo punto ho bisogno dell’altezza delle lettere quando utilizzo font e dimensioni ricevuti: le lettere in quelle condizioni hanno una altezza fissa (che dobbiamo ricavarci)  e una larghezza variabile che ha come valore massimo dim. Per ricavare l’altezza  inserisco una lettera qualsiasi in uno span a cui assegno le determinate caratteristiche di font e la estraggo.
  5. Ora ho tutti i dati necessari per calcolarmi le coordinate di ciascuna lettera :parte dunque un ciclo in cui viene processata ogni lettera che verrà disposta nelle coordinate x e y: abbiamo l’angolo e il raggio quindi per ricavarle basterà utilizzare le funzioni seno e coseno.
  6. Non resta che ruotare ora le lettere: come abbiamo detto le vogliamo rivolte verso il centro della circonferenza, in termini più matematici vogliamo che la base della lettera risulti perpendicolare al raggio: l’angolo di rotazione sarà uguale a 90° più i gradi dell’angolo che crea la lettera (che è l’angolo che ci eravamo già ricavati).

Per concludere vi mostro il codice:

Codice jQuery

$(document).ready(function() {	

	var livello = 1;

	var origineX = $('#circle').position().left + ($('#circle').width()/2);
	var origineY = $('#circle').position().top + $('#circle').height()/2;

	newCircle('.n1',150,'40','Arial Black',origineX,origineY);

	function newCircle(elem,r,dimensione,font,origineX,origineY) {

	// variabili circonferenza
	var raggio = r + dimensione/2;
	var circonferenza = 2*Math.PI*raggio;

	// variabili testo
	var testo = $(elem).html();
	var lunghezzaTesto =   testo.length;
	var i = 0;
	var carattere = '';
	var lettera = '';

	// calcoli di posizione
	var distanza = circonferenza / lunghezzaTesto;

	// circonferenza : 360 = distanza : angolo
	var angolo = ((360*distanza)/circonferenza)* Math.PI / 180 ;
	var angolo_new = angolo;
	// mi calcolo le coordinate
	var x = 0;
	var y = 0;	
	// dimensioni lettera
	var width = 0;
	var height = 0;
	var fontsize = dimensione + 'px';
	// calcolo della rotazione delle lettere
	var rotazione = 0;
	// creo span test per avere le giuste dimensioni
	$('.lettera').css("fontFamily", font);
	$('.lettera').css("fontSize",fontsize);

	// estraggo le dimensioni
	$('.lettera').html('I'); // lettera a caso, l'altezza è sempre uguale indipendentemente dalla lettera
	var height_let = $('.lettera').height(); // mi serve per le dimensioni della cornice -> sarà la stessa anche con una rotazione di 180 gradi
	$('#circle').append('<div class="cerchio num'+livello+'"></div>');

	// stile della cornice
	var f = (raggio*2+height_let)+'px';
	$('.cerchio.num'+livello).css('width',  f );
	$('.cerchio.num'+livello).css('height', f );

	for (i = 0; i<lunghezzaTesto; i++)
	{
		// ricavo la lettera
		carattere = testo.charAt(i);
		// ricavo l'angolo -> ovviamente va aggiunto alla somma di quelli precedenti
		angolo_new = angolo*(i+1);
		// calcolo l'angolo di
		rotazione = 90 +  (angolo_new*180/Math.PI); // l’angolo mi serve in deg

		// mi ricavo x e y tenendo conto dell’origine
		x = raggio*Math.cos(angolo_new) + origineX;
		y = raggio*Math.sin(angolo_new) + origineY;

		// i caratteri di spazio non devono essere ignorati		
		if (carattere == ' '){ carattere = '&nbsp;'}

		lettera = '<span class="liv'+livello+'" id="let'+i+'"style="  left:'+(x - dimensione/2)+'px; top:'+(y - dimensione/2)+'px; width:'+fontsize+'; transform: rotate('+rotazione+'deg); -webkit-transform: rotate('+rotazione+'deg); -o-transform: rotate('+rotazione+'deg); -moz-transform: rotate('+rotazione+'deg);">'+carattere+'</span>';

		// output nel cerchio
		$('.cerchio.num'+livello).append(lettera);
		$('.cerchio.num'+livello).css('fontFamily',font);
		$('.cerchio.num'+livello).css('fontSize', fontsize);
}

	livello++;
	}

	});

In questo caso ho creato un elemento circle e ho passato alla funzione il centro di questo come coordinate di origine. Vi faccio notare inoltre che se volessimo che le lettere fossero rivolte dalla parte opposta (con la “testa” rivolta verso il centro) basterebbe aggiungere 180 all’angolo di rotazione.

finale

Conclusioni e note finali

ATTENZIONE! Si faccia attenzione a questo passaggio:

lettera = ‘<span id=”let’+i+'”style=”  left:’+(x – dimensione/2)+’px; top:’+(y – dimensione/2)+’px; width:’+fontsize+’; transform: rotate(‘+rotazione+’deg); -webkit-transform: rotate(‘+rotazione+’deg); -o-transform: rotate(‘+rotazione+’deg); -moz-transform: rotate(‘+rotazione+’deg);”>’+carattere+'</span>’;

Qui attribuisco a qualsiasi lettera la larghezza massima, questo perché se non lo facessi le lettere più grandi (‘m’, ‘w’) finirebbero per sovrapporsi alle altre più strette. Assegnando a tutti la larghezza massima e allineandole al centro (si veda il foglio di stile) garantisco una migliore distribuzione sulla circonferenza. Nonostante ciò è sempre opportuno passare alla funzione principale un corretto rapporto tra raggio e dimensioni del font in modo tale da non avere indesiderate sovrapposizioni.

NOTA BENE

Questo non è l’unico metodo per raggiungere il nostro obiettivo, ce n’è qualche altro anche decisamente più semplice e meno prolisso. Tuttavia con questo articolo ho voluto proporvi un metodo più matematico e, se vogliamo, “geometrico”.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.