CAAT.Actor

Input system

CAAT input system works in two ways.
By default every Actor has input enabled (mouse/touch). The system traverses the scene graph in-orderly trying to find what Actor will have input events routed to. The main issue with this way of input routing is that children which lie out of its parent bounds won't be able to have input events sent. To prevent this, a CAAT.Foundation.ActorContainer can be created with CAAT.Foundation.ActorContainer.AddHint.CONFORM so that it will conform its size by computing their children bounding box.
The other way of going with input are input lists. These lists, are managed by the methods
  • enableInputList(number): number of priority lists to set for this scene. A priority list is a list of actors you want to receive input first. If no actor on the priority lists are under the cursor/touch, the whole scene graph is traversed instead, as if no priority list existed.
  • addActorToInputList( actor, index, position ): add an actor to a given priority list at certain position.
  • emptyInputList( index ): remove all elements from a list.
  • removeActorFromInputList( actor, index ): remove an actor from the list identified by index.
The input lists change the input semantics so that the developer can decide what scene graph actors will be immediately tested to have input sent. This procedure bypasses the container size restriction making non prioritized actors behave as if they were not on screen regarding input events.
To globally disable input for every scene actor, you can set CAAT.Foundation.Actor.prototype.mouseEnabled= false; and then a call to actor.enableEvents(true); must be explicitly called to enable input for any given actor.

Actor Input Events

An Actor instance has mouse events enabled by default. The mouse control methods are the following:

  • function mouseEnter(mouseEvent)
    Triggered whenever the mouse enters the rectangular area of an Actor. CAAT will perform perfect pixel collision regardless the transformation an actor has applied. See demo4 for a demo on this fact.
  • mouseExit(mouseEvent)
    Exactly like in mouseEnter, but when leaving the Actors bounding box.
  • mouseMove(mouseEvent)
    Triggered whenever the mouse arrow traverses inside the Actor's bounding box.
  • mouseDown(mouseEvent)
    Triggered whenever we press the mouse button inside the Actor's contour.
  • mouseUp(mouseEvent)
    Same as mouseDown but when releasing the mouse button.
  • mouseClick(mouseEvent)
    Triggered whenever a click has been generated on the Actor. That means that previously a mouseDown and then a mouseDown have been triggered on the Actor. A mouseClick event won't be received if any mouseDrag has been detected.
  • mouseDblClick(mouseEvent)
    Same as mouseClick but double click.
  • mouseDrag(mouseEvent)
    Triggered after we perform an equivalent to mouseMove after having done mouseDown. After dragging, when releasing the mouse button, only mouseUp will be triggered avoiding to trigger mouseClick event.

All these methods receive a unique parameter of type CAAT.Event.MouseEvent. It contains the following information:

  • screenPoint
    The 2D point of the screen coordinate that originated the mouse event.
  • x,y the same as screenPoint but w/o being wrapped in an object.
  • point
    The 2D point of local Actor coordinates. Remember that local coordinates are from (0,0) to actor's (width,height). These 2D point is derived from the screenPoint.
  • modifiers
    Modifiers will tell you whether some special keys where pressed during the mouse input. The CAAT.Event.MouseEvent class has some methods to check for these special keys.
  • time
    The Scene time (more on this later) at which the event was produced.
  • source
    The actor the event was produced at.

Multitouch

CAAT also supports multitouch features but they must be explicitly enabled. See demo22 for a multitouch example.. Single touch and multitouch can't run at the same time, but can switch from multitouch to mouse/single touch by setting a global variable.

First of all, multitouch must be enabled by setting CAAT's global variable CAAT.TOUCH_BEHAVIOR to CAAT.TOUCH_AS_MULTITOUCH; like: CAAT.TOUCH_BEHAVIOR= CAAT.TOUCH_AS_MULTITOUCH;

To get back to single touch/mouse, set the variable to CAAT.TOUCH_AS_MOUSE value.

From this point, CAAT actors will be notified to multitouch control functions:

  • touchStart(mouseEvent);
  • touchMove(mouseEvent)
  • touchEnd(mouseEvent)
  • gestureStart(rotation, scaleX, scaleY)
  • gestureChange(rotation, scaleX, scaleY)
  • gestureEnd(rotation, scaleX, scaleY)

