1. /**
  2.  * File containing class example.VirtualCentreSprite
  3.  * @author Tim Whitlock
  4.  */ 
  5. package example { 
  6.     
  7.    import flash.display.Sprite; 
  8.    import flash.geom.Point; 
  9.    import flash.geom.Matrix; 
  10.     
  11.    /**
  12.     * Simple sprite class that supports scaling and rotating around an arbitrary centre point
  13.     */ 
  14.    public class VirtualCentreSprite extends Sprite { 
  15.  
  16.       /**
  17.        * Scale around an arbitrary centre point
  18.        * @param Number local horizontal offset from 'real' registration point
  19.        * @param Number local vertical offset from 'real' registration point
  20.        * @param Number relative scaleX increase; e.g. 2 to double, 0.5 to half
  21.        * @param Number relative scaleY increase
  22.        */ 
  23.       protected function scaleAround( offsetX:Number, offsetY:Number, absScaleX:Number, absScaleY:Number ):void { 
  24.          // scaling will be done relatively 
  25.          var relScaleX:Number = absScaleX / this.scaleX; 
  26.          var relScaleY:Number = absScaleY / this.scaleY; 
  27.          // map vector to centre point within parent scope 
  28.          var AC:Point = new Point( offsetX, offsetY ); 
  29.          AC = this.localToGlobal( AC ); 
  30.          AC = this.parent.globalToLocal( AC ); 
  31.          // current registered postion AB 
  32.          var AB:Point = new Point( this.x, this.y ); 
  33.          // CB = AB - AC, this vector that will scale as it runs from the centre 
  34.          var CB:Point = AB.subtract( AC ); 
  35.          CB.x *= relScaleX; 
  36.          CB.y *= relScaleY; 
  37.          // recaulate AB, this will be the adjusted position for the clip 
  38.          AB = AC.add( CB ); 
  39.          // set actual properties 
  40.          this.scaleX *= relScaleX; 
  41.          this.scaleY *= relScaleY; 
  42.          this.x = AB.x; 
  43.          this.y = AB.y; 
  44.       } 
  45.  
  46.        
  47.       /**
  48.        * Rotate around an arbitrary centre point
  49.        * @param Number local horizontal offset from 'real' registration point
  50.        * @param Number local vertical offset from 'real' registration point
  51.        * @param Number absolute rotation in degrees 
  52.        */ 
  53.       protected function rotateAround( offsetX:Number, offsetY:Number, toDegrees:Number ):void { 
  54.          var relDegrees:Number = toDegrees - ( this.rotation % 360 ); 
  55.          var relRadians:Number = Math.PI * relDegrees / 180; 
  56.          var M:Matrix = new Matrix( 1, 0, 0, 1, 0, 0 ); 
  57.          M.rotate( relRadians ); 
  58.          // map vector to centre point within parent scope 
  59.          var AC:Point = new Point( offsetX, offsetY ); 
  60.          AC = this.localToGlobal( AC ); 
  61.          AC = this.parent.globalToLocal( AC ); 
  62.          // current registered postion AB 
  63.          var AB:Point = new Point( this.x, this.y ); 
  64.          // point to rotate, offset position from virtual centre 
  65.          var CB:Point = AB.subtract( AC ); 
  66.          // rotate CB around imaginary centre  
  67.          // then get new AB = AC + CB 
  68.          CB = M.transformPoint( CB ); 
  69.          AB = AC.add( CB ); 
  70.          // set real values on clip 
  71.          this.rotation = toDegrees; 
  72.          this.x = AB.x; 
  73.          this.y = AB.y; 
  74.       } 
  75.  
  76.    } 
  77.        
  78. }