[Laszlo-dev] Some questions on masking views/sprites when displaying rounded corners with AS3

Raju Bitter rajubitter at googlemail.com
Sun Jan 31 07:42:00 PST 2010


Henry, Max, I've done some testing to improve the functionality for rounded corners in AS3 based runtimes. Currently clipping still uses a rectangle mask independent of the cornerradius. I made some modifications to enable clipping. Here's a screenshot of the small sample app I used for testing:

-------------- next part --------------
A non-text attachment was scrubbed...
Name: RoundedCorners-Sprite-Clipping-SWF10.png
Type: image/png
Size: 56189 bytes
Desc: not available
Url : http://www.openlaszlo.org/pipermail/laszlo-dev/attachments/20100131/3a414fbc/RoundedCorners-Sprite-Clipping-SWF10-0001.png
-------------- next part --------------

I basically use a view with a drop shadow and rounded corners and yellow background. The 2nd item is the same view class with a red child view, centered and reduced by 12px in length and height. The 3rd item is the same yellow view with a child view containing an image that's larger then the parent view. All of the first three items use clip="true" on the yellow view. The 4th item is the same as the 3rd with clipping turned off.

In this process I ran into some thinks that are unclear to me in lps/kernel/swf9/LzSprite.as:

1) LzSprite.clip property
Seems to be never set. The method LzSprite#setClip just calls applyMask and removeMask. But for clipping rounded corners, we need to access the setting for clip in the setCornerradius method. Would it be safe to store that value?
    
  public function setClip( clip:Boolean ):void {
        // Clip is never stored, but it's need in setCornerradius 
        // to check if we have to apply a mask.
        this.clip = clip;
        if (clip) {
            applyMask();
        } else {
            removeMask();
        }
    }

2) Drawing background and LzKernelUtils#rect
When drawing the background you use the method LzKernelUtils#rect. Why didn't you use the AS3 Grahipcs#rect method instead?

3) Scaling within applyMask()
The rectangle mask MovieClip in applyMask is created with a width of 1px by 1px and then scaled based on the width and height
                ms.graphics.drawRect(0, 0, 1, 1);
                ms.scaleX = this.lzwidth;
                ms.scaleY = this.lzheight;
For rounded corners, that approach doesn't work, since we need to take the cornerradius value when drawing the mask using drawRoundRect(). Why did you choose to scale the mask here instead of directly setting it to lzwidth and lzheight? I used this code for creating the mask:
            if (this.cornerradius > 0) {
              ms.graphics.drawRoundRect(0, 0, this.lzwidth, this.lzheight, this.cornerradius*2);
            } else {                
                ms.graphics.drawRect(0, 0, 1, 1);
                ms.scaleX = this.lzwidth;
                ms.scaleY = this.lzheight;
            }

4) Removing the mask MovieClip child from the LzSprite child list
Within LzSprite#removeMask you call this.removeChild(this.masksprite). I detected that after the removeChild call the LzSprite.masksprite still points to the same MovieClip object. That's a problem when I try to reapply a mask by removing the old one and creating a new (which needs to be done when setCornerradius is called and the mask has to be modified). So I explicitly set this.masksprite = null to make that work.
    public function removeMask():void {
        if (this.mask != null) {
            this.removeChild(this.masksprite);
            // With add explicitely setting the masksprite to 'null'
            // it will still contain the old sprite reference and
            // applyMask() will fail to create a new mask
            this.masksprite = null;
            this.mask = null;
        }
    }

5) Setting the cornerradius
When a cornerradius is set, the mask needs to be updated if clip=true. Here's the modified code I tested:
    var cornerradius = 0;
    function setCornerRadius(radius) {
        this.cornerradius = radius;
        if (this.clip) {
            this.removeMask();
            this.applyMask();
        }
        this.drawBackground();
    }

With those changes it would be possible to clip the content of a view at the view border defined by the cornerradius. But there's a bug somewhere, the app renders correctly in SWF10 70-80% of the times, with some views sometimes not showing up when the views are clipped or the content still overlapping the mask . An interesting fact is that the drop shadow doesn't show up for the clipped elements that are visible in that case.

Here's a screenshot: The 3rd item is not showing up, and in the 2nd item the red box is not clipped with the drop shadow missing on the first 2 items. I guess there's a timing problem with initialization, where the order of when a value is set varies - but you'll probably know much better.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: RoundedCorners-Sprite-Clipping-SWF10-Error.png
Type: image/png
Size: 47671 bytes
Desc: not available
Url : http://www.openlaszlo.org/pipermail/laszlo-dev/attachments/20100131/3a414fbc/RoundedCorners-Sprite-Clipping-SWF10-Error-0001.png
-------------- next part --------------



With DHTML there are some other problems, mainly missing browser support for clipping based on corner radius settings. I added a comment http://jira.openlaszlo.org/jira/browse/LPP-8508 with detailed info. I attached a diff for LzSprite.as and a zip file with the example app, if you want to test.

- Raju

-------------- next part --------------
A non-text attachment was scrubbed...
Name: LzSprite_roundedcorner.diff
Type: application/octet-stream
Size: 2403 bytes
Desc: not available
Url : http://www.openlaszlo.org/pipermail/laszlo-dev/attachments/20100131/3a414fbc/LzSprite_roundedcorner-0001.obj
-------------- next part --------------
A non-text attachment was scrubbed...
Name: roundedcorner_cliptest.zip
Type: application/zip
Size: 49678 bytes
Desc: not available
Url : http://www.openlaszlo.org/pipermail/laszlo-dev/attachments/20100131/3a414fbc/roundedcorner_cliptest-0001.zip


More information about the Laszlo-dev mailing list