I am keeping this on my blog only to be able to not lose it.

The explanation of this class is at: http://web.2point1.com/2008/04/13/scale-rotate-around-an-arbitrary-centre, and any usage must be credited to that blog’s owner, Tim Whitlock.

/**
 * File containing class example.VirtualCentreSprite
 * @author Tim Whitlock
 */ 
package example { 
    
   import flash.display.Sprite; 
   import flash.geom.Point; 
   import flash.geom.Matrix; 
    
   /**
    * Simple sprite class that supports scaling and rotating around an arbitrary centre point
    */ 
   public class VirtualCentreSprite extends Sprite { 
 
      /**
       * Scale around an arbitrary centre point
       * @param Number local horizontal offset from 'real' registration point
       * @param Number local vertical offset from 'real' registration point
       * @param Number relative scaleX increase; e.g. 2 to double, 0.5 to half
       * @param Number relative scaleY increase
       */ 
      protected function scaleAround( offsetX:Number, offsetY:Number, absScaleX:Number, absScaleY:Number ):void { 
         // scaling will be done relatively 
         var relScaleX:Number = absScaleX / this.scaleX; 
         var relScaleY:Number = absScaleY / this.scaleY; 
         // map vector to centre point within parent scope 
         var AC:Point = new Point( offsetX, offsetY ); 
         AC = this.localToGlobal( AC ); 
         AC = this.parent.globalToLocal( AC ); 
         // current registered postion AB 
         var AB:Point = new Point( this.x, this.y ); 
         // CB = AB - AC, this vector that will scale as it runs from the centre 
         var CB:Point = AB.subtract( AC ); 
         CB.x *= relScaleX; 
         CB.y *= relScaleY; 
         // recaulate AB, this will be the adjusted position for the clip 
         AB = AC.add( CB ); 
         // set actual properties 
         this.scaleX *= relScaleX; 
         this.scaleY *= relScaleY; 
         this.x = AB.x; 
         this.y = AB.y; 
      } 

      /**
       * Rotate around an arbitrary centre point
       * @param Number local horizontal offset from 'real' registration point
       * @param Number local vertical offset from 'real' registration point
       * @param Number absolute rotation in degrees 
       */ 
      protected function rotateAround( offsetX:Number, offsetY:Number, toDegrees:Number ):void { 
         var relDegrees:Number = toDegrees - ( this.rotation % 360 ); 
         var relRadians:Number = Math.PI * relDegrees / 180; 
         var M:Matrix = new Matrix( 1, 0, 0, 1, 0, 0 ); 
         M.rotate( relRadians ); 
         // map vector to centre point within parent scope 
         var AC:Point = new Point( offsetX, offsetY ); 
         AC = this.localToGlobal( AC ); 
         AC = this.parent.globalToLocal( AC ); 
         // current registered postion AB 
         var AB:Point = new Point( this.x, this.y ); 
         // point to rotate, offset position from virtual centre 
         var CB:Point = AB.subtract( AC ); 
         // rotate CB around imaginary centre  
         // then get new AB = AC + CB 
         CB = M.transformPoint( CB ); 
         AB = AC.add( CB ); 
         // set real values on clip 
         this.rotation = toDegrees; 
         this.x = AB.x; 
         this.y = AB.y; 
      } 
   } 
}

– 30 –

Advertisements