apache flex – Getting the global coordinates of the visible area of a component – Education Career Blog

I am trying to determine the global coordinates of the visible rectangle that is currently rendered on the stage.

Specifically, if a canvas has an explicit height and width and is a child of a panel that has a scrollbar, the scrollbar can “hide” a part of the canvas. ContentToGlobal(x,y) provides the global position of the content at the time, but content coordinates can scroll off the boundaries of the parent panel and continue to give x,y coordinates that are not visible.

Is there a way to determine the viewable rectangle that is not hidden by anything?

,

It turns out that the UIComponent class has an undocumented public function that does exactly what I was looking for.

/**
 *  @private
 * 
 *  Get the bounds of this object that are visible to the user
 *  on the screen.
 * 
 *  @param targetParent The parent to stop at when calculating the visible
 *  bounds. If null, this object's system manager will be used as
 *  the parent.
 * 
 *  @return a <code>Rectangle</code> including the visible portion of the this 
 *  object. The rectangle is in global coordinates.
 */  
public function getVisibleRect(targetParent:DisplayObject = null):Rectangle

This is pulled from the class and is documented as private but is actually a publicly accessible function that can be used on any UI object.

Since this isn’t in the documentation anywehere, I imagine it may be susceptible to future changes.

,

No, there is no straightforward solution.

You should calculate the visible rectangle manually:

    private function getVisibleRectangle(container:Container, child:UIComponent):Rectangle
    {
        var rect:Rectangle = child.getBounds(child.stage);
        var containerMetrics:EdgeMetrics = container.viewMetrics;
        var containerPoint:Point = container.localToGlobal(new Point(0, 0));
        var containerRect:Rectangle = new Rectangle(containerPoint.x + containerMetrics.left, 
            containerPoint.y + containerMetrics.top, 
            container.width - containerMetrics.left - containerMetrics.right, 
            container.height - containerMetrics.top - containerMetrics.bottom);

        if (rect.left >= containerRect.right ||
            rect.right <= containerRect.left ||
            rect.top >= containerRect.bottom ||
            rect.bottom <= containerRect.top)
            return null;

        rect.left = Math.max(rect.left, containerRect.left);
        rect.right = Math.min(rect.right, containerRect.right);
        rect.top = Math.max(rect.top, containerRect.top);
        rect.bottom = Math.min(rect.bottom, containerRect.bottom);
        return rect;
    }

Example of usage:

<mx:Panel id="panel" width="200" height="200">
    <mx:Canvas backgroundColor="green" width="100" height="100"/>
    <mx:Canvas id="canvas" backgroundColor="red" width="500" height="400" 
        enterFrame="trace(getVisibleRectangle(panel, canvas));"/>
</mx:Panel>

Leave a Comment