touchStart, touchMove and touchEnd receive a CAAT.Event.MouseEvent object instance.

gestureStart, gestureChange and gestureEnd receive a value from 0 to 2*PI for rotation, and values from 0 to N for scaleX and scaleY.

CAAT actors receive gesture events by default, there's no need to enable multitouch. The method setGestureEnagled(bool) and isGestureEnabled() => bool control default behavior for gestures which are pinch and zoom capabilities. You can define your own behavior by redefining gesture methods. See demo4 for gesture support.

Input control

If an Actor instance is not supposed to process input from mouse, a call to enableEvents(false) must be explicitly called. This method can be called at any given time with a boolean parameter to set or reset mouse handling.

Two methods of CAAT.Foundation.Actor instances will change default mouse event handling methods for others:

  • function enableEvents(bool). Will enable/disable mouse/touch/multitouch in an Actor.
  • function enableDrag(). Will set mouse methods to allow an actor instance's drag. Some drag modifiers such as shift, control and shift+control will change actor's rotation and scale.
  • function setAsButton(). Will set mouse methods to allow a given actor behave as a button.

Other input types such as keys and accelerometer are handled directly by CAAT.Foundation.Director instances.

Example

In this example, you can see some rectangle-shaped actors with other rectangle child inside.

A CAAT.ActorContainer can contain any number of Actors and hence any number of other ActorContainer instances.

            var director_1 = new CAAT.Foundation.Director().initialize(
                    600,120,
                    document.getElementById('_c1'));

            var scene_1=     director_1.createScene().setFillStyle('#fff');
            
            // make the scene clear background and draw a black rectangle
            scene_1.paint= function(director, time) {
                var ctx= director.ctx;
                ctx.fillStyle= this.fillStyle;
                ctx.fillRect(0,0,this.width,this.height);
                ctx.strokeStyle= '#000';
                ctx.strokeRect(0,0,this.width-1,this.height-1);
            }


            // create six actors for this scene.
            for(var i=0; i<6; i++ ) {

                // rectangle shaped actors of 80x80 pixels.
                var s = 80;

                // containers can contain other actors or containers.
                var _c1_container = new CAAT.Foundation.ActorContainer().
                        setBounds(i*100+10, 20, s, s).
                        setRotation( Math.PI*2*Math.random() ).
                        setFillStyle('#ff3fff').
                        enableDrag();

                _c1_container.name = 'rectangle'+i;
                // set container paint routine to draw an arrow
                _c1_container.paint= function(director, time) {

                    var crx= director.ctx;

                    // fill actor
                    crx.fillStyle= this.fillStyle;
                    crx.fillRect(0,0,this.width,this.height );

                    // outline it.
                    crx.strokeStyle= 'black';
                    crx.strokeRect(0,0,this.width,this.height );

                    // draw a white arrow. just to point where position 0,0 is.
                    crx.strokeStyle='white';
                    crx.beginPath();
                    crx.moveTo(5,10);
                    crx.lineTo(20,10);
                    crx.lineTo(15,5);

                    crx.moveTo(20,10);
                    crx.lineTo(15,15);

                    crx.lineWidth=2;
                    crx.lineJoin='round';
                    crx.lineCap='round';

                    crx.stroke();
                };

                // add actor to scene.
                scene_1.addChild(_c1_container);

                // create a container.
                var _c1_container_child= new CAAT.Foundation.ActorContainer().
                        setBounds(s/2,s/2,s/4,s/4).
                        setRotation( Math.PI*2*Math.random() ).
                        setFillStyle('#00ff00').
                        enableDrag();

                // set a custom paint function for children inside containers.
                _c1_container_child.paint= function(director,time) {
                    // call default container paint method.
                    CAAT.Foundation.ActorContainer.superclass.paint.call(this,director,time);
                    var ctx= director.ctx;

                    // fill a white circle of 10x10 pixels at position 2,2
                    // just to show where 0,0 is positioned on screen.
                    ctx.fillStyle='white';
                    ctx.beginPath();
                    ctx.arc(7,7,5,0,2*Math.PI,false);
                    ctx.fill();
                }


                // add this container as a child of the previous created container.
                _c1_container.addChild(_c1_container_child);
            }

            // set animation to 10fps.
            CAAT.loop(10);