Archive for the ‘Actionscript’ Category
HDVideoPlayer class
Posted by Fabricio in Actionscript, Design, Interactive, Xperiments / Tuts on April 5th, 2010
I worked on a project where I built a video player. So far, nothing out of normality.
The issue was that we decided to set up the video dimensions on the Flash side rather than in the CMS with checkboxes or something similar.
Video dimensions vary in width and height, but also in proportion, or aspect ratio.
The client had all sorts of videos, 640 x 480, 400 x 300, 1280 x 720, etc.
The solution is to detect the file dimensions in an onMetaData event handler and set your visual elements accordingly.
For wide screen mode I decided to draw the black stripes on top and bottom.
I use the NetStream and NetConnection objects to handle the video file.
Preview:
HD video player
Here is the source code for the video player class.
HDVideoPlayer.as:
package src{
/*Import*/
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.media.SoundTransform;
import flash.media.Video;
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.display.*;
import flash.events.*;
import flash.geom.*;
import caurina.transitions.*;
import caurina.transitions.properties.ColorShortcuts;
/*Class*/
public class HDVideoPlayer extends MovieClip {
/*Properties*/
private var mVideo:Video;
private var ncVideo:NetConnection = new NetConnection();
private var nsVideo:NetStream;
private var netClient:Object = new Object();
private var mySound:SoundTransform;
private var videoDuration:Number;
private var actualTime:Number = 0;
private var actualTimeDragger:Number;
private var actualLength:Number;
private var volPercentage:Number;
private var pctLoaded:Number;
private var pctPlayed:Number;
private var dragTime:Number;
private var videoURL:String = new String();
private var MODE:String;
private var mBG:Sprite = new Sprite();
private var mBlackStripes:Sprite = new Sprite();
private var mBGBar:Sprite = new Sprite();
private var mProgressBar:Sprite = new Sprite();
private var mLoadBar:Sprite = new Sprite();
private var mDragger:Sprite = new Sprite();
private var mControl:MovieClip = new MovieClip();
private var mPlay:PlayPause = new PlayPause();
private var mStop:Stop = new Stop();
private var mVolume:Volume = new Volume();
private var bFull:Full = new Full();
private var bBack:Back = new Back();
private var tAlert:TextField;
private var format:TextFormat = new TextFormat();
private var volEquation:Number;
private var videoWidth:Number;
private var videoHeight:Number;
private var ratio:Number;
private var diffDragger:Number = 0;
private var overColor:uint;
/*Constructor*/
public function HDVideoPlayer(fileData:Object):void{
trace("//---> HDVideoPlayer");
videoURL = fileData.file;
overColor = 0xFFFFFF;
ColorShortcuts.init();
addEventListener(Event.ADDED_TO_STAGE, init);
};
private function init(e:Event):void{
removeEventListener(Event.ADDED_TO_STAGE, init);
addEventListener(Event.REMOVED_FROM_STAGE, removedFromStage);
buildVideo();
};
private function removedFromStage(e:Event):void{
trace("// ---- HDVideoPlayer removed from stage");
mySound.volume = 0;
nsVideo.soundTransform = mySound;
nsVideo.close();
ncVideo.close();
mVideo.clear();
mVideo.alpha = 0;
removeEventListener(Event.REMOVED_FROM_STAGE, removedFromStage);
};
public function buildVideo ():void{
MODE = "SD";
mBG.graphics.beginFill(0x231F20, 1);
mBG.graphics.drawRect(0, 0, 400, 364);
mBG.graphics.endFill();
mBG.alpha = 0;
addChild(mBG);
mBlackStripes.graphics.beginFill(0x000000, 1);
mBlackStripes.graphics.drawRect(0, 0, 400, 300);
mBlackStripes.graphics.endFill();
addChild(mBlackStripes);
mPlay.x = 25;
mPlay.y = 14;
mControl.addChild(mPlay);
mStop.x = 64;
mStop.y = 14;
mControl.addChild(mStop);
bFull.x = 175;
bFull.y = 10;
bFull.visible = false;
mControl.addChild(bFull);
bBack.x = -12;
bBack.y = -12;
bBack.visible = false;
addChild(bBack);
mVolume.x = 302;
mVolume.y = 18;
mControl.addChild(mVolume);
mBGBar.graphics.beginFill(0x3F3F3F, 1);
mBGBar.graphics.drawRect(0, 0, 400, 3);
mBGBar.graphics.endFill();
mBGBar.x = 0;
mBGBar.y = 54;
mControl.addChild(mBGBar);
mLoadBar.graphics.beginFill(0xFFFFFF, 1);
mLoadBar.graphics.drawRect(0, 0, 400, 3);
mLoadBar.graphics.endFill();
mLoadBar.x = 0;
mLoadBar.y = 54;
mLoadBar.width = 0;
mControl.addChild(mLoadBar);
mProgressBar.graphics.beginFill(0xF5F5F5, 1);
mProgressBar.graphics.drawRect(0, 0, 400, 3);
mProgressBar.graphics.endFill();
mProgressBar.x = 0;
mProgressBar.y = 54;
mProgressBar.alpha = 0;
mControl.addChild(mProgressBar);
mDragger.graphics.beginFill(0xFFFFFF, 1);
mDragger.graphics.drawRect(0, 0, 14, 7);
mDragger.graphics.endFill();
mDragger.x = 0;
mDragger.y = 47;
mControl.addChild(mDragger);
diffDragger = mBGBar.width - mDragger.width;
tAlert = new TextField();
tAlert.autoSize = TextFieldAutoSize.CENTER;
tAlert.x = 120;
tAlert.width = 160;
tAlert.height = 14;
tAlert.textColor = 0xFFFFFF;
format.font = "Arial";
format.bold = true;
format.color = 0xFFFFFF;
format.size = 8;
tAlert.defaultTextFormat = format;
mControl.addChild(tAlert);
mControl.y = 308;
mControl.alpha = 0;
addChild(mControl);
Tweener.addTween(mDragger,{_color:overColor, time:0});
Tweener.addTween(mControl, {alpha:1, time:1, transition:"linear",
onComplete:function(){
connectVideo();
}
});
};
public function connectVideo ():void{
//Video connection
ncVideo.connect(null);
nsVideo = new NetStream(ncVideo);
nsVideo.client = this;
nsVideo.bufferTime = 5;
mVideo = new Video();
mVideo.x = 0;
mVideo.y = 0;
addChild(mVideo);
this.swapChildren(mVideo, bBack);
mVideo.attachNetStream(nsVideo);
nsVideo.play(videoURL);
mVideo.smoothing = true;
mPlay.gotoAndStop(1);
//Sound
mySound = nsVideo.soundTransform;
mySound.volume = 1;
nsVideo.soundTransform = mySound;
//Bars
mLoadBar.width = 0;
mProgressBar.width = 0;
//Listeners
nsVideo.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
bFull.addEventListener(MouseEvent.MOUSE_DOWN, buildVideoHD);
bFull.addEventListener(MouseEvent.ROLL_OVER, eventOver);
bFull.addEventListener(MouseEvent.ROLL_OUT, eventOut);
bBack.addEventListener(MouseEvent.MOUSE_DOWN, backVideo);
bBack.addEventListener(MouseEvent.ROLL_OVER, eventOver);
bBack.addEventListener(MouseEvent.ROLL_OUT, eventOut);
mPlay.addEventListener(MouseEvent.MOUSE_DOWN, pauseVideo);
mPlay.addEventListener(MouseEvent.ROLL_OVER, eventOver);
mPlay.addEventListener(MouseEvent.ROLL_OUT, eventOut);
mStop.addEventListener(MouseEvent.MOUSE_DOWN, stopVideo);
mStop.addEventListener(MouseEvent.ROLL_OVER, eventOver);
mStop.addEventListener(MouseEvent.ROLL_OUT, eventOut);
mDragger.addEventListener(MouseEvent.MOUSE_DOWN, dragSeek);
mVolume.mVolSlider.addEventListener(MouseEvent.MOUSE_DOWN, volumeScrubberClicked);
stage.addEventListener(MouseEvent.MOUSE_UP, volumeScrubberUnClicked);
mVolume.mVolSlider.addEventListener(MouseEvent.ROLL_OVER, volumeScrubberRolledOver);
mLoadBar.addEventListener(Event.ENTER_FRAME, loadBar);
mPlay.buttonMode = true;
mStop.buttonMode = true;
bFull.buttonMode = true;
bBack.buttonMode = true;
mDragger.buttonMode = true;
mVolume.mVolSlider.buttonMode = true;
mPlay.dispatchEvent(new MouseEvent(MouseEvent.ROLL_OUT));
mStop.dispatchEvent(new MouseEvent(MouseEvent.ROLL_OUT));
bFull.dispatchEvent(new MouseEvent(MouseEvent.ROLL_OUT));
bBack.dispatchEvent(new MouseEvent(MouseEvent.ROLL_OUT));
};
public function eventOver (e:MouseEvent):void{
Tweener.addTween(e.currentTarget, {alpha:1, time:0.2, transition:"linear"});
};
public function eventOut (e:MouseEvent):void{
Tweener.addTween(e.currentTarget, {alpha:.5, time:0.2, transition:"linear"});
};
public function netStatusHandler(evt:NetStatusEvent):void{
if(evt.info.code == "NetStream.FileStructureInvalid"){
tAlert.text = "File structure invalid. ";
}else if(evt.info.code == "NetStream.NoSupportedTrackFound"){
tAlert.text = "File is not supported. ";
}else if (evt.info.code == "NetStream.Play.StreamNotFound") {
tAlert.text = "Error: Stream not found. ";
}else if (evt.info.code == "NetStream.Play.Start") {
tAlert.text = "Buffering video... ";
trace("evt.info.code --->>> "+evt.info.code+"\n")
}else if (evt.info.code == "NetStream.Buffer.Empty") {
tAlert.text = "Buffering video... ";
trace("evt.info.code --->>> "+evt.info.code+"\n")
}else if (evt.info.code == "NetStream.Buffer.Full") {
mPlay.gotoAndStop(2);
trace("evt.info.code --->>> "+evt.info.code+"\n")
tAlert.text = " ";
}else if (evt.info.code == "NetStream.Play.Stop"){
mPlay.gotoAndStop(1);
trace("evt.info.code --->>> "+evt.info.code+"\n")
}
};
public function onMetaData(obj:Object):void{
for(var propName:String in obj){
//trace("**Metadata video: "+propName + " = " + obj[propName])
if (propName == "width") {
videoWidth = obj[propName]
}
if (propName == "height") {
videoHeight = obj[propName]
}
};
ratio = videoHeight/videoWidth;
ratio = Number(ratio.toFixed(4));
//trace("videoWidth original ---> "+videoWidth)
//trace("videoHeight original ---> "+videoHeight)
//trace("ratio ---> "+ratio)
addEventListener(Event.ENTER_FRAME, dragSeekBar);
videoDuration = obj.duration;
setVideo();
};
private function setVideo():void{
if (MODE == "SD") {
mVideo.width = 400;
if (ratio < 0.6) {
bFull.visible = true;
mVideo.y = 36;
}else{
mVideo.y = 0;
bFull.visible = false;
}
}else if (MODE == "HD960"){
mVideo.width = 960;
}else if (MODE == "HD640"){
mVideo.width = 640;
}
mVideo.height = Math.round(mVideo.width*ratio);
trace("mVideo.height adjusted ---> "+mVideo.height)
};
public function buildVideoHD(obj:Object):void{
if (stage.stageHeight < 810) {
MODE = "HD640";
mBG.width = 640;
mBG.height = 424;
mBlackStripes.width = 640;
mBlackStripes.height = 360;
mBGBar.width = 640;
mLoadBar.width = 640;
mProgressBar.width = 640;
mControl.y = 368;
mVolume.x = 530;
bFull.x = 300;
bFull.visible = false;
bBack.x = -13;
bBack.visible = true;
tAlert.x = 320;
mVideo.y = 0;
setVideo();
diffDragger = mBGBar.width - mDragger.width;
}else{
MODE = "HD960";
mBG.width = 960;
mBG.height = 604;
mBlackStripes.width = 960;
mBlackStripes.height = 540;
mBGBar.width = 960;
mLoadBar.width = 960;
mProgressBar.width = 960;
mControl.y = 548;
mVolume.x = 850;
bFull.x = 460;
bFull.visible = false;
bBack.x = -13;
bBack.visible = true;
tAlert.x = 480;
mVideo.y = 0;
setVideo();
diffDragger = mBGBar.width - mDragger.width;
}
};
public function backVideo(obj:Object):void{
MODE = "SD";
mBG.width = 400;
mBG.height = 364;
mBlackStripes.width = 400;
mBlackStripes.height = 300;
mBGBar.width = 400;
mLoadBar.width = 400;
mProgressBar.width = 400;
mControl.y = 308;
mVolume.x = 302;
bFull.x = 175;
bBack.visible = false;
tAlert.x = 120;
setVideo();
diffDragger = mBGBar.width - mDragger.width;
};
public function pauseVideo(evt:MouseEvent):void{
if (mPlay.currentFrame == 2) {
mPlay.gotoAndStop(1);
nsVideo.pause();
}else{
mPlay.gotoAndStop(2);
setVideo();
nsVideo.resume();
}
};
public function stopVideo(evt:MouseEvent):void{
nsVideo.pause();
nsVideo.seek(0);
mPlay.gotoAndStop(1);
};
public function loadBar(evt:Event):void{
//trace("buffer ---> "+nsVideo.bufferLength)
pctLoaded = Math.floor(nsVideo.bytesLoaded / nsVideo.bytesTotal * 100);
Tweener.addTween(mLoadBar, {width: (mBGBar.width * pctLoaded) / 100, time:1, transition:"linear"});
if (pctLoaded >= 100){
evt.currentTarget.removeEventListener(Event.ENTER_FRAME, loadBar);
}
};
public function dragSeekBar(evt:Event):void{
actualTime = nsVideo.time;
Tweener.addTween(mDragger, {x: Math.round(actualTime / videoDuration * diffDragger), time:.1, transition:"linear"});
actualTime = nsVideo.time;
if (Math.round(actualTime) == Math.round(videoDuration)){
Tweener.addTween(this, {time:1, transition:"linear",
onComplete:function(){
tAlert.text = "";
nsVideo.pause();
nsVideo.seek(0);
mPlay.gotoAndStop(1);
}
});
}
};
public function dragSeek(evt:Event):void{
//actualTimeDragger = int(((evt.currentTarget.x) / mBGBar.width) * videoDuration);
nsVideo.pause();
removeEventListener(Event.ENTER_FRAME, dragSeekBar);
Tweener.removeAllTweens();
stage.addEventListener(MouseEvent.MOUSE_UP, dragSeekOut);
evt.currentTarget.startDrag(false, new Rectangle(0,47,diffDragger,0));
};
public function dragSeekOut(evt:MouseEvent):void{
dragTime = Math.round(mDragger.x / diffDragger * videoDuration);
actualTime = dragTime;
mDragger.x = (actualTime / videoDuration * diffDragger);
nsVideo.seek(dragTime);
nsVideo.resume();
mPlay.gotoAndStop(2);
mDragger.stopDrag();
stage.removeEventListener(MouseEvent.MOUSE_UP, dragSeekOut);
addEventListener(Event.ENTER_FRAME, dragSeekBar);
};
public function volumeScrubberClicked(evt:Event):void {
mVolume.mVolSlider.startDrag(false, new Rectangle(8, 0, 66, 0));
mVolume.mVolSlider.addEventListener(Event.ENTER_FRAME, volumeScrubberSlide);
};
public function volumeScrubberRolledOver(evt:Event):void {
evt.currentTarget.buttonMode = true;
};
public function volumeScrubberUnClicked(evt:Event):void {
mVolume.mVolSliderbuttonMode = false;
mVolume.mVolSlider.stopDrag();
mVolume.mVolSlider.removeEventListener(Event.ENTER_FRAME, volumeScrubberSlide);
};
public function volumeScrubberSlide(evt:Event):void{
volEquation = (100*(evt.currentTarget.x - 8))/66;
volPercentage = volEquation / 100;
mySound.volume = volPercentage;
nsVideo.soundTransform = mySound;
};
public function formatTime(t:int):String {
// returns the minutes and seconds with leading zeros
// for example: 70 returns 01:10
var s:int = Math.round(t);
var m:int = 0;
if (s > 0) {
while (s > 59) {
m++;
s -= 60;
}
return String((m < 10 ? "0" : "") + m + ":" + (s < 10 ? "0" : "") + s);
}else {
return "00:00";
}
};
};// end player class
};// end package
You can download the entire source code here:
The library contains all the visual elements and in the Main.as file you can change which video sample to play.
There are three high-def videos to play with.
I uploaded them separately because they are quite big.
So, download it from here and place it in the video folder from the HDVideo_source.zip file.
Arduino + Flash + Wii
Posted by Fabricio in Actionscript, Design, Interactive on April 6th, 2010
More and more I want to have a chance to work on a project using Arduino!
Check this example out:
Arduino + Flash + Wii Nunchuck + Servos + Webcam
CaT 2009: Open Source Everything
Posted by Fabricio in Actionscript, Art, Design, Interactive on April 6th, 2010
Ben Fry, co-founder of Processing and director of Seed Phyllotaxis Lab and Carlos Ulloa, founder and creator of Papervision3D and HelloEnjoy talk about their software as well as their views on the future of open source and collaboration.
Quick thoughts on Flash vs. HTML5
Posted by Fabricio in Actionscript, Business, Design, Misc on April 5th, 2010
Well, recently there has been a lot of discussion on the future of Flash or the web.
Just because some known websites and companies have chosen HTML5 as an alternative for their development.
I’d like to say this is not a biased statement, but I have to point out the pros and cons of each technology accordingly to my perspective and past experience.
First, I have coded, learned, failed and succeeded with both.
Back in the day I was so amused by the fact that we could code for visual purposes, at least for the web.
So, html came into play and it was fun understanding how all that could be wrapped with data and server-side processing.
From iframes to tables and later divs the language was evolving, slowly but forward.
And that is my point, it takes decades to something new get implemented in html, it took a long time to have a video tag!
Not to mention that html is an interpreted language, not compiled. It needs support form other technologies such as Javascript or back-end ones.
Now, the good part, it can be accessed from any browser, despite some incompatibilities, any app or device.
I am pretty sure that will evolve more in the short-term, new libraries and frameworks of all kinds will be more popular, useful and reliable.
On the other hand, Flash which is mistakenly know only as an animation program, or a way to “make annoying banners” for some (I am serious, I heard that so many time!s) is largely used for delivering digital content on the web, such as video (Youtube owes Flash a lot!), interactivity, 3d, etc.
From a basic prototyped language to a OOP version its language became a powerful resource for web development and adds that dynamic touch as if the webpage is another canvas itself.
There is a lot more to tell and discuss for both technologies, but to make my point clear, I am trying to say that both technologies are useful and there should be no need for such war. It reminds me of the Cold War, Coca-cola vs. Pepsi or Nike vs. Adidas, which means both sides, I mean both side supporters, are more concerned in attacking each other rather than providing better solutions for each technology.
When planes first came out, we didn’t loose cars, bikes or any other type of vehicles. Unfortunately, most people depend on cars more than anything else, but people support alternatives to that.
What about the user?Have we forgot it?To me this should all be about having a better experience on the web, whether it is done in Flash or HTML5. You also need a plug-in (runtime) for Java if you visit a webpage that contains Java apps or applets and still no one mentions that as a turn down for Java. Why do they do it for Flash?
Certainly, HTML5 will benefit the web and Flash use will decrease in the following years, but wouldn’t it be great if they both continue as the main technologies for front-end development? Who is the evil and the good guy here?
Behind this debate there are some many things we don’t know about it, corporations interested in increasing their profits and extinguishing competitors.
My advice for users is use both, don’t complain if it’s Flash the webpage you visit, you probably don’t know how much effort there is in order to bring you that information.
Also, don’t complain if that HTML5 site is killing your processor due to a canvas animation in the background. Eventually, you will have to choose one for certain apps, but don’t feel guilty in your decision, find a way to support both.
For developers, be aware of what’s going on, try them both, the more you understand both, the broader will be your options when it comes to use one technology for a specific project. You may like one more than the other, but coldly analyze what fits better your skills and needs for each app you work on.
Below is some good articles I read in the past few days. It’s more info for you to be wisely involved in this buzz.
Dan Mall post about the Cold War of the Web
Adobe Engineer explaining the nuances of Core Animation in Cocoa (MacOS)
Roundoff error
Posted by Fabricio in Actionscript on April 5th, 2010
Computers still do wrong calculations!
Adobe says: “This is not a bug in Flash. This is an example of roundoff error, a fundamental issue in floating-point arithmetic.”
Indeed, it’s true, but it’s an exception, it is bound to happen due to mathematics nature.
A floating point is not exact.
Check it out:
Adobe Technote
Fourier Transform
Posted by Fabricio in Actionscript, Misc on April 5th, 2010
Recently I had to do some research on the Fourier Transform, a calculus technique which allows one to manipulate frequencies from a signal wave.
I could spend hours studying and discussing the Transform, but I just wanted to post a technical link from MathWorks.
They are the manufacturer of MATLAB, a powerful software for spectrum analysis which I used 6 years ago in school.
It is also widely used in all sorts of engineering, image processing, intensive computational tasks and so on.
More info : MatLab
In my case I have wave signal being the input and I want to sample data from the frequency spectrum.
The problem is that using a Discrete Fourier Transform, processing goes up to the ceiling.
The solution is to use a Fast Fourier Transform that makes a distinction between the window length and the transform length.
That decreases the computational complexity from O(n2) to O(n log n).
Let’s see if that helps me in my project.
I’ll make updates to this post.
Meanwhile, take a read:
Fast Fourier Transform
DUI – Drawing under the influence
Posted by Fabricio in Actionscript, Design, Interactive, Xperiments / Tuts on April 4th, 2010
In this little experiment I tried to change usual mouse interaction to something similar to a staggery or frantic effect.
It all depends on the type of effect chosen. Options given are related to known drug effects.
In fact, I wish there was a different kind of way to interact with our precious machines.
I’ve seen stuff around and it may be bound to happen soon.
See it live:
Download source and doc:
AS cue points and custom events – SunLife video website
Posted by Fabricio in Actionscript, Xperiments / Tuts on April 4th, 2010
I recently worked on a website that contains a “talking” video along six different sections, each with its own video.
The challenge was to create a custom event class to assign and handle actionscript cue points.
One other aspect worth pointing out was the loader, which needed to be a circular mask that reveals
the layer below in a “clock wipe” or “pie chart” type of transition.
As easy as it may sound, drawing such shape, or actually making the animation, needed some attention.
After some research, I figured that you actually need to to draw a segment from the center out.
The next segment will be adjacent to the previous one but slightly offset within a circle.
This example uses a percentage variable in an ENTER_FRAME event, but it can be used upon a PROGRESS_EVENT of some sort:
br>
br>
br>
br>
br>
br>
br>
br>
br>
br>
br>
br>
br>
br>
br>
br>
br>
br>
br>
br>
br>
br>
br>
Source:
br>
br>
package src{
import flash.display.*;
import flash.events.*;
public class CircleLoader extends MovieClip{
private var circleLoader:MovieClip;
private var percentage:Number = 0;
public function CircleLoader() : void{
trace("//---> CircleLoader");
circleLoader = new MovieClip();
addEventListener(Event.ADDED_TO_STAGE, init);
};
private function init(event:Event) : void{
removeEventListener(Event.ADDED_TO_STAGE, init);
addChild(circleLoader);
circleLoader.radius = 80;
addEventListener(Event.ENTER_FRAME, circleEnterFrame);
};
public function circleEnterFrame(event:Event) : void{
percentage = (percentage + 1);
MovieClip(this.parent).tLoader.text = String(percentage.toFixed(0));
if (percentage > 100){
//removeEventListener(Event.ENTER_FRAME, doMask);
percentage = 0;
}
var endAngle:Number;
var startAngle:Number;
if (!isNaN(percentage)){
graphics.clear();
endAngle = 2 * Math.PI * percentage / 100;
startAngle = 0;
if (endAngle != startAngle){
graphics.lineStyle(2, 0, 0.5);
graphics.beginFill(0x003299, 0.5);
graphics.lineTo(-circleLoader.radius, 0);
CircleSegmentTo(0, 0, startAngle, endAngle, -circleLoader.radius, 1);
graphics.lineTo(0, 0);
graphics.endFill();
}
}
};
public function CircleSegmentTo(x, y, a1, a2, r, dir) : MovieClip{
var diff = Math.abs(a2 - a1);
var divs = Math.floor(diff / (Math.PI / 4)) + 1;
var span = dir * diff / (2 * divs);
var rc = r / Math.cos(span);
graphics.moveTo(x + Math.cos(a1) * r,y + Math.sin(a1) * r);
for (var e = 0; e < divs; ++e){
a2 = a1 + span;
a1 = a2 + span;
graphics.curveTo(x + Math.cos(a2) * rc,
y + Math.sin(a2) * rc,
x + Math.cos(a1) * r,
y + Math.sin(a1) * r);
}
return this;
};
};//end class
};//end package
So, for the actionscript cue point event I created a class named “CueEvent.as” which holds a string as a parameter to differ from other objects of the same class.
From up-down understanding of the hierarchy, my Main class instantiates a FLVPlayer class and adds a listener of type “VIDEOCUE” (public property in my CueEvent class):
Main.as:
public var mVideo:FLVPlayer;
mVideo.addEventListener("VIDEOCUE", cuePointHandler);
private function cuePointHandler(event:CueEvent) : void{
var e:* = event;
trace(" Cue point is: " + e.option);
if (e.option == "innovative"){ }
};
The FLVPlayer class contains a FLVPlayback instance to load up and play the video.
All that needs to be done is add a listener and the cue points to the FLVPlayback instance:
1. Add the built-in MetadataEvent.CUE_POINT
2. Add each cue point event using the addASCuePoint method passing two parameters (time, name)
3. In the callback function for the listener dispatch the custom event rather than a simple Event object:
We need the name assigned to the FLVPlayback instance in the Main class (cuePointHandler of the Main class) in order to make decisions for each cue point.
FLVPlayer.as:
public var mVideo:FLVPlayback;
mVideo.addASCuePoint(10.36, "innovative");
mVideo.addEventListener(MetadataEvent.CUE_POINT, cuePointHandler);
private function cuePointHandler(event:MetadataEvent) : void{
dispatchEvent(new CueEvent(CueEvent.VIDEOCUE, String(event.info.name)));
};
Finally, the custom event class has two important properties.
One string to be the type of event (VIDEOCUE) and another one to hold the name of the cue point.
CueEvent.as:
package src{
import flash.events.*;
public class CueEvent extends Event{
private var _option:String = "none";
public static const VIDEOCUE:String = "VIDEOCUE";
public function CueEvent(param1:String, param2:String) : void{
super(param1, true);
_option = param2;
return;
};
public function get option() : String{
return _option;
};
override public function clone() : Event{
return new CueEvent(type, _option);
};
};//end class
};//end package
Remember, CueEvent is a public class that extends the Event class used in the FLVPlayer class without being a instance variable inside of FLVPlayer.as.
We simply dispatch the event: dispatchEvent(new CueEvent(CueEvent.VIDEOCUE, String(event.info.name)));
The Main class instantiates the FLVPlayer class in a variable. That’s how it is structured.
When running the file, your player should start and when the playhead reaches the exact time you assigned
in the addASCuePoint method you will have an event triggered in your Main class with the name of your cue point event.
All this helped me understand better the way custom events work and on top of that,
I associated actionscript cue points for FLV playback passed up to your the level.
For each cue point added I receive its name and decide on which graphics to instantiate and animate.
For the Intro video I added these cue points:
mVideo.addASCuePoint(10.36, “innovative”);
mVideo.addASCuePoint(11.75, “tools”);
mVideo.addASCuePoint(13.13, “support”);
mVideo.addASCuePoint(22.68, “board”);
mVideo.addASCuePoint(24.41, “moveboard”);
mVideo.addASCuePoint(27.84, “dynamic”);
mVideo.addASCuePoint(29.53, “easy”);
mVideo.addASCuePoint(31.12, “innovativetech”);
mVideo.addASCuePoint(32.84, “intuitive”);
mVideo.addASCuePoint(34.51, “advisor”);
mVideo.addASCuePoint(36.02, “compensation”);
mVideo.addASCuePoint(44.34, “switch”);
mVideo.addASCuePoint(46.06, “pull”);
mVideo.addASCuePoint(47.51, “servicesolutions”);
mVideo.addASCuePoint(49.01, “productssolutions”);
mVideo.addASCuePoint(50.75, “insightsolutions”);
mVideo.addASCuePoint(52.16, “websolutions”);
mVideo.addASCuePoint(53.82, “compensationsolutions”);
mVideo.addASCuePoint(69.87, “out”);
mVideo.addASCuePoint(73.31, “discover”);
mVideo.addASCuePoint(75.91, “end”);
You can view the project running on my server.
Sunlife Solutions
School of Animation, Arts and Design PV3D sphere
Posted by Fabricio in Actionscript, Art, Design on April 5th, 2010
We recently worked on a template website for the Sheridan School of Animation, Arts and Design.
It took a lot of effort to understand how to make the mouse move a sphere and still be able to get the mouse location on a click.
Clicking on a picture brings it to the front and so on.
It is still buggy, but I will eventually upload a fixed version.
The problem is that the school has not decided if they want to continue on the project,
and for that reason and other projects I have to work on, Kevin and I haven’t been able to finish it.
Check it out:
SAAD sphere
[ Portfolio projects remaining list ]
Posted by Fabricio in Actionscript, Design, Interactive on April 4th, 2010
This list contains previous projects I worked on and were not included in my portfolio featured list.
Each project contains a link, a thumbnail and a larger image of one page.
Enjoy it!
O’Pub
O’Pub Augmented Reality
O’Pub
![]()

DeepCover
DeepCover is an image game. The challenge here was to serialize/parse bytearrays to a bitmapdata object and save the picture locally.
![]()

SociedadeDDP
SociedadeDDP is a multidisciplineray communication agency.
It aims non-traditional advertising through resource optimization and efficient communication.
Visual identity for each section of the site.
![]()

Ao Vivo
Light, camera, action!
Release of a 15 min. movie about a girl’s delirium to become famous.
Object of movie production debates and summits.
World-wide nominee for film festivals.
![]()

Feelmes
A growing film production company.
Website displays their reel and the logo.
Feel me.
![]()

Relax Medic
Relax Medic is a dealer of products designed for relaxation purposes.
Quality of life matters the most.
Dynamic integration with the product database and all effects for each section made me wanna work using one of their chairs!
![]()

Mater
Mater is a reproductive medicine center with facilities in different countries.
They are specialized in human offspring fertility and all treatment options.
Two leveled navigation system to exposure all content, from staff to treatments and articles.
![]()

Claus Lehmann
Photographer portfolio.
Showcase for his selected pieces along with roll over effects and bitmapdata manipulation.
![]()

The Globe and Mail banner
RSS feed banner for the auto section.
![]()

Autohound banner
AutoHound.ca features used cars and trucks for sale in Canada.
Interactive banner for MSN Auto portal.
![]()

SoftFluid
High-tech infra-strucure company.
Networking services including design, installation & maintenance for professional environments.
Fancy robotic effects implemented to display the necessary information for any client of theirs.
![]()

Soberan
Agricultural and rural product manufactered by Bayer.
Bayer’s intranet showcase for this product, the project involved animations, charts and xml navigation to ensure the success and popularity of the project.
![]()

Medco
Number one pharmacy benefit management company in the US.
Worked with the IBM B2C team implementing new requirements and maintanance.
From the jsp client side to the Broadvision framework and C++ components.
![]()

Sotheby’s eGallery
Sotheby’s International Realty Canada is a premier full-service luxury real estate portfolio management brokerage with an experienced team of real estate sales and marketing professionals that provide marketing and sales services.
Worked with the server side team to integrate data for a slideshow displayed in a plasma TV in all SIR offices around the world.
![]()

Sotheby’s
Sotheby’s International Realty is a premier full-service luxury real estate portfolio management brokerage with an experienced team of real estate sales and marketing professionals that provide marketing and sales services.
One year project for IBM.
Web designed new pages and the map application.
![]()
