SEARCH
  Tutorials Flash & Swish Flash Tutorials Adding Multiple GML-Defined Gestures, Using Method 3: CML Constructors & GML Manipulations

Adding Multiple GML-Defined Gestures, Using Method 3: CML Constructors & GML Manipulations

Adding Multiple GML-Defined Gestures,
Using Method 3: CML Constructors & GML Manipulations

In GestureWorks3 we designed Creative Markup Language (CML) to simplify the development of multitouch applications by providing advanced methods in Flash for developers to create interactive objects and containers that can be manipulated using configurable gestures. In each application created with GestureWorks 3 there are two associated xml documents: "my_application.cml" and "my_gestures.gml", which are located in the folder "bin/library/cml" and "bin/library/gml" respectively.

As part of the CML tool kit in GestureWorks 3 there are multiple built-in components that can be accessed using "my_application.cml". For example:

<CanvasKit>
<ComponentKit>
<TouchContainer id="touchContainer" x="200" y="200" rotation="-45" dimensionsTo="image" mouseChildren="true">
<ImageElement id="image" src="library/assets/wb0.jpg"/>
<GestureList>
</GestureList>
</TouchContainer>
<TouchContainer id="touchContainer2" x="400" y="400" rotation="45" dimensionsTo="image2" mouseChildren="true">
<ImageElement id="image2" src="library/assets/wb1.jpg"/>
<GestureList>
</GestureList>
</TouchContainer>
</ComponentKit>
</CanvasKit>

This creates a new TouchContainer object that houses the ImageElement object that holds a dynamically loaded bitmap image. The "touchContainer" is then positioned, scaled and rotated inside the ComponentKit container which is placed in the CanvasKit and then on stage. This is repeated for the " touchContainer2" item.

To attach a gesture to an touch object defined in the CML document, it must be added to the block associated with the TouchContainer. In order to attach multiple gestures to a touch object, multiple gesture references are added to the block and activated by setting the "gestureOn" attribute to true. For example:

<CanvasKit>
<ComponentKit>
<TouchContainer id="touchContainer" x="200" y="200" rotation="-45" dimensionsTo="image">
<ImageElement id="image" src="library/assets/wb0.jpg"/>
<GestureList>
<Gesture ref="n-drag" gestureOn="true"/>
<Gesture ref="n-scale" gestureOn="true"/>
<Gesture ref="n-rotate" gestureOn="true"/>
</GestureList>
</TouchContainer>
<TouchContainer id="touchContainer2" x="400" y="400" rotation="45" dimensionsTo="image2">
<ImageElement id="image2" src="library/assets/wb1.jpg"/>
<GestureList>
<Gesture ref="n-drag" gestureOn="true"/>
<Gesture ref="n-rotate" gestureOn="true"/>
<Gesture ref="n-scale" gestureOn="true"/>
</GestureList>
</TouchContainer>
</ComponentKit>
</CanvasKit>

The CML document in this case describes the attachment of three gestures "n-drag", "n-scale " and "n-rotate" to two "ImageElement" items. The effect of this is to activate matching, analysis and processing for the three gestures on each touch object. These gestures are uniquely defined in the root GML document "my_gestures.gml" located in the bin folder of the application.

The traditional event model in flash employs the explicit use of event listeners and handlers to manage gesture events on a touch object. However in GestureWorks3 Gesture Markup Language can be used to directly control how gesture events map to touch object properties and therefor how touch objects are transformed. These tools are integrated into the gesture analysis engine inside every touch object and allow custom gesture manipulations and property updates to occur on each touch object.

<Gesture id="n-drag" type="drag">
<match>
<action>
<initial>
<cluster point_number="0" point_number_min="1" point_number_max="5" translation_threshold="0"/>
</initial>
</action>
</match>
<analysis>
<algorithm>
<library module="drag"/>
<returns>
<property id="drag_dx"/>
<property id="drag_dy"/>
</returns>
</algorithm>
</analysis>
<processing>
<inertial_filter>
<property ref="drag_dx" release_inertia="true" friction="0.996"/>
<property ref="drag_dy" release_inertia="true" friction="0.996"/>
</inertial_filter>
</processing>
<mapping>
<update>
<gesture_event>
<property ref="drag_dx" target="x" delta_threshold="true" delta_min="0.01" delta_max="100"/>
<property ref="drag_dy" target="y" delta_threshold="true" delta_min="0.01" delta_max="100"/>
</gesture_event>
</update>
</mapping>
</Gesture>

