É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):
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;
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!
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!
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.
Me parece muy bueno tu tip… seguro lo utilizaré!.
Muchas gracias.
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!
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);
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??