Tip: Rotar MovieClip tomando como eje su centro

danii . lunes 27 de septiembre de 2010. a las 12:08

Éste es un pequeño tip muy útil si alguna vez os habéis visto en la necesidad de rotar MovieClips por programación utilizando como eje de rotación su centro, pero el punto de registro de dicho movieclip está en otro sitio. Por ejemplo, en esta demo el punto rojo marca la posición tanto del origen de coordenadas como del punto de registro (el eje de rotación, vamos):

Get Adobe Flash player

Como podéis ver, el movieclip de la derecha rota sobre su punto de registro como es normal, sin embargo que el de la izquierda sigue el comportamiento que queremos: rota sobre su centro «geométrico». Para conseguir esto seguiremos dos sencillos pasos:

Primero, utilizamos el método getRect de la clase base DisplayObject, utilizando como parámetro el stage para trabajar con coordenadas globales. Este método nos devuelve el rectángulo «contenedor» de un objeto gráfico (podéis ver a qué me refiero en la demo, son los recuadros outline rosa y verde que engloban al MovieClip). El centro de dicho rectángulo contenedor coincide con el centro del objeto gráfico sin importar cómo esté rotado y posicionado internamente, lo cual nos ahorra un poco de tediosa trigonometría. Como curiosidad, he incluido dos outline: uno rosa que se va actualizando conforme el MovieClip rota y otro verde estático, el inicial. Puesto que los centros de ambos rectángulos contenedores coinciden continuamente (como se aprecia por las diagonales trazadas), realmente solo es necesario almacenar el inicial.

Y ahora en el segundo paso la «magia» que hace que este proceso funcione consiste en realizar una translación sobre la matriz de transformación del MovieClip para colocarlo directamente sobre el centro de su rectángulo contenedor, rotarlo (ahora su eje de rotación será dicho centro) y a continuación volver a trasladarlo a su posición inicial. Et voilà!

var r:Rectangle = forma_mc.getRect(stage);

var centro:Point = new Point(r.x+r.width/2,r.y+r.height/2);

//m matriz de transformación del movieclip
var m:Matrix=forma_mc.transform.matrix;

//translación al centro
m.tx -= centro.x;
m.ty -= centro.y;

//rotación (en radianes)
m.rotate(angle*(Math.PI/180));

//traslación final, a su posición de partida
m.tx += centro.x;
m.ty += centro.y;

//y aplicamos la matriz de transformación sobre el movieclip
forma_mc.transform.matrix=m;

Etiquetas: , , ,

7 Comentarios
» Feed RSS de los Comentarios

  1. Marcos dice:

    Frikis!!!

    Pero útil coñe. Porque anda que en flash no te andas comiendo la bola a la hora de crear un clip en tiempo de diseño si ponerle el centro en la esquina superior izquierda o en el centro geométrico en función de las operaciones que luego vas a hacer con el :).

    Pa la saca con él!

  2. danii dice:

    Me alegro que lo encuentres útil 😉

    Lo peor es cuando es un diseñador externo quien te pasa los flas y todos los contenidos de los MovieClips están posicionados en lugares absurdos… me negué rotundamente a reposicionarlos todos, y de ahí surgió la idea/necesidad de este post!

  3. Marcos dice:

    Eso es… madre mía cuanto tiempo se ahorraría si algunos diseñadores pudieran ver por un momento los problemas de los programadores por cosas tan simples como poner el punto de registro donde toca 🙂

    Muy buena solución y la demo genial.

  4. Elkin Siabato dice:

    Me parece muy bueno tu tip… seguro lo utilizaré!.

    Muchas gracias.

  5. tsk dice:

    Hola!

    Genial el tip!. Una pregunta, serviría el «truco» para cualquier otra propiedad a parte de la rotación?, por ejemplo, escalar o cambiar el tamaño del clip en partiendo de su centro?.

    Gracias!

  6. danii dice:

    Hola tsk, perdona por la tardanza en contestar, te confirmo que este «truco» sirve para todas las propiedades controladas por la matriz de transformación, es decir translación, rotación, escalado (que es el por el que me preguntas) y también sesgado (skewing).

    Para escalar es muy sencillo ya que, al igual que la rotación, el objeto matriz de transformación tiene un método (llamado scale) que la controla, en este caso recibe 2 parámetros para el escalado en el eje x y en el eje y:

    var m:Matrix=forma_mc.transform.matrix;
    m.scale(escala_x, escala_y);

  7. Bea dice:

    Hola, muy bueno el tip pero yo de matrices y tal no entiendo gran cosa. El caso es que estaba intentando usar el tip para rotar un objeto sobre el centro de otro y no lo consigo. Podrías poner un ejemplo de eso??

Enviar comentario