Comunidad de diseño web y desarrollo en internet

Tutorial de emoticones en campos de texto de Flash

Amigos, bienvenidos una vez mas a BricoMania, esta tarde nos dedicaremos a fabricar nuestro propio campo de texto con emoticonos[a partir de ahora emotes] Asi que explicaremos un poco como va esto, pero antes una imagen "final" para que os hagais una idea de como quedara, esta incluye mas emotes de los que tienen los ejemplos, pero es posterior y adaptada a mi necesidades, sorry

No esperes un gran campo de texto con iconos maravillos que se ajusten a todos los lados, tipos de fuentes etc etc, esto sera mas bien un "home made".


Vista previa del campo de texto con iconos

Propiedades de nuestro campo de texto :

  • El campo no soportara HTML, es decir fuera negritas, fuera italics y fuera ahref
  • Se podran meter tantos iconos como deseeas, tan facil como añadir dos datos a unos arrays
  • Los ajustes de letra, interlineado, alturas de emotes etc etc se haran a mano! [horror]
  • Los emotes seran MC's, como tales pueden ejecutar acciones [links - visto en esta version] animaciones etc etc

Materiales necesarios :

  • Flash MX04
  • Muuuuucha cabeza y paciencia [solo si se intenta mejorar]

IDEA BASE, problemas y demas


La idea base es crear un campo de texto donde al poner ciertas palabras se sustituyan por emotes. El principal problema que puede surgir es donde se ponen los emotes no? coordenadas XeY, el problema lo resolvi metiendo cada palabra en un campo de texto diferente, y ajustandola a la anterior, asi kedaban perfectos, he incluso se podian aplicar diferentes estilos a cada palabra! permitiendo el html pero habia un GRAAN problema,....... aun no lo sabeis..... seguid pensando..... al estar cada uno en campos de texto diferentes no se podia seleccionar el campo entero, esto en principio parece una tonteria pero se notaria si no se pudiese...

Si aun no cogiste lo de meter cada palabra en un bloque lee esto

Es sencillo, imaginate una seria de blokes, ahora ve apilandolos a la izquierda, los bloques se kedan uno al lado de otro, encajando perfectamente en altura, ahora imaginate a los emotes tambien como bloques. Para saber donde colocar un emote solo tendiramos que ir poniendo bloque a bloque y cuando detectemos que hay un emote pues lo soltamos ahi, como los emotes tambien tienen ancho se seguiria respetando kedando perfecto.

Ahora, ya teniendo ese sistema haremos un "duplicado" pero en un solo campo de texto, es decir, tendremos nuestro campo de texto, e iremos añadiendo palabras, en vez de emotes dejaremos espacios " " [esp] y los emotes los colocaremos teniendo como refenrencia el otro campo [el formado por bloques], no lo entendiste? es como escribir algo asi

Lorem ipsum dolor sit _____amet, consectetuer adipiscing elit. Aliquam pharetra orci non lectus. Mauris ut arcu in libero sodales feugiat. ______ Ut vel turpis in justo____cursus rhoncus. Nunc mauris lorem, cursus a, mollis_____________ eu, facilisis ut, libero. Pellentesque semper. Etiam gravida ultrices leo.

Solo que nosotros nos encargaremos de dos cosillas, que esos espacios sean los justos para poner el emote, y dos ponerlo ahi.

Problemillas

Tendremos que crear un campo de texto con la letra que queramos, dinamico y embebida [Propiedades>>Caracter] yo suelo utilizar los 95 del latin basico y edspues estos "ñÑáéíóúÁÉÍÓÚ¡'0987654321º¬€~#@|\¿?=)(/&%$·"!ª" aunque algunos se repiten saldran un total de 114 caracteres [vamos el juego completo] Esto sera para obtener un resultado mejor, tb probe a meter la fuente en la biblioteca pero no le dedike mucho tiempo asi que esto lo veo mas sencillo.

Empezando

Ahora, no os confundais, NO vamos a meter los emotes en el campo de texto, lo mas facil sera meterlo todo en un MC y despues a este enmascararlo asi lo meveremos con mayor facilidad, la otra posibilidad es saber la posicion del scroll del campo de texto, e ir moviendo los emotes de acuerdo al interlineado y altura de las fuentes [al ser mas complejo esto no lo trataremos por el momento]

Lo que haremos sera, dividir el texto en palabras, meter cada palabra en un campo de texto, pegar cada campo de texto al anterior, asi sabremos las posiciones de los emotes, por otra parte crearemos un campo de texto, en el iremos metiendo las palabras -separadas por un " " -, este ultimo sera el que se muestre. Los emotes estaran en la biblioteca, exportados en el primer frame con un "codigo"

Asi que poneros el casco, la señal de trabajando que vamos a empezar con lo serio, abrir el flash, un nuevo archivo, creamos un nuevo MC [llamado noemo], nos dirijimos dentro de el y empezamos con el codigo

_lockroot = true;
_root.createTextField("linea", 999999, 0, -32, 10, 16);
linea.autoSize = "left";
_global.ancho = 495;
lastarraylength = 0;
texto_dummy = "Lorem ipsum url=http://www.nodani.com dolor sit amet, consectetuer adipiscing elit. Vivamus adipiscing, ligula nec consectetuer consequat, arcu <br><br>lacus euismod justo, ac faucibus metus orci nec neque. Morbi quis pede. Donec pede. Nullam urna orci, dignissim :d nec, venenatis id, ultrices vitae, nulla. Quisque Vengan a CRISTALABurl=http://www.cristalab.com risus ipsum, euismod a, pellentesque nec, :Dconsequat ac, lectus. Ut ut xdxvelit. Maecenas auctor dictum quam. Vivamus in est a nulla vehicula posuere. Vestibulum vestibulum nonummy enim. Curabitur id dolor id elit interdum pharetra. Quisque tincidunt turpis non elit. Aenean libero neque, consequat nec, pellentesque ut, placerat id, libero. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.";
emotes = new Array("url=", "xD", ":D", ":rollo:");
codes = new Array("daurl", "chino", "sonrisa", "rollo");
Que hemos hecho? Hemos puesto un _lockroot mas que necesario [si no sabes lo que es F1], despues creamos el campo de texto "linea" y que sea autoSize=left, -esto hace que crezca hacia la derecha lo que sea necesario, esta cualidad la usaremos para saber en que X colocar los emotes- despues la var "ancho" [este es el ancho de nuestro campo de texto", lastarraylength es una variable donde guardaremos la longitud del ultimo array, esto nos servira para borrar los emotes si la funcion[que parsea el texto] se vuelve a llamar , despues tenemos el "texto_dummy" sacado de www.lipsum.com con algunas modificaciones para que sirva a nuestro proposito, por ultimo tenemos emotes[] y codes[], el primero son nuestras palabras clave, el segundo el codgio de exportacion de la libreria

Para hacerlo mas facil, ya que trabajamos con palabras sueltas [por lo del ajuste de linea] los emotes deberian de ir tambien cada uno en una palabras, separado por espacios, como esto es algo que nosotros podemos hacer, pero no los usuarios... lo que haremos sera PRE-Parsear el texto, es una funcion "lenta", recorreremos el texto letra a letra buscando las palabras clave, tantas veces como emotes. Nos devolvera el texto en forma de variable, asi como nuevoTexto=parseador("Visitare www.nodani.com o me mataran"); .

function parseador(texto) {
for (i=0; i<emotes.length; i++) {
for (a=0; a<texto.length-(emotes[i].length-2); a++) {
if (texto.substr(a, emotes[i].length).toLowerCase() == emotes[i].toLowerCase()) {
texto = texto.slice(0, a)+" :3m0:"+emotes[i] + texto.slice(a+emotes[i].length, texto.length);
a += 6;
}
}
}
for (a=0; a<texto.length-2; a++) {
if (texto.substr(a, 4).toLowerCase() == "<br>") {
texto = texto.slice(0, a)+" <br> "+texto.slice(a+4, texto.length);
a += 5;
}
}
return texto;
}
Si os habeis fijado, lo que hace realmente es cortar el texto donde este un emote y pegar justo delante suyo la caden " :3m0:", delante del :3m0: hay un espacio, esto hara que los emotes keden en palabras sueltas pero... que pasa con la parte de atras? bien, eso es sencillo, la palabra de atras si la dejan pegada, sera cortada y pegada en nuestra funcion, porque no lo haces tambien por detras? pues porque hay emotes que necesitaran alguna variable, por ejemplo un link hacia una url, o algun otro que vosotros penseis [no os voy a dar todo hecho Guiño .... entonces si lo puedes cortar por detras despues, porque hacerlo por delante ahora? bien sencillo, en cada palabra solo puede entrar un emote, esto no es mas que nada por comodidad [ya vereis el cacao de codigo que tengo] xq si no tendria que añadir este mismo codigo mas adelante, imaginemos algo como palabra[emote]palabra[emote]palabra[emote][emote] pues seria casi un infierno controlarlo, de esta forma kedaria en[ "-" representa un espacio] palabra - [emote]palabra - [emote]palabra - [emote] - [emote] Tambien tiene otra peculiaridad, y es que los <br> los separa completamente [por delante y por detras - formando una sola palabra] Aki si hay que tener cuidado y reparsear el texto que se kiera meter, ya que no entenderia los \n o \r ......

Ahora bien, en nuestra funcion empezaremos a declarar un estilo, unos camppos de texto y sus propiedades, asi como borrar [en caso de que hubiera] los emotes anteriores, y declarar algunas variables

/* tanto los emotes como las palabras sueltas se llamaran genericamente "t"+i, con esto borraremos los
   emotes anteriores */
for (i=0; i<lastarraylength; i++) {
_root["t"+i].removeMovieClip();
}
//llamamos al preparseador
texto = parseador(texto);
//inicializamos variables
delete un_array;
un_array = new Array();
un_array = texto.split(" ");
/* lastx sera donde empecemos a poner nuestro texto que despues desaparece el valor de 350 se puede modificar por el que querais, pero yo lo puse asi xq en principio mi Campo de Texto [a partir de ahora CT] media en principio 300 y kedaban uno al lado del otro*/
lastx = 350;
//last y deberia de ser igual a donde ponemos nuestro campo de texto "chat" ya que indicara la altura
lasty = 0;
//el estilo
estilo = new TextFormat();
//customStandard, pixel font traida de www.kadazuro.com [en su blog] si no la encontrais avisarme
estilo.font = "customStandard";
estilo.size = "8";
estilo.leading = "5";
//este sera nuestro campo de texto principal
_root.createTextField("chat", -999998, 0, 0, ancho, 1);
//esto es para saber cuanto mide un espacio en ese tipo de fuente
_root.createTextField("espacio", 999997, lastx, lasty, 10, 1);
espacio.autoSize = "left";
espacio.selectable = false;
espacio.text = " ";
espacio.setTextFormat(estilo);
linea.text = "";
linea.setTextFormat(estilo);
chat.embedFonts = true;
chat.autoSize = "center";
chat.selectable = true;
chat.multiline = true;
enblanco = espacio.textWidth;
Por ultimo comencemos con la funcion, que comentare trozo a trozo , aunque no haya muchas unidades divisibles, ya que por ejemplo todo va dentro de un gran for, lo que hace perder la pista bastante
for(i=0;i<un_array.length;i++) {
if(un_array[i]=="<br>") {
chat.htmlText += linea.text+"\n";
linea.text = "";
_root["t"+i]._x = 0;
lastx = 350;
_root["t"+i]._y = lasty+18;
lasty += 18;
} else {
Nuestro SUPER-FOR principal y ... oh dios mio ya hay cosas chungas![que va... no sabeis lo que os espera MWHAHAHAHAH BOFH] El primer condicional es por si encuentra la cadena "<br>" en la palabra, lo que significa que saltamos de linea [si veis emos aumentado lasty en 18 -que es la distancia a la que se encuentra cada linea de nuestro texto], pero no añadimos mas texto, en caso contrario ...
		if(un_array[i].indexOf(":3m0:")==-1) {
_root.createTextField("t"+i,i,lastx,lasty,10,16);
_root["t"+i].autoSize = "left";
_root["t"+i].selectable = false;
_root["t"+i].text = un_array[i];
_root["t"+i].setTextFormat(estilo);
} else {
...empezamos con lo chulo, si no esta la cadena " :3m0:" dentro de la palabra significa que no hay emotes por lo que simplemente crearemos el CT correspondiente
//hacemos un recorrido por el array de emotes para saber cual es
for (e=0; e<emotes.length; e++) {
//este if indica que hemos encontrado el emote que le corresponde
if (un_array[i].substr(5, emotes[e].length) == emotes[e]) {
/*si este emote es del tipo url= hay mas miga!!
el url= es un emotes especial, este sale mas explikado abajo pero basicamente es un Mc con un boton dentro capaz de llevarnos a la url que le digamos increible pero cierto!!*/

if (un_array[i].substr(5, emotes[e].length) == "url=") {
//final es la palabra que venga despues del emote
final = un_array[i].substring(emotes[e].length+5, un_array[i].length);
//nos traemos el emote desde la libreria y ajustamos sus Coordenadas
attachMovie(codes[e], "t"+i, i);
/* os acordais de que lastx era 350 al principio? eso es porque nuestras cajas se forman en x=350, pero nuestro texto a mostrar estara en x=0, de alli el ajuste*/
_root["t"+i]._x = lastx-350;
_root["t"+i]._y = lasty;
//variable interna que le indica la url a donde va
_root["t"+i].daweb = final;
/*en un_array[i] es donde guardamos esto "url=http://www.nodani.com" como no queremos mostrar eso, si no que dejar un espacio en blanco [el justo para que entre el emote lo ponemos a cero] */
un_array[i] = "";
/* sencillo, esto lo que ace es añadir tantos espacios como sean necesarios para dejar el espacio suficiente para el emote */
for (d=0; d<(Math.ceil(_root["t"+i]._width/enblanco)+2); d++) {
un_array[i] += " ";
}
} else {
/*este es el caso en el que el emote no sea uno del tipo url=, el funcionamiento es el mismo salvo que en este caso si que meteremos en nuestro un_array[i] el texto que va despues */
final = un_array[i].substring(emotes[e].length+5, un_array[i].length);
attachMovie(codes[e], "t"+i, i);
_root["t"+i]._x = lastx-350;
_root["t"+i]._y = lasty;
un_array[i] = "";
for (d=0; d<(Math.ceil(_root["t"+i]._width/enblanco)+2); d++) {
un_array[i] += " ";
}
un_array[i] += final;
}
}
}
Con todo esto ya tenemos nuestras cajitas con el texto correspondiente y sus emotes en su sitio.... falta meter el texto en la caja de texto principal, pero antes controlaremos algo que nadie se a dado cuenta,... los saltos de linea.... como? si si, imagina pues que tu palabra escede del CT y salta la linea... pero no tu variable que controlaba la Y de los emotes! horror!!, asi que forzaremos ese salto de linea cuando sea necesario
	if(((lastx+_root["t"+i]._width)-350)>ancho) {
		chat.text += linea.text+"\n";
linea.text = ""; _root["t"+i]._x = 0; lastx = 350; _root["t"+i]._y = lasty+18; lasty += 18; };
No creo que haga falta comentar el codigo no? de todas formas recordar lo del 350 que es de ajuste!! Asi que por ultimo colocaremos nuestro texto en la CT principal y os dejare de dar la tabarra!!
			linea.text += un_array[i]+" ";
linea.setTextFormat(estilo);
lastx = linea._width+350;
}; //end del br
};//END DEL FOR
chat.text += linea.text;
chat.setTextFormat(estilo);
chat._x = 0;
//aqui borraremos todos los CT que creamos para cada palabra y fin!!
for(i=0;i<un_array.length;i++) {
_root["t"+i].removeTextField();
};
lastarraylength = un_array.length;
altura = chat._height;

Bueno, no fin del todo....ahora falta irnos a la escena principal, enmascarar nuestro MC con todo esto dentro y crear un scroll sencillo, como creo que sabeis todos hacerlo mas o menos no lo pondre... pongo la funcion de una parte y listo, antes os dejo con el codigo del emote url

/*sin declarar la variable no furula, esto se mete DENTRO del mc, en el primer frame*/
var daweb;
bt.onRelease = function() {
getURL(daweb,"_blank");
};

Codigo completo

_lockroot = true;
_root.createTextField("linea", 999999, 0, -32, 10, 16);
linea.autoSize = "left";
_global.ancho = 495;
lastarraylength = 0;
texto_dummy = "Lorem ipsum url=http://www.nodani.com dolor sit amet, consectetuer adipiscing elit. Vivamus adipiscing, ligula nec consectetuer consequat, arcu <br><br>lacus euismod justo, ac faucibus metus orci nec neque. Morbi quis pede. Donec pede. Nullam urna orci, dignissim :d nec, venenatis id, ultrices vitae, nulla. Quisque Vengan a CRISTALABurl=http://www.cristalab.com risus ipsum, euismod a, pellentesque nec, :Dconsequat ac, lectus. Ut ut xdxvelit. Maecenas auctor dictum quam. Vivamus in est a nulla vehicula posuere. Vestibulum vestibulum nonummy enim. Curabitur id dolor id elit interdum pharetra. Quisque tincidunt turpis non elit. Aenean libero neque, consequat nec, pellentesque ut, placerat id, libero. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.";
emotes = new Array("url=", "xD", ":D", ":rollo:");
codes = new Array("daurl", "chino", "sonrisa", "rollo");
function noparse(texto) {
for (i=0; i<lastarraylength; i++) {
_root["t"+i].removeMovieClip();
}
texto = parseador(texto);
delete un_array;
un_array = new Array();
un_array = texto.split(" ");
lastx = 350;
lasty = 0;
estilo = new TextFormat();
estilo.font = "customStandard";
estilo.size = "8";
estilo.leading = "5";
_root.createTextField("chat", -999998, 0, 0, ancho, 1);
_root.createTextField("espacio", 999997, lastx, lasty, 10, 1);
espacio.autoSize = "left";
espacio.selectable = false;
espacio.text = " ";
espacio.setTextFormat(estilo);
linea.text = "";
linea.setTextFormat(estilo);
chat.embedFonts = true;
chat.autoSize = "center";
chat.selectable = true;
chat.multiline = true;
enblanco = espacio.textWidth;
for (i=0; i<un_array.length; i++) {
if (un_array[i] == "<br>") {
chat.htmlText += linea.text+"\n";
linea.text = "";
_root["t"+i]._x = 0;
lastx = 350;
_root["t"+i]._y = lasty+18;
lasty += 18;
} else {
if (un_array[i].indexOf(":3m0:") == -1) {
_root.createTextField("t"+i, i, lastx, lasty, 10, 16);
_root["t"+i].autoSize = "left";
_root["t"+i].selectable = false;
_root["t"+i].text = un_array[i];
_root["t"+i].setTextFormat(estilo);
} else {
for (e=0; e<emotes.length; e++) {
if (un_array[i].substr(5, emotes[e].length) == emotes[e]) {
if (un_array[i].substr(5, emotes[e].length) == "url=") {
final = un_array[i].substring(emotes[e].length+5, un_array[i].length);
attachMovie(codes[e], "t"+i, i);
_root["t"+i]._x = lastx-350;
_root["t"+i]._y = lasty;
_root["t"+i].daweb = final;
un_array[i] = "";
for (d=0; d<(Math.ceil(_root["t"+i]._width/enblanco)+2); d++) {
un_array[i] += " ";
}
} else {
final = un_array[i].substring(emotes[e].length+5, un_array[i].length);
attachMovie(codes[e], "t"+i, i);
_root["t"+i]._x = lastx-350;
_root["t"+i]._y = lasty;
un_array[i] = "";
for (d=0; d<(Math.ceil(_root["t"+i]._width/enblanco)+2); d++) {
un_array[i] += " ";
}
un_array[i] += final;
}
}
}
}
if (((lastx+_root["t"+i]._width)-350)>ancho) {
chat.text += linea.text+"\n";
linea.text = "";
_root["t"+i]._x = 0;
lastx = 350;
_root["t"+i]._y = lasty+18;
lasty += 18;
}
linea.text += un_array[i]+" ";
linea.setTextFormat(estilo);
lastx = linea._width+350;
}
//end del br
}
//END DEL FOR
chat.text += linea.text;
chat.setTextFormat(estilo);
chat._x = 0;
for (i=0; i<un_array.length; i++) {
_root["t"+i].removeTextField();
}
lastarraylength = un_array.length;
altura = chat._height;
}
function parseador(texto) {
for (i=0; i<emotes.length; i++) {
for (a=0; a<texto.length-(emotes[i].length-2); a++) {
if (texto.substr(a, emotes[i].length).toLowerCase() == emotes[i].toLowerCase()) {
texto = texto.slice(0, a)+" :3m0:"+emotes[i] + texto.slice(a+emotes[i].length, texto.length);
a += 6;
}
}
}
for (a=0; a<texto.length-2; a++) {
if (texto.substr(a, 4).toLowerCase() == "<br>") {
texto = texto.slice(0, a)+" <br> "+texto.slice(a+4, texto.length);
a += 5;
}
}
return texto;
}
noparse(texto_dummy);

Algunas direcciones utiles

Generador de texto "lorem ipsum"
Ejemplo online Solo funcionan los emotes url=direccion xD y :D
Mi wEB

ICEM4N
http://www.nodani.com/

¿Sabes SQL? ¿No-SQL? Aprende MySQL, PostgreSQL, MongoDB, Redis y más con el Curso Profesional de Bases de Datos que empieza el martes, en vivo.

Descargar Archivo

Publica tu comentario

El autor de este artículo ha cerrado los comentarios. Si tienes preguntas o comentarios, puedes hacerlos en el foro

Entra al foro y participa en la discusión

o puedes...

¿Estás registrado en Cristalab y quieres
publicar tu URL y avatar?

¿No estás registrado aún pero quieres hacerlo antes de publicar tu comentario?

Registrate