CAAT.Foundation.ActorContainer

Adding actors to a container

In CAAT, every out-of-the-box actor instance is a CAAT.ActorContainer except the CAAT.Actor object instances themselves. Despite it could seem odd adding an Actor object to (for instance) a CAAT.Shape it makes sense to do so when you need to link hierarchycally other actors to the shape. A good example could be when trying to do an elbow like relationshiop between two given actor instances. See dem8 for an example.

It must be noticed that a CAAT.Foundation.ActorContainer has no size by default, and that unless specified, a container's size will be 1x1 regardless adding/removing actors to/from it.

You can eventually, call new CAAT.Foundation.ActorContainer( CAAT.Foundation.ActorContainer.AddHint.CONFORM ); which will make the container to grow in size when adding children to it.

Addition Methods

There're two methods to add Actors to a Container.

The method function addChildDelayed(actor, constraint) batches the actor addition until CAAT.Director's current frame is processed. When adding actors to a container (in example in response to behavior events), the current frame is being processed, and adding new Actors could lead to visual artifacts. The reason is that the newly added actors have not yet executed their animation stage when being drawn on screen.

The methods function addChild(actor, constraint ) and function addActorImmediately(actor, constraint) in opposition to the previous method addActor, adds immediately an actor to the rendering pipeline, and could cause such visual artifacts.

The constraint parameter is used in case the container has a LayoutManager object associated. See Layout in the documentation for more info.

The methods function addChildAt(pos) adds an actor at a given ZIndex position.

addActorImmediately is the default actor addition behavior.

As a rule of thumb, you must take care of adding/removing actors while animate, paintActor or paint methods are being executed. These methods are traversing the list of actors present in a scene (or containers of current scene) and modifying this list while is traversed is not a good idea. In such cases, use addActorDelayed function.

In this example, every tentacle is linked to the center, and every tentacle's shape is linked (contained) to the previous one. So rotating slightly every tentacle's element turns into an accumulative rotation transformation.


                // create a tentacle
                    function __createTentacle( root, angle, segments, armSegmentSizeW, armSegmentSizeH, armIndex, maxAngle ) {

                        var i;
                        var segment= root;

                        for( i=0; i < segments; i++ ) {

                // calculate a color which lies somewhere between the rgb colors
                // (255,255,0) yellow and (255,128,0) orange.
                            var color= CAAT.Module.ColorUtil.Color.interpolate(
                                    255,255,0,
                                    255,128,0,
                                    segments,
                                    i
                            );

                // create a tentacle's segment
                            var newSegment= new CAAT.ActorContainer().
                                setSize( armSegmentSizeH-4, armSegmentSizeH-4 ).
                                setFillStyle( "rgb("+color.r+","+color.g+","+color.b+")" ).
                                setLocation( 0,-armSegmentSizeH );

                // and link it to the previos tentacle segment or root element
                            if ( segment==root ) {
                                newSegment.setRotationAnchored(angle, .5, 1);
                                newSegment.oldAngle= angle;
                            } else {
                                newSegment.oldAngle= 0;
                // set for every tentacle's segment up an animation function which applies
                // some rotation. Every segment's rotation will be composed with the previous
                // segment's one.
                                newSegment.animate= function(director,time) {
                                    this.setRotationAnchored(
                                            this.oldAngle+
                                            maxAngle*Math.sin(new Date().getTime()*.0005 + armIndex*Math.PI/segments/2
                                            ),
                                            .5,
                                            1
                                    );
                                    return CAAT.ActorContainer.prototype.animate.call(this,director,time);

                                };
                            }

                            segment.addChild(newSegment);
                            segment= newSegment;
                        }
                    }

                var _director_9= new CAAT.Director().initialize(
                        200,
                        200,
                        document.getElementById('_tut3_100'));

                var _scene_9= _director_9.createScene();

                _director_9.addScene( _scene_9 );

            // make this actor each tentacle's parent.
            // rotating this actor will make every tentacle to rotate around it.
                var root= new CAAT.ShapeActor().
                        setShape( CAAT.ShapeActor.prototype.SHAPE_CIRCLE ).
                        setBounds( _director_9.width/2, _director_9.height/2, 1, 1 ).
                        setFillStyle( 'yellow' ).
                        addBehavior(
                            new CAAT.RotateBehavior().
                                setFrameTime(0,20000).
                                setValues(0,2*Math.PI).
                                setCycle(true)
                        );

            // create 10 tentacles
                var arms= 10;
            // with 10 segments each
                var segments=10;

                var i;

                for( i=0; i<arms; i++ ) {
                    __createTentacle( root, 2*Math.PI/arms * i, segments, 2, 10, i, Math.PI/segments/2 );
                }

                _scene_9.addChild(root);
                CAAT.loop(15);