Showing posts with label AS3. Show all posts
Showing posts with label AS3. Show all posts

Thursday, June 4, 2009

FontBook: AS3 Font and CSS stylesheet management class

I developed this singleton FontBook class to function as a font and CSS stylesheet manager for flash and flex projects. It loads fonts from an external swf and registers them so they can be accessed by the parent swf and all children of the parent swf. If a CSS Path is passed into the FontBook instance, FontBook loads and parses the external css stylesheet to use with the fonts.

FontBook should be used for managing text treatment in mini-sites and other multi-page/ multi-swf applications. By keeping the fonts separate from the content swfs and only needing to load them once FontBook helps keep file sizes low.

Implementation:
  1. Open a new fla, right click in the library and select "new font"
  2. Choose the font you wish to embed. Select "export for Actionscript" and give it a class name
  3. Add as many fonts as you need
  4. In the first and only frame of the fla, open the actions panel and populate a fontClassArray array with the class names of the fonts chosen to embed (NOTE: use the class names specified in the "export for Actionscript" settings, NOT the proper font names) :

    var fontClassArray:Array = ["MyFontClassName1", "MyFontClassName2", etc, etc];
  5. Save the fla and export the swf (i.e. fonts.swf)
  6. In the target application instantiate FontBook and pass the location of the font swf and css stylesheet to the FontBook constructor.
    public var fontBook:FontBook;
    private var _cssPath:String = "stylesheet.css";
    private var _fontsPath:String = "fonts.swf";

    fontBook = FontBook.getInstance(_fontsPath,_cssPath);
    fontBook.addEventListener (FontBook.FONT_DATA_ERROR, onFontDataError);
    fontBook.addEventListener (FontBook.CSS_DATA_ERROR, onCSSDataError);
    fontBook.addEventListener (FontBook.FONTS_LOADED, onFontsLoaded);
    fontBook.addEventListener (FontBook.CSS_LOADED, onCSSLoaded);

    private function onFontsLoaded(event:Event):void
    {
    trace (Fonts.enumerateFonts()); // will trace out the embedded fonts
    }
  7. To retrieve fonts and stylesheet for use with htmlText:
    var tField:TextField = new TextField();
    tField.styleSheet = fontBook.css;
    tField.embedFonts = true;
    tField.htmlText = "<'span class="cssClass">lorem Ipsum...<'/span>"
    // where 'cssClass' is a class style in the stylesheet
  8. To retrieve fonts from FontBook for use with Flash's TextFormat:
    var tFormat:TextFormat = new TextFormat();
    tFormat.font = fontBook.fontByClass("MyFontClassName1");
    //where "MyFontClassName1" is the font class name in the fontClassArray of fonts.swf
download FontBook

Friday, October 17, 2008

Holy Cow! Papervision3D Materials Demo

Here is a little experiment with various Papervision3D and a static PointLight3D. Use the “shift” key to cycle through the various material skins.






I pulled the cow.dae model from a google search. I had to edit the dae a bit by stripping it of all the material, camera, and light references so that the file only defines the geometric mesh. This is so I can specify the camera and lighting in papervision and apply the materials dynamically through Actionscript. Also, for some reason I had problems swapping materials in the dae model using the Collada and DAE parser classes, as a result I had to convert it into a zip and then parse it using the KMZ parser.

The great thing about the KMZ parser is the ability to reference individual objects in the Collada (.dae). All Collada data is contained within the scene (registered as COLLADA_SCENE, not “scene”), I named the geometric mesh “Cow”. As a result, I was able to reference the cow mesh directly using my _cow DisplayObject3D variable and this simple line of code:
_cow = _KMZ.dae.getChildByName("COLLADA_Scene").getChildByName("Cow");

Then by referencing the material property of the _cow DisplayObect3D Flash can dynamically reskin the mesh with the material specified.


Download Source Code and Example

Thursday, October 9, 2008

Basic Interactivity with Papervision2.0

For the past few years the Flash community has reveled in the ability to create a virtual 3D environment using the open source Papervision3D engine. After a few hours playing with the code, one realizes the immense potential of Papervision and the exciting paths it has, and will continue, to pave for Flash Designers and Developers. We find it very easy to create three-dimensional objects, making it ideal for banging out quick prototypes and wowing our colleagues and friends with rotating cubes and other platonic solids. However, when we start to consider functionality and specific forms of interaction, things become slightly more complicated.

Depending on what we wish to accomplish, there are two primary ways to interact with our 3D scenes: 1. The flash.events packages inherent to Flash, and 2. The InteractiveScene3DEvent bundled with the Papervision code. Both these methods are valid and while at first seem as if they can be used interchangeably, we soon find that there are specific scenarios where we must choose one or the other. A quick and dirty , yet handy, generalization is that when we you wish to interact with the Scene or a 3D object as a whole use the InteractiveScene3DEvent. For interaction within 3D objects (i.e. with the materials) use flash.events.

To demonstrate these two methods of interactivity, I built a simple flipping card demo using the latest Papervision2.0 release (aka the “Great White” branch). The idea is to allow the user to flip the card by clicking on it while also allowing basic button interaction on the obverse side. I commented the code, and assume that the reader has a basic understanding of Papervision.

Download Source Code and Example







Code:
import gs.TweenLite;
import org.papervision3d.view.BasicView;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.objects.primitives.Plane;
import org.papervision3d.materials.*;
import org.papervision3d.events.InteractiveScene3DEvent; //imports InteractiveScene3DEvents

var backface = new BackFace;//instantiates BackFace library asset

/*BasicView(viewportWidth:Number = 640, viewportHeight:Number = 480, scaleToStage:Boolean = true, interactive:Boolean = false, cameraType:String = "Target")*/
var view:BasicView = new BasicView(1,1,true,true);
view.buttonMode = true
view.camera.focus=100; //.camera is an inherrit property of the BasicView Class as is scene and viewport
view.camera.zoom=10; //focus to zoom ratio of 100:10 renders objects at their actual sizes

//Instantiates DisplayObject3D, which will act as the container for the front and back faces of our card

var card:DisplayObject3D = new DisplayObject3D;
/*MovieMaterial(movieAsset:DisplayObject = null, transparent:Boolean = false, animated:Boolean = false, precise:Boolean = false, rect:Rectangle = null)*/
var backMat = new MovieMaterial (backface,false,true,true);
backMat.smooth = true;
backMat.interactive = true; /*set the interactive property of the InteractiveScene3DEvent to true, since we want to be able to click to flip*/

//BitmapFileMaterial(url:String = "", precise:Boolean = false)
var frontMat = new BitmapFileMaterial ("cardFront.jpg");
frontMat.smooth = true;
frontMat.interactive = true;

/*Plane(material:MaterialObject3D = null, width:Number = 0, height:Number = 0, segmentsW:Number = 0, segmentsH:Number = 0)*/

var back:Plane = new Plane(backMat, 360, 200, 3,3);
back.rotationX = 180; //b/c it is the backside and we want it to be rightside up when we flip the card
back.z = 1; // places it one pixel back in z space

var front:Plane = new Plane (frontMat, 360,200,3,3);

addChild(view); //adds our BasicView to the stage
card.addChild (back);//adds back Plane to the card DisplayObject3D
card.addChild(front);//adds front Plane to the card DispalyObject3D
view.scene.addChild(card); //adds card DisplayObject3D to the scene of our BasicView

function addInteraction(e:Event = null):void {
back.addEventListener (InteractiveScene3DEvent.OBJECT_PRESS, flip);
front.addEventListener(InteractiveScene3DEvent.OBJECT_PRESS, flip);
}

/*we need to remove the InteractiveScene3DEvents when the mouse cursor is over the button on the obverse side since we do not want the card to flip when the button is clicked*/
function removeInteraction(e:Event):void {
back.removeEventListener (InteractiveScene3DEvent.OBJECT_PRESS, flip);
front.removeEventListener(InteractiveScene3DEvent.OBJECT_PRESS, flip);
}

function flip(e:InteractiveScene3DEvent):void {
TweenLite.to (card, .75, {rotationX:"180"}); /*Animates the Card Flip, 180 is in quotations so TweenLite reads it as a relative value*/
}

function render(e:Event):void {
view.singleRender();

}

addInteraction();
addEventListener(Event.ENTER_FRAME, render);
backface.addEventListener ("btnOver",removeInteraction); //listens for MouseOver event in BackFace library asset.
backface.addEventListener ("btnOut", addInteraction);//listens for MouseOut event in BackFace library asset