Es hora de otro Post ! en servicio de la comunidad...
Hoy como casi cualquier dia, comenze a curiosear por los Foros, hasta que me tope con un Post, que en especial me entretuvo un rato (si no el post en si, la pagina que postearon)... Asi es que decidi abrir el tan empolvado Flash ! Tenia mucho tiempo sin usar la API de Flash, y entre mis curioseos nacio esto:...
Y no tengo NPI de que funcionalidad tenga, pero es alucinante ! [12 fps]
Tan solo utiliza un For para trazar un monton de lineas especificados en los valores de los campos de Texto, y que con curveTo y lineTo son dirigidas principalmente con un Listener hacia la poscicion del Raton...
Pero me di cuenta de que comenzaba a perder el tiempo, asi es que retome el Tema...
Hoy aprendi algo nuevo... No hay conozco una manera para detectar el tiempo que lleva un Elemento cualquiera dentro de un Array... Es decir, obtener cuanto tiempo ha pasado desde que agregue el ultimo dato... Es por eso que recurri a controlarlo mediante MC´s, cosa que no termina de convencerme del todo... Y que mas adelante cambiare...
Este es el resultado del Prototipo, de donde espero obtener sus futuras versiones, y que estas sean aun mejor y mucho mas "Bonitas":...
Ejemplo sin detalles ni nada en especial [12 fps]
Notese que se esta reproduciendo a 12 Fps, por lo que si quieres ver el movimiento mas Fluido y menos Brusco, tendras que aumentar esta masomenos a 25 Fps... Ademas de que puse una Triste linea Azul, solo para hacer notar su funcionamiento y no diseño, mas adelante pondre algo mas "Bonito"
El codigo empleado el algo muy simple la verdad, y conociendo la Comunidad algo muy facil de optimizar... Esto es solo para dar una idea !
Primero vamos a Agregar a nuestro KeyFrame principal, los 2 Array a utilizar, donde se van a estar guardando las posciciones del Mouse... En este caso xArray y yArray:..
Código :
var xArray:Array = new Array ();
var yArray:Array = new Array ();
Despues para no tener que recurrir a un alentizador EnterFrame, utilizamos un Listener para estar actualizando la poscicion del Raton el cual Ironicamente llamaremos mouseMove...
Ahora, ya que YO dezconosco otra manera mejor de hacerlo, recurri a los MC´s para controlar el tiempo que tardan en desaparecer y eliminarse del Array (tal y como explique arriba), agregue esto a un MC vacio, con nombre de Instancia "brushClip":..
NOTA: Lo unico que hace el codigo es checar si el nombre no es "brushClip" como deveria, significa que este es uno de los MC´s duplicado, por lo tanto cumple su Funcion; desaparecer en un lapso de Tiempo...
Ahora en la Funcion del Listener agregas este trozo de codigo encargado de Duplicar MC´s, basandose en los Array´s
Ahora por ultimo agregamos la funcion encargada de Trazar las lineas respecto a los MC´s ya creados... Algo asi como unir los puntitos... Dejando algo asi:..
Código :
onEnterFrame = function( ){//-
createEmptyMovieClip("lineClip", 0);
lineClip.lineStyle(1, 0x006699, 50);
lineClip.moveTo(xArray[0], yArray[0]);
for(var i:Number = 0; i < xArray.length; i++){lineClip.lineTo(xArray[i], yArray[i]);}//- For
_root.lineClip.setMask(maskClip);};//- Function
______________ Por lo que al final debe quedarte algo similar a esto en un KeyFrame:...
Código :
var mouseMove:Object = new Object();
var xArray:Array = new Array ();
var yArray:Array = new Array ();
//-
mouseMove.onMouseMove = function( ){//- trace("_z: " + zArray[zArray.length -1]);
xArray.push(_xmouse); yArray.push(_ymouse);
duplicateMovieClip(_root.brushClip, "brush"+ xArray.length, xArray.length);
_root["brush"+ xArray.length]._x = xArray[xArray.length - 1];
_root["brush"+ xArray.length]._y = yArray[yArray.length - 1];}//- Function
onEnterFrame = function( ){//-
createEmptyMovieClip("lineClip", 0);
lineClip.lineStyle(1, 0x006699, 50);
lineClip.moveTo(xArray[0], yArray[0]);
for(var i:Number = 0; i < xArray.length; i++){lineClip.lineTo(xArray[i], yArray[i]);}//- For
};//- Function
//-
Mouse.addListener(mouseMove);
Bueno, puestos a colaborar en el tema pienso que en el problema de los dibujos "finitos" si aumentemos el fps conseguimos más continuidad pero perdemos "curvatura" , se nos notará el "temblor de pulso" como se aprecia al dibujar en tu ejemplo de arriba. Para conseguir difuminar esos saltos esto es mejor: Añadir un par de lineas de código para una interpolación. Dibujamos un array de curvas tangentes entre sí y definidas por los puntos tomados por el mouse en cada llamada. Código simple:
Código :
import flash.geom.*;
ln=[];
dib = createEmptyMovieClip("dib",0);
setInterval(capt,50); //intervalo de escritura.
setInterval(capt2,20);// intervalo de borrado.
function capt(){
dib.clear();
for(n=0; n<Math.min(ln.length,30)-2; n++){
p0= Point.interpolate(ln[n+2], ln[n+1], .5);
p1= Point.interpolate(ln[n+1], ln[n], .5);
dib.lineStyle(10 , 0x88cc33, 100); // grueso de linea, color, etc...
// si se quiere "perspectiva" del movimiento cambiar por la linea siguiente:
//dib.lineStyle(20 + ln[n].y/20 , 0x88cc33, 100);
dib.moveTo(p0.x, p0.y);
dib.curveTo(ln[n+1].x, ln[n+1].y, p1.x, p1.y);
// añadir la siguiente linea para que no desaparezca el punto al parar:
//if(n==0) dib.lineTo(ln[n].x+1, ln[n].y);
}
ln.pop();
}
function capt2(){if(ln.length<100) ln.unshift(new Point(_xmouse ,_ymouse));}
que nos ejecuta lo siguiente a 20fps:
Para entender su "movimiento" en este ejemplo vemos como "dibuja" poniendo como una linea negra la salida sin interpolación y en rojo la interpolada. Es como si hiciéramos un zoom del movimiento de ratón.
Este es el código para el ejemplo anterior:
Código :
import flash.geom.*;
Pa=[]; // array de puntos
puntos = 10; //numero de puntos a visualizar a la vez
i_val = 100;//intervalo de frames
ajuste = .5;
//(de 0 a 1) acercamiento al punto, si - ó + más ajuste y menor curvatura.
createEmptyMovieClip("visor",0);
onMouseDown = function(){cinta();id= setInterval(cinta,i_val);}
onMouseUp = function(){clearInterval(id)}
function cinta(){
long = Pa.unshift(new Point(_xmouse ,_ymouse));//tomamos punto nuevo.
visor.clear();
for(n=0; n<puntos; n++){
//código para linea normal:
visor.lineStyle(1, 0, 100); // linea negra.
visor.moveTo(Pa[n].x, Pa[n].y);
visor.lineTo(Pa[n+1].x, Pa[n+1].y);
//código para curva tangente:
p0= Point.interpolate(Pa[n+2], Pa[n+1], ajuste);
p1= Point.interpolate(Pa[n+1], Pa[n], ajuste);
visor.lineStyle(3, 0xff0000, 60); // linea roja y semitransparente.
if(n==0){visor.moveTo(Pa[n].x,Pa[n].y);visor.lineTo(p1.x, p1.y);}
visor.moveTo(p0.x, p0.y);
visor.curveTo(Pa[n+1].x, Pa[n+1].y, p1.x, p1.y);
}
if(long>puntos+1)Pa.pop(); //eliminando el último punto.
}
Ambos se basan en dibujar un array de n puntos cada vez y borrado total, aunque podemos usar otro camino que solo dibuja una linea (un solo punto) en cada llamada y borra solo en punto final (sistema push-pull). Este es un ejemplo a 20 fps de esta manera, como ves no lleva bucle FOR , dibuja el nuevo y borra el de atrás:
Código :
import flash.geom.*;
ln=[];
lin=8; // longitud de la cinta (puntos tomados)
dib = createEmptyMovieClip("dib",0);
setInterval(capt,50);
function capt(){
lon= ln.unshift( new Point(_xmouse ,_ymouse));
p0= Point.interpolate(ln[2], ln[1],.5);
p1= Point.interpolate(ln[1], ln[0],.5);
dib.lineStyle(3,0xff00ff,100);
dib.moveTo(p0.x, p0.y);
dib.curveTo(ln[1].x,ln[1].y,p1.x,p1.y);
dib.lineStyle(3,0xffffff,100);
p0= Point.interpolate(ln[lin], ln[lin-1],.5);
p1= Point.interpolate(ln[lin-1], ln[lin-2],.5);
dib.moveTo(p0.x, p0.y);
dib.curveTo(ln[lin-1].x,ln[lin-1].y,p1.x,p1.y);
}
Así dibuja este código:
Por último, pongo el código mas simple (base) que ejecuta el efecto de la página que postearon y que citas en el el origen del este tema:
Apunte: Existe otra manera (la más fina y elegante) que crea el perfil de la linea como un sólido y la rellena con lo que queramos. Se basa en crear doble punto a partir del tomado del mouse y un poco desplazado a ambos lados del mouse.
En cuanto a saber el tiempo: Cuando se coloca en el array el nuevo valos , también tomamos en una variable el valor getTimer() y vamos comparando el actual getTimer con el guardado.
Ahora podemos seguir avanzando en el tema un poco más...
Chicos muy interesante el código, yo creo que se podría crear un nuevo apartado en los foros de Clab para la ''Experimentación'' no creen? y que cada uno vaya aportando su granito de arena, si el tema le interesa.
Es en momentos como estos en los que pienso donde puedo conseguir una Etiqueta que diga algo como "Teseo F@N" !
En mi ejemplo si aumentabas el grosor hasta 5 por ejemplo, se disimulaba ese temblor en el pulso... Pero me parece mas que genial tu solucion utilizando curveTo y no solo lineTo, ya que son esas bofetadas ahora 2, que llegan sin previo aviso y ayudan a crecer... Bravo !
Quitaria del Post mi ejemplo y asi me ahorro espacio en Host, pero me parece una buena manera de mostrar lo que no se debe hacer, ademas de que muestra el error con el pulso que causa...