In this example the gesture "n-drag" as defined the root GML document "my_gestures.gml" directly maps the values returned from gesture processing "drag_dx" and "drag_dy" to the "target" "x" and "y". Internally the delta values are added to the "$x" and "$y" properties of the touch object ("TouchContainer"). This translates the object on stage to the center of the touch point cluster.

<Gesture id="n-scale" type="scale">
<match>
<action>
<initial>
<cluster point_number="0" point_number_min="2" point_number_max="5" separation_threshold="0"/>
</initial>
</action>
</match>
<analysis>
<algorithm>
<library module="scale"/>
<returns>
<property id="scale_dsx"/>
<property id="scale_dsy"/>
</returns>
</algorithm>
</analysis>
<processing>
<inertial_filter>
<property ref="scale_dsx" release_inertia="true" friction="0.996"/>
<property ref="scale_dsy" release_inertia="true" friction="0.996"/>
</inertial_filter>
</processing>
<mapping>
<update>
<gesture_event>
<property ref="scale_dsx" target="scaleX" func="linear" factor="0.0033" delta_threshold="true" delta_min="0.0001" delta_max="1"/>
<property ref="scale_dsy" target="scaleY" func="linear" factor="0.0033" delta_threshold="true" delta_min="0.0001" delta_max="1"/>
</gesture_event>
</update>
</mapping>
</Gesture>

The gesture "n-scale" as defined the root GML document "my_gestures.gml" directly maps the values returned from gesture processing "scale_dsx" and "scale_dsy" to the "target" "scaleX" and "scaleY". Internally the delta values multiplied with the "$scaleX" and "$scaleY" properties of the touch object ("touchContainer") and scales the object on stage about the center of the touch point cluster.

<Gesture id="n-rotate" type="rotate">
<match>
<action>
<initial>
<cluster point_number="0" point_number_min="2" point_number_max="5" rotatation_threshold="0"/>
</initial>
</action>
</match>
<analysis>
<algorithm>
<library module="rotate"/>
<returns>
<property id="rotate_dtheta"/>
</returns>
</algorithm>
</analysis>
<processing>
<noise_filter>
<property ref="rotate_dtheta" noise_filter="true" percent="30"/>
</noise_filter>
<inertial_filter>
<property ref="rotate_dtheta" release_inertia="true" friction="0.996"/>
</inertial_filter>
</processing>
<mapping>
<update>
<gesture_event>
<property ref="rotate_dtheta" target="rotate" delta_threshold="true" delta_min="0.1" delta_max="10"/>
</gesture_event>
</update>
</mapping>
</Gesture>

The gesture "n-rotate" as defined the root GML document "my_gestures.gml" directly maps the value returned from gesture processing "rotate_dtheta" to the "target" "rotation". Internally the delta value added to the "$rotation" property of the touch object ("ImageElement") and the object is rotated about the center of the touch point cluster on stage.

When touch points are placed on the touch object they are collected into a local "cluster". The motion of this cluster is inspected for matching gesture actions and then the motion and geometry analysed, processed and returned for mapping. Each gesture activated on the touch object can be triggered independently. When multiple gestures are detected in the same frame the touch object undergoes a blended transformation which results in animated motion on stage.

Adding the three gestures "n-drag","n-scale" and "n-rotate" in combination allow the touch object to be interactively moved, scaled and rotated around a dynamic center of motion. This gives a "natural" feel to the touch objects as it can pivot and scale around any touch point in the cluster. These "affine" transformations are managed internally to the touchsprite ("ImageElement").

The benefit of using the CML to construct touch objects and GML to handle gesture events is that complex interactive media object can be created with sophisticated gesture based manipulations in a few simple lines of code. The details of component creation, media loading and unloading, display layouts, gesture interactions and event management are all handled automatically in the CML and GML framework in GestureWorks3.

The tools available as part of the CML and GML internal framework allows developers to rapidly create configurable Flash applications that can be completely described using editable XML documents. This method mimics best practices used for dynamically assigning object based media assets and formatting, providing a framework that fully externalizes object gesture descriptions and interactions. The result of this approach allows developers to efficiently refine UI/UX interactions, layouts and content without the need to recompile applications.

subscribe to newsletter