Note: Graphics 2.0 is now in public beta for all Corona SDK Pro and Enterprise subscribers. Please see Walter’s recent blog piece on the news.


In Corona‘s graphics model, groups have been the workhorse way of organizing objects hierarchically. When you modify a group’s properties, the children are affected. For example, if you set the alpha on a group, then each child’s alpha is effectively multiplied by that alpha of the parent group.

The new graphics engine is going to have a new kind of group called a Container.

Before I dive into that, let’s digress and talk about a common task in creating interfaces: limiting the rendering of a group to a rectangular region. To do this in the old graphics engine (well, old to me) is a bit of a task because groups don’t provide this functionality out of the box.

By themselves, groups have an infinite boundary, so no object is ever clipped by the group. Now the renderer might decide to cull offscreen objects in a group, but that’s different from the group itself having a boundary. If the screen were stretched so its dimensions were sufficiently large, all the children in a group would be rendered.

So the standard way in the old engine to “clip” the rendering of the children in a group, you’d need to do something extra. Specifically, you’d have to set a rectangular mask on the group.

The problem with this approach is this required some foresight because the mask has to be based on a bitmap file. In other words, you’d have to know exactly the dimensions when you create them in Adobe Photoshop, Illustrator, etc. And if you wanted to create various groups with different clipping dimensions, there are some tricks like scaling the mask, but none of them were perfect.

That brings us back to Containers.

Containers are a new feature that will be introduced in the new graphics engine. Containers derive from groups, so they inherit all the methods to add and remove children. On top of that, they will provide first-class support for clipping the children of a group, based on the width and height for the group. No more messing with separate mask files — just specify the width and height that you want!

In the video below, we show a container with two children (a background image and a text object). As the container’s height shrinks, only the parts of the children inside the container bounds render:

Initially, the container is 300×300. Then we add our favorite aquarium image from the ‘Fishies’ sample and some text. Notice that the container clips the aquarium image so you only see the center of the original full 320×480 image. And as the height shrinks, the container will eventually clip the text object as well.

Here’s the corresponding code. Basically, think of the container as the same as a group, except you call a different constructor and you can change the ‘width’ and ‘height’ properties:

local container = display.newContainer( 300, 300 )
container:translate( 160, 240 ) -- center the container

local bkgd = display.newImage( "aquariumbackgroundIPhone.jpg" )
container:insert( bkgd, true ) -- insert and center bkgd

local myText = display.newText( "Hello, World!", 0, 0, native.systemFont, 40 )
myText:setFillColor( 255,255,0 )
container:insert( myText, true ) -- insert and center text

-- dynamically resize the height of the container
transition.to( container, {height = 20, time=2000} )
  1. Nice to see progress.

    There are still some questions open:
    Can we import a whole group into a container?
    So we can still work with groups, and if we want to render certain things, we could just put the whole group into the container.

    Next question: Will those Container-Objects allow us to finally use repeating Patterns? It’s always a bit ressource-heavy to make images for the whole width/height of the device (especially for Retina-Tablets)..

    I think those Containers might be the perfect solution for that. Allowing repeating patterns and even moving there offset in the container.

    • Yes, a container is just a group with a width and height, so you can add a group into the container, just like you can add a group inside another group.

      What do you mean by “finally”? Can’t you create groups with a child tiles today?

      • Well I don’t think I can make a group with a fixed width and add a single repeating image in there. Let me know if I’m wrong, but atm you would have to make many display images to fill the place OR use a single huge image – which is of course bad for texture memory.

        What I would like to see is to put in a single image into a container and set the container to repeat-all, repeat-x or repeat-y.

        Thanks for clarifying the group in container fact!

        Now one more thing: Can we apply the new graphic-effects (especially blur) on the Container, so we can have a soft-edge? ;)

  2. Excellent – I recently added a request for this in the features list.

    One question: The display objects in the video are centred, but changing the height of the container moves the top and bottom borders towards the middle. Does this mean that the border of a container is always equally centred on the (0,0) location of the border?

    To explain: If I wanted just the top and not the bottom to close inwards, would I have to change the height and, at the same time, move the container and everything in it, to keep everything centred?

    Love the possibilities for this – business apps will definitely be easier!

    • Yes, the border is centered around the container’s origin.

      You can always add a child group inside the container and offset that child group (relative to the parent container). So instead of adding children directly to the parent container, you add them to the child group

      • On second thought, to get the effect you want, there’s still some work to translate that child group.

        Can you give us some examples of how you might use the container? That’ll help us prioritize this.

        • Why would the container not just have the usual top left width and height properties?
          Hopefully it can be updated, as the idea of having it centered on around the container’s origin will introduce a needless set of additional groups and code to offset.

          A simple example:

          I have a table view that I wish to clip to an area of the screen, which can change depending on the device resolution. I know the t, l, w and h values, and essentially only the h value would change. As it stands, I’d need to offset the entire table view, rather than just create the container with matching values to the table view constructor.

          There are many many more examples, all of which would (for simplicity’s sake) require the container to work the same as other features that require or describe a rectangular area of the screen.

          Bottom line though, it seems strange to create a new, extremely useful feature which is at odds with the rest of the corona library. A container is a rectangle, so keep it in line with everything else, and improve the functionality to boot!

  3. As it sounds now, this will not do away with graphic masks. If you are going to to do this, why not extend it so that shapes can be defined instead of simple bounding boxes with a width and height?

    How about some basic shapes like circle, box, star, etc? Could we not pass in some vectors? Or multiple points? I may want a box that is has a width of 300 on the left but 200 on the right.

    Thus a shape like (imagine the lines drawn between the points).

    y1
    y2

    x1 x2

    Love the idea of going away with bitmap masks when possible and doing something like this would help that cause far more than simple boxes.

    • It seems the blog does not like the spacing in my example.

      From left to right 0 to 10 and top to bottom 0 to 10.

      y1 = 0,10
      y2 = 10, 8
      x1 = 0,0
      x2 = 10, 0

      • Well since in graphics 2.0 you can change position of corners, and since container is going to have be a rect, I don’t see why Corona would not allow us to modify containers, right? :)

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>