Comunidad de diseño web y desarrollo en internet online

Clase MouseGestures en Actionscript 2

Una de mis extensiones favoritas de Firefox es Mouse Gestures, que permite navegar usando gestos del ratón (por ejemplo, mover el ratón hacia la izquierda hace que vayas atrás).
Posiblemente es la extensión que más tiempo me ahorra al navegar (y la que más me hace extrañar mi ordenador cuando estoy navegando desde fuera).
Bueno, el caso es que cuando uno quiere un proyecto en flash realmente usable, vendría muy bien poder incorporar algo como eso, que en flash tendría la ventaja de no depender del navegador que se use y las extensiones instaladas (aunque la extensión de Firefox no va sobre flash).

Lo que hace esta clase es crear un MovieClips que dibujan los movimientos del ratón cuando presionamos el botón izquierdo y nos encontramos sobre un clip padre (_root por defecto) que definimos en el constructor. A partir de allí captura los gestos y con el método addGestureHandler, cuando el gesto que hemos hecho coincida, podemos definir una función que se ejecute en un ámbito determinado además de poder añadirle una descripción.
Los gestos se representan con un array que contiene números, que serían las direcciones, como en un móvil para desplazarse desde la tecla 5:


Para que funcione tendrán que usar mi clase Trig, que pueden descargar aquí (y ponen el archivo Trig.as en la misma carpeta que esta clase).

Código :

/********************* Clase MouseGestures,******************/
/*Para crear una navegación basada en 
los movimientos del ratón.*/
/*importamos las clases necesarias. Pueden descargar y aprender sobre la clase Trig
en la siguiente dirección:
http://www.cristalab.com/tutoriales/177/trigonometria-en-flash-y-clases
*/
import Trig;
import flash.geom.*;
import mx.utils.Delegate;
class MouseGestures {
   //La longitud que tiene que tener 
   public var gestureLength:Number = 40;
   //El tiempo en milisegundos que tienen que pasar para que se cancele el gesto
   public var timeOff:Number = 2000;
   //Esto se invoca cada vez que hay un único gesto (completo no, que para eso está la función addGestureHandler.
   public var onGesture:Function;
   //Esto se invoca cuando se termina un gesto.
   public var onGestureEnd:Function;
   //
   //
   //
   //
   private var lines:MovieClip;
   private var clip:MovieClip;
   private var parent:MovieClip;
   private var cGestures:Array = [];
   private var containerRect:Rectangle;
   //Los números van como en un teléfono al que le han quitado el 5.
   private var nums:Array = [2, 3, 6, 9, 8, 7, 4, 1];
   //El array que contendrá las funciones.
   private var functions:Array = [];
   public function get listeners():Array {
      return functions;
   }
   public function get currentGestures():Array {
      return cGestures;
   }
   //Variables privadas varias
   private var mainStyle:Array = [2, 0, 100, null, null, null, null, null];
   private var secondStyle:Array = [1, 0xccccee, 100, null, null, null, null, null];
   private var lastPoint:Point;
   private var lastLine:Point;
   private var onMouseMove:Function;
   private var interval:Number = 0;
   //
   //
   //
   //Constructor:
   //Las líneas se dibujarán dentro del clip que indiquemos como target 
   //y sólo si están en el rectámgulo.
   function MouseGestures(target:MovieClip, rect:Rectangle) {
      //Parámetros opcionales
      if (target == undefined) {
         target = _root;
      }
      if (rect == undefined) {
         if (target == _root) {
            rect = new Rectangle(0, 0, Stage.width, Stage.height);
         } else {
            rect = new Rectangle(0, 0, target._width, target._height);
         }
      }
      parent = target;
      containerRect = rect;
      lines = target.createEmptyMovieClip("$MouseLines", target.getNextHighestDepth());
      clip = target.createEmptyMovieClip("$MouseGestures", target.getNextHighestDepth());
      Mouse.addListener(this);
   }
   //Un montón de código raro...
   private function onMouseDown():Void {
      //El manejo de los lineStyles apesta...
      clip.lineStyle(mainStyle[0], mainStyle[1], mainStyle[2], mainStyle[3], mainStyle[4], mainStyle[5], mainStyle[7], mainStyle[7]);
      lines.lineStyle(secondStyle[0], secondStyle[1], secondStyle[2], secondStyle[3], secondStyle[4], secondStyle[5], secondStyle[6], secondStyle[7]);
      var pt:Point = new Point(parent._xmouse, parent._ymouse);
      lastPoint = pt.clone();
      lastLine = pt.clone();
      clip.moveTo(pt.x, pt.y);
      lines.moveTo(pt.x, pt.y);
      this.onMouseMove = function():Void  {
         clearInterval(interval);
         interval = setInterval(this, "clearAll", timeOff);
         pt = new Point(parent._xmouse, parent._ymouse);
         if (containerRect.contains(pt.x, pt.y)) {
            clip.lineTo(pt.x, pt.y);
            var dist:Number = Point.distance(lastPoint, pt);
            if (dist>gestureLength) {
               var angle:Number = (Trig.hallarAngulo(pt, lastPoint)+382.5)%360;
               var fact:Number = Math.floor(angle/45);
               var finalAngle:Number = fact*45;
               var finalPoint:Point = Trig.hallarPunto(finalAngle, Point.distance(lastLine, pt), lastLine);
               lastLine = finalPoint.clone();
               lines.lineTo(finalPoint.x, finalPoint.y);
               var gesture:Number = nums[Math.floor(fact)];
               if (gesture != cGestures[cGestures.length-1]) {
                  cGestures.push(gesture);
                  onGesture(evalGesture());
               }
               lastPoint = pt.clone();
            }
         }
      };
   }
   private function onMouseUp():Void {
      gestureMethod();
      clearAll();
   }
   //
   //
   //
   //
   //Función para añadir funciones.
   public function addGestureHandler(gests:Array, scope:Object, func:Function, desc:String):Number {
      functions.push({handler:Delegate.create(scope, func), gestures:gests, description:desc});
      return functions.length-1;
   }
   //
   //
   //
   //
   //Funciones para los tipos de línea
   public function mainLineStyle() {
      var ln:Number = arguments.length;
      for (var i:Number = 0; i<ln; i++) {
         mainStyle[i] = arguments[i] != undefined ? arguments[i] : null;
      }
   }
   public function secondLineStyle() {
      var ln:Number = arguments.length;
      for (var i:Number = 0; i<ln; i++) {
         secondStyle[i] = arguments[i] != undefined ? arguments[i] : null;
      }
   }
   //
   //
   //
   //Funciones privadas
   private function gestureMethod() {
      for (var a in functions) {
         if (cGestures.toString() == functions[a].gestures.toString()) {
            functions[a].handler();
         }
      }
   }
   private function evalGesture() {
      var ln = functions.length;
      for (var i:Number = 0; i<ln; i++) {
         if (cGestures.toString() == functions[i].gestures.toString()) {
            return functions[i];
         }
      }
      return null;
   }
   private function clearAll():Void {
      onGestureEnd(evalGesture())
      clip.clear();
      lines.clear();
      clearInterval(interval);
      this.onMouseMove = null;
      cGestures = new Array();
   }
}


Y pueden probarla poniendo el siguiente código en flash:

Código :

import MouseGestures;
var mg:MouseGestures = new MouseGestures();
mg.mainLineStyle(1, 0xff00ff);
var mc:MovieClip = this.createEmptyMovieClip("mc", 999);
var txt:TextField = this.createTextField("txt", 1000, 100, 100, 200, 50);
//
//
//
mc._x = 200;
mc._y = 200;
mc.beginFill(0xff0000);
mc.lineTo(0, 100);
mc.lineTo(100, 100);
mc.lineTo(100, 0);
mc.lineTo(0, 0);
//
//
//
function left() {
   this._x -= 10;
}
function right() {
   this._x += 10;
}
function biggerSize() {
   this._xscale += 10;
   this._yscale += 10;
}
//
//
mg.addGestureHandler([4], mc, left, "Mover a la izquierda");
mg.addGestureHandler([6], mc, right, "Mover a la derecha");
mg.addGestureHandler([8, 6], mc, biggerSize, "Aumentar tamaño");
mg.onGesture = function(gesture:Object) {
   txt.text = gesture != null ? gesture.description : "Esto no hace nada";
};
mg.onGestureEnd = function() {
   txt.text = "";
};


Que quedaría así:

¿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.

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