Skip to main content
February 1, 2012
Question

Issue with localToGlobal during after scaling

  • February 1, 2012
  • 3 replies
  • 1230 views

I ran into a problem which I'm not sure if I'm just using it wrong or if it's an issue with the Flash default classes related to localToGlobal ( and globalToLocal ).

Whenever I rescale the container for my objects, the returned localToGlobal point will always be off by whatever the scale is. If I were to divide the returned point by the scale then the positions are fixed.

Here's a sample code I quickly wrote up regarding the issue I'm having.

package

{

    import flash.display.MovieClip;

    import flash.display.NativeWindow;

    import flash.display.NativeWindowInitOptions;

    import flash.display.Sprite;

    import flash.display.Stage;

    import flash.display.StageAlign;

    import flash.display.StageScaleMode;

    import flash.events.MouseEvent;

    import flash.events.NativeWindowBoundsEvent;

    import flash.geom.Point;

    public class TestScale extends MovieClip

    {

        private var _window:NativeWindow;

        private var _container:Sprite;

        private var _targetLocation:Sprite;

       

        private var _defaultWidth:Number;

        private var _defaultHeight:Number;

       

        public function TestScale()

        {

            var window:NativeWindow            = stage.nativeWindow;

           

            this.stage.nativeWindow.visible = true;

            this.stage.scaleMode             = StageScaleMode.NO_SCALE;

            this.stage.align                 = StageAlign.TOP_LEFT;

           

            var button:Sprite = new Sprite();

            button.graphics.beginFill(0xFF6600);

            button.graphics.drawRoundRect(10, 10, 120, 50, 30);

            button.graphics.endFill();

            addChild(button);

           

            this.stage.nativeWindow.width     = window.width - window.stage.stageWidth + button.width + 20;

            this.stage.nativeWindow.height     = window.height - window.stage.stageHeight + button.height + 20;

           

            button.addEventListener(MouseEvent.CLICK, addBox);

           

            _window = new NativeWindow(new NativeWindowInitOptions());

           

            _container         = new Sprite();

            _targetLocation = new Sprite();

           

            _window.stage.scaleMode = StageScaleMode.NO_SCALE;

            _window.stage.align = StageAlign.TOP_LEFT;

            _window.activate();

            _window.addEventListener(NativeWindowBoundsEvent.RESIZE, resizeHandler);

            _window.stage.addChild(_container);

           

            _defaultWidth     = _window.stage.stageWidth;

            _defaultHeight    = _window.stage.stageHeight;

           

            _container.addChild(_targetLocation);

           

            _targetLocation.x = _targetLocation.y = 100;

            var startPos:Sprite = new Sprite();

            var containerPoint:Point = _targetLocation.localToGlobal(new Point(0,0));

            startPos.graphics.beginFill(0x000000, 0.1);

            startPos.graphics.drawRect(containerPoint.x, containerPoint.y, 100, 100);

            startPos.graphics.endFill();

            _container.addChild(startPos);

        }

       

        private function addBox(event:MouseEvent):void

        {

            var rect:Sprite = new Sprite();

            var containerPoint:Point = _targetLocation.localToGlobal(new Point(0,0));

            var containerFinal:Point = _targetLocation.localToGlobal(new Point(200,200));

           

            rect.graphics.beginFill(0xFFFFFF * Math.random(), 0.5);

            rect.graphics.drawRect(containerPoint.x, containerPoint.y, 100, 100);

            rect.graphics.endFill();

           

            _container.addChild(rect);

        }

       

        private function resizeHandler(event:NativeWindowBoundsEvent):void

        {

            var window:NativeWindow = event.target as NativeWindow;

            var stage:Stage = window.stage;

            var scaleX:Number = stage.stageWidth / _defaultWidth;

            var scaleY:Number = stage.stageHeight / _defaultHeight;

            var scale:Number = (scaleX < scaleY) ? scaleX : scaleY;

           

            _container.scaleX = _container.scaleY = (scale == 0 ? 1 : scale);

        }

    }

}

The program basically just creates 2 native windows, one of which is a simple button to create boxes in the second window based on a static localToGlobal position.

There's also a resize handler that I'm using to change the scale of the container. Normally when you click on the button the boxes are created in the proper locations. However, if I resize the second window, the positions become messed up and are not placed properly.

Anyone know whether there is a solution to this? It needs to give the correct location regardless of scale.

Thanks in advance.

This topic has been closed for replies.

3 replies

February 8, 2012

I have added a bug report and created a workaround that can fix the issue but would rather there be an official answer for this.

The workaround involves overriding the localToGlobal and globalToLocal functions and manually adding in the scale ( and offsets if centering ).

override public function localToGlobal(point:Point):Point

{

var returnPoint:Point = super.localToGlobal(point);

           

return calculateOffset(returnPoint);

}

       

override public function globalToLocal(point:Point):Point

{

var returnPoint:Point = super.globalToLocal(point);

           

return calculateOffset(returnPoint);

}

private function calculateOffset(baseLocation:Point):Point

{

var stage:Stage = this.stage;

           

if(_appStage) stage = _appStage;

           

var trueLocation:Point = baseLocation;

var scale:Number = this.getStageScale();

var offsetX:Number = this.getStageOffsetX();

var offsetY:Number =this.getStageOffsetY();

trueLocation.x = (trueLocation.x - offsetX) / scale;

trueLocation.y = (trueLocation.y - offsetY) / scale;

           

return trueLocation;

}

I didn't include the code to get the scale and offsets since half of it is hardcoded but roughly that was my workaround.

Inspiring
February 5, 2012

i am also facing the same problem, hope someone can helps.

chris.campbell
Legend
February 7, 2012

I haven't had time to try the source code out, but in the interim can you create a new bug report over at bugbase.adobe.com so we don't loose track of this.  In addition to sample code, if you can let us know if this is new behavior for AIR 3.1 that would also be very helpful.

Thanks,

Chris