Archive for category ActionScript 3

VideoMaterial with Away3D (version 3.6)

I was trying to map a video to a sphere today, so I wanted to use the VideoMaterial in Away3D, but I wasn’t finding any example on it. Also seems like it is not that straight forward so let me put an example here.

Here is the base code for it (I guess SphereView could be compiled):

public function SphereView() {
  scene = new Scene3D();
 
  camera = new Camera3D();
  camera.fov = 35;
  camera.z = 0;
 
  view = new View3D();
  view.scene= scene;
  view.camera = camera;
  addChild(view);
 
  material2 = new VideoMaterial({lockW:2000, lockH:1000});
  material2.loop = true;
  material2.file = "../flv/test2.flv";
  material2.smooth = true;
 
  sphere = new Sphere();
  sphere.material = material2;
  sphere.radius = 2000;
  sphere.segmentsW = 40;
  sphere.segmentsH = 20;
  sphere.invertFaces();
 
  spherecontainer = new ObjectContainer3D(sphere);
  scene.addChild(spherecontainer);
 
  addEventListener(Event.ENTER_FRAME, _onEnterFrame);
  addEventListener(Event.ADDED_TO_STAGE, _onAddedToStage);
}

I had to fiddle a bit with the Away3D VideoMaterial.as to make it accept my very wide video. Find the function playStream and replace it with this one:

private function playStream():void {
  _netStream = new NetStream(nc);
  _netStream.checkPolicyFile = true;
  _netStream.client = CustomClient;
  _netStream.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler,false,0,true);
  _netStream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, ayncErrorHandler,false,0,true);
  _netStream.addEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler,false,0,true);
  play();
 
  if(video == null){
    // Setup video object
    video = new Video(_lockH, _lockW);
    video.smoothing = true;
    sprite.addChild(video);
  }
 
  video.attachNetStream(_netStream);
}

All I needed to do was add _lockW and _lockH to the Video constructor, but it improved the quality of the played video (it was 320×240 before, the default value of Video). Now with this you should be able to start mapping your own videos inside of a sphere. Oh yeah if you want it, here are the functions that are missing in the first snippets, they basically enable you to move the camera around.

private function _onAddedToStage(event : Event) : void {
  view.x = stage.stageWidth / 2;
  view.y = stage.stageHeight / 2;
 
  stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
  stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);			
}
 
private function _onEnterFrame(event:Event):void{					
  if (move) {
    spherecontainer.rotationX = (mouseY - lastMouseY)/10 + lastRotationX;
    if (spherecontainer.rotationX > 90)
      spherecontainer.rotationX = 90;
    if (spherecontainer.rotationX < -90)
      spherecontainer.rotationX = -90;
    sphere.rotationY = (lastMouseX - mouseX)/10 + lastRotationY;
  }			
  view.render();
}
 
private function onMouseDown(event:MouseEvent):void{
  lastRotationX = spherecontainer.rotationX;
  lastRotationY = sphere.rotationY;
  lastMouseX = mouseX;
  lastMouseY = mouseY;
  move = true;
}
 
private function onMouseUp(event:MouseEvent):void{
  move = false;  
}

, , ,

4 Comments


TLFTextfield blocking “ENTER” Keyboard event

Probably my last post about TLFTextfied for a little while. This is going to be a quick one and was actually found by my colleague Will Adams. Also he found the solution somewhere else on the web but I can’t find it anymore so I thought it would be good to post it here too.

So here is the problem, if you use TLFTexfields as input fields for your form and you want to listen for the user pressing the “ENTER” key to submit the form, if at that moment the focus is on the input field, you won’t be able to listen for it. So normally, you would put the Keyboard event listener on the stage so that it doesn’t matter which textfield the user is on, if he presses “ENTER”, it will submit the form. Turns out that for some reasons, TLFTextfield will block that event from firing. Funny thing, is that it doesn’t block other key press events from firing just the “ENTER” (or “RETURN”).

Now for the quick fix:

_tlfTextfield.getChildAt(1).addEventListener(KeyboardEvent.KEY_UP, _onKeyPressed);

So you will have to add this to every of your textfields, which is a bit annoying, but it will make it work. I don’t know how the guy that found this found it, but I’m sure glad he did.

,

2 Comments


Difference between TextField and TextBloc (or TextLine)

Ok I have been writing a lot about TLF Framework lately and it is definitely not my favorite topic but I thought people should be aware of this. So here you go : using the new text engine will actually give you better looking text! When I say text engine, I mean using TextBloc and TextLine. Here is a little example I made to show the difference. On the left it is a good old TextField, in the middle we have the new TLFTextField and on the right I am using TextBloc / TextLine (TextBloc for now on).

This movie requires Flash Player 9

As you can see there is nearly no difference between using a TextField and a TLFTextField, the actual code is also the same, the difference is that you need to use a DF4 exported font (some new none-sense setting in Flash CS5). On the other hand, when using TextBloc, it does look better, I agree it is subtle, but it is better. I am writing this post because I was arguing with a colleague that there was no difference, but he showed it to me, I hope this does the same to you.
 

Using TextBloc

Now when using TextBloc, a lot changed from using the good old TextField. First, you need to use the class ElementFormat instead of TextFormat. Here is an example on how to do so:

var font:AvantGardeGothicStdBook = new AvantGardeGothicStdBook(); //this is a font embedded in a swc
var fontDesc:FontDescription = new FontDescription(font.fontName);
fontDesc.fontLookup = FontLookup.EMBEDDED_CFF;
 
var style:ElementFormat = new ElementFormat();
style.fontDescription = fontDesc;
style.fontSize = 32;
style.color = 0xf9827f;

 

When you want to display a single line of text, it is fairly easy to do so. Here is how to do it:

var element:TextElement = new TextElement("TEXTLINE!!!!", style); // we defined style earlier
var textBlock:TextBlock = new TextBlock();			
textBlock.content = element;
var textline:TextLine = textBlock.createTextLine(null, 200);
textline.x = 430;
textline.y = 36;
addChild(textline);

 

The things get more complicated when you want to display a paragraph:

var elementPar:TextElement = new TextElement("This is what some normal text in a textline paragraph looks like. The difference is subtle but there is one with the textline stuff.", stylePar);
var textBlockPar:TextBlock = new TextBlock();
textBlockPar.content = elementPar;
var paragraph:Sprite = new Sprite();
var line:TextLine = textBlockPar.createTextLine(null, 200);
var currentY:Number = 0;
while(line){
	line.y = currentY;
	currentY += line.height;
	paragraph.addChild(line);
	line = textBlockPar.createTextLine (line, 200);
}
paragraph.x = 430;
paragraph.y = 63;
addChild(paragraph);

 

So what now? Should we all start using TextBloc? I don’t know and to be frank it seems like even Adobe doesn’t know. But if you want better looking text, maybe you should.

, , , , , , , ,

No Comments


Donut Charts in AS3

Most of what I write comes from goals that I must achieve through my work and when I search the web to figure out how to do those I find very little information. So usually once I have figured it out I write a post about it. I was looking to create some donut charts which are basically pie charts but with a mask on them to make a hole in the middle. All I could find on the web was solutions that you had to pay for, bundles of charts that looked really bad. So I thought it shouldn’t be that bad to just to them from scratch.

Well I actually didn’t do them from scratch, first I translated some old ActionScript 2 found here to make the donut mask and I used Lee Brimelow wedge class to create the subdivision of the chart. So here are four examples of what you can do with it:

 

This movie requires Flash Player 9

 

And here is the code used to create them:

var wedgeVector:Vector.<ChartWedgeInfo> = new Vector.<ChartWedgeInfo>();
wedgeVector.push(new ChartWedgeInfo(0.3, 0x70ddff));
wedgeVector.push(new ChartWedgeInfo(0.21, 0x56baec));
wedgeVector.push(new ChartWedgeInfo(0.3, 0x2b78d2));
 
_donut1 = new DonutChart(50, 20, 0x1e457a, wedgeVector);
_donut1.x = 60;
_donut1.y = 60;
addChild(_donut1);
 
var wedgeVector2:Vector.<ChartWedgeInfo> = new Vector.<ChartWedgeInfo>();
wedgeVector2.push(new ChartWedgeInfo(0.5, 0xfca25a));
 
_donut2 = new DonutChart(40, 10, 0x821626, wedgeVector2);
_donut2.x = 180;
_donut2.y = 60;
addChild(_donut2);
 
_donut3 = new DonutChart(30, 25, 0x56baec);
_donut3.x = 300;
_donut3.y = 60;
addChild(_donut3);
 
var wedgeVector3:Vector.<ChartWedgeInfo> = new Vector.<ChartWedgeInfo>();
wedgeVector3.push(new ChartWedgeInfo(0.3, 0xfca25a));
wedgeVector3.push(new ChartWedgeInfo(0.3, 0xfd8332));
wedgeVector3.push(new ChartWedgeInfo(0.3, 0xde4649));
wedgeVector3.push(new ChartWedgeInfo(0.3, 0xaa2c34));
wedgeVector3.push(new ChartWedgeInfo(0.3, 0x821626));
 
_donut4 = new DonutChart(50, 30, 0x821626, wedgeVector3);
_donut4.x = 420;
_donut4.y = 60;
addChild(_donut4);

I think it is pretty easy to use. Here are some considerations; if you don’t give in any wedge info, it will just draw a donut, you can give more than 100% for your chart it will just loop, and the chart 0,0 is at the center of the donut. So here you go, you can just download the files below. I think it could be improved a little and there is no options to put labels or anything but it should fit more use cases that way.

DonutChartsSource

, , , ,

8 Comments


RTL languages and the Text Layout Framework

So this is the positive post about the Text Layout Framework that I was talking about earlier. For the current project I am working on I have the joy (read the sarcasm here) to be doing it in 9 languages and if that wasn’t fun enough one of those is Hebrew which is a right to left language. To be frank this kinda make the project really hard but not because of technical reasons, it makes it hard just to put the text at the right place… Anyway I digress, the thing when working with right to left languages is that there is not that much information on it or what you will find is really dated and not relevant anymore. Well it is that way with TLF in general too, so finding information on the subject is really tedious. Actually I didn’t find anything useful on the web and I had to figure things out on my own; that is why I am writing this post. Has I mentioned on the previous post, there are 3 ways to make text using the TLF: TLFTextfield, TextBlock or TextFlow. I will go through all of those and explain how to display RTL language correctly.

TLFTextfield

I find that this is the easiest way to display text using the Text Layout Framework. It is easy because it pretty much works the same as the good old Textfield. A colleague told me that the CSS part of it wasn’t really working and from the documentation it seems to be still in beta. To display a right to left language like Arabic, Hebrew or Persian, this seems like the way to go. Easily enough, it has a property called direction that you can just set to “rtl” and there you go, your text will display properly.

TextBlock

If you think you are going to be doing a version of your site/application for a RTL language, do not use TextBlock. That’s a shame cause this method of displaying text seems to give better looking text, but I was never able to get my Hebrew text displaying properly. It is weird because if you look at the documentation there seems to be a way to do it, using the bidiLevel property and setting it to an odd number (I have no idea why, this seems very unobvious to me). But I tried it and it doesn’t work. The problem arise when you have LTR text inside a RTL paragraph, so let’s say a english word inside a Arabic paragraph. This will greatly confuse the text engine and your text won’t display properly sometimes showing very differently than it the xml it has been taken from (if you pull your text from xml). So in this case, use TLFTextfield.

TextFlow

I am not a big fan of TextFlow, it seems more complicated for nothing, but I guess that if you want to display columns and more complex text that is the way to go. But has in the case of the TLFTextfield, it seems pretty easy to use RTL languages and TextFlow. So basically in your TextFlow markup you can do something like that <flow:p direction=”rtl”>my persian content</flow:p>. Easy enough, I haven’t tried it, but I have read that it works.

So there you have it, how I finally got it to work properly. Had I known before I would have built my site differently, I was using TextBlock everywhere, so now I check if the language is Hebrew and use TLFTextfield in that case. Also note that working with right to left text using tools that don’t really support it is really hard and confusing, the editor gets confused and selecting text becomes hell as it goes a bit for right then to the left and then right again. Be prepared for some trouble… Anyway I hope this saved some a bit.

, , , , , , , , ,

2 Comments


New Text Layout Framework, same font problems

I guess this has been said before, but I really feel like ranting. I will post a positive article later on about TLF, but for now I need to vent.

So I guess the problem come from the fact that I thought the new Text Layout Framework would solve all problems relating to fonts and Flash. But I guess that was hoping for too much. TLF does have a good side, it does make your text look better. I was skeptic at first, but it really does. The problem is, it has a lot of bad sides.

First problem is that it will add between 100k to 160k to your file size (pretty much forget about it for banners) and that is for every SWF that uses it. I don’t know about you but the sites I build usually contain at least 4 SWFs, so that’s nearly a megabyte just for the text engine, you’re not embedding the fonts yet or adding any content. There are ways to circumvent that but you still have to figure it out and it involves another workflow.

Secondly, there is not much documentation about it. I have been looking and it is pretty hard to figure out what is working or not. Seems like TLF changed since it was introduced, so some information is not relevant anymore. The other thing is that there are multiple ways to use it, you can use TextBlock and TextLine, you can use TLFTextField or you can use TextFlow. It gets pretty confusing at some point, cause you don’t solve the same problems the same ways with each of the three option I named before.

Lastly, it doesn’t work in every situation, I gave the banner example previously, but using the Text Layout Framework is also very expensive CPU wise. For example I was making this combobox which had an opened state with about a hundred items in it. Well it made the site become very slow. I was using TextLines and I had to revert to using good old TextFields. Which introduced a new problem, the font format that you use for TLF is not compatible with the old TextFields, so in this case I had to embed the same font twice, once DF3 and once DF4…

Which brings me to another point, which not necessarily negative, but the TLF does introduce new terminology and knowledge. WTF is DF3 or DF4 or embedCFF. So now your Flash baggage has to be bigger, what about when Molehill comes out, we will have to be interface experts, typography experts and 3D experts???

Well I promise next article will be positive.

, , , , , , , , , ,

2 Comments


Sending byteArray (image) and variables to server-side script as POST data in AS3

A couple things here, I first talked about how to send an image and variables to the server (at the same time) on this post, but it felt a bit weird, the file had no name to retrieve it and the variables were sent as GET. Now while working a with a new colleague, he showed me this code that for him was nothing but for me was amazing. It is a little library called UploadPostHelper made by Jonathan Marston back in 2007 (2007! why didn’t someone talk to me about this library before!!!).

Anyway here is a little code snippet showing how to use it:

var jpegEncoder:JPGEncoder = new JPGEncoder(85); //using the JPGEncoder from as3corelib
var jpegBytes:ByteArray = jpegEncoder.encode(myPicture.bitmapData); //encoding a Bitmap into a ByteArray
 
var urlRequest : URLRequest = new URLRequest();
urlRequest.url = "THE URL OF YOUR SERVER SIDE SCRIPT";
urlRequest.contentType = 'multipart/form-data; boundary=' + UploadPostHelper.getBoundary();
urlRequest.method = URLRequestMethod.POST;
 
//now create an object with the variables you want to send as POST
var postVariables:Object{variable1Name:variable1Data, variable21Name:variable2Data, variable3Name:variable3Data}
urlRequest.data = UploadPostHelper.getPostData( 'image.jpg', jpegBytes,"filedata", postVariables); //here is where the magic happens, filedata will be the name to retrieve the file
urlRequest.requestHeaders.push( new URLRequestHeader( 'Cache-Control', 'no-cache' ) );
 
//from here it is just a normal URLLoader
_pictureUploader = new URLLoader();
_pictureUploader.dataFormat = URLLoaderDataFormat.BINARY;
_pictureUploader.addEventListener( Event.COMPLETE, _onUploadComplete, false, 0, true );
_pictureUploader.load( urlRequest );

How easy and beautiful is that?

So can get the code for the UploadPostHelper at the bottom of this post or I have made a zip file with the .as file here.

Dude, 2007!

, , , , , , , ,

10 Comments


Drawing Bezier tool using Robotlegs

I came back from FITC Toronto with a lot of ideas for new posts and this is the last one of them. But fear not this is a first article in what will probably be a serie of 3 because it would otherwise be too long (or I wouldn’t have the patience to write it). So while at FITC, I went to a presentation be the guys at Firstborn about how they were often making tools instead of doing things by brute force. Well the idea stuck with me.

In the current project that I am working on, there was a part where I needed the coordinates of points along a path. The brute force way was to estimate the next point myself and to compile to see if I was right, repeat until I had all the coordinates I needed. Very tedious and boring task and the path could change often so there was high chances that I would redo this process often. What better time to start making a tool! Well it turn out that my project changed so much that that part wasn’t in it anymore… But it still makes a great topic for this blog.

Let me start by showing you what will be the result of this first post. (Below is not juste whitespace, click in it to ad points. You can select a path to make a control point appear, drag the control point to make a curve).

As you can see this is pretty bare bone. But the good thing about that is that you can use this as the base of multiple tools.

I built this using Robotlegs. If I am going to build something for myself, might as well learn (or train) a few things on the way. Plus, I think Robotlegs is very well suited for application style projects. Now that being said, using that kind of framework (MVC) will require you to create a lot of extra classes but in the end you will understand what you gain by doing so. Out of all these, 4 of them are really important. The Model, where you will keep all information on paths and points at all time and three View classes; one for the clickable area layer, one for the paths layer and one for the point layer.

The easiest of all of them is the clickable are layer. It’s job is just to register clicks and tell the framework where something has been clicked. This could have been done otherwise, but since we will want to layer stuff (points are over paths) plus we will want to select points and path to move or curve them, it is just easier to create a view just to register clicks on the unused stage and put that view in the back off our application.

package com.zedia.drawingtool.view.components {
  import com.zedia.drawingtool.events.PointEvent;
  import com.zedia.drawingtool.model.objects.PointObject;
  import flash.display.Sprite;
  import flash.events.MouseEvent;
 
  /**
    * @author dominicg
  */
  public class DrawingArea extends Sprite {
    public var pointArray:Array;
    private var _pathArray:Array;
    public function DrawingArea() {
      graphics.beginFill(0xffffff);
      graphics.drawRect(0, 0, 550, 400);
      graphics.endFill();
      addEventListener(MouseEvent.MOUSE_DOWN, _onMouseClick, false, 0, true);
    }
    private function _onMouseClick(event : MouseEvent) : void {
      dispatchEvent(new PointEvent(PointEvent.ADD_POINT, new PointObject(event.stageX, event.stageY)));
    }
  }
}

Our second view is the one that handles the points. Points are simple visual objects, they are just circles placed at a x and y coordinate. So when the user clicks on the clickable layer, the point view is notified and a circle is added where the click was registered. Another functionality that is added is that you can drag a point to move it around the stage. One thing to notice is that whenever a point is moved, it tells the framework about it so that the Model is always up to date and so that the path layer can display the paths correctly.

package com.zedia.drawingtool.view.components {
	import com.zedia.drawingtool.events.PointEvent;
	import com.zedia.drawingtool.model.objects.PointObject;
 
	import flash.display.Sprite;
	import flash.events.Event;
 
	/**
	 * @author dominicg
	 */
	public class PointLayer extends Sprite {
		private var _pointVector:Vector.<PathPoint>;
		public function PointLayer() {
			_pointVector = new Vector.<PathPoint>();
		}
		public function addPoint(point:PointObject):void{
			var pathPoint:PathPoint = new PathPoint();
			pathPoint.addEventListener(PointEvent.POINT_MOVED, _onPointMoved, false, 0, true);
			pathPoint.x = point.x;
			pathPoint.y = point.y;
			addChild(pathPoint);
			_pointVector.push(pathPoint);
		}
 
		private function _onPointMoved(event:Event) : void {
			dispatchEvent(new PointEvent(PointEvent.POINT_MOVED, new PointObject(PathPoint(event.target).x, PathPoint(event.target).y, _pointVector.indexOf(PathPoint(event.target)))));
		}
	}
}

Now this is the last of the view class: the PathLayer. It is also the most complicated of the three view classes because a path is a complex object. It is comprised of a start point, an end point and a control point. With those you can draw a curve using the curveTo method from the AS3 drawing API. Here is the code:

package com.zedia.drawingtool.view.components {
	import com.zedia.drawingtool.events.PathEvent;
	import com.zedia.drawingtool.model.objects.PointObject;
	import com.zedia.drawingtool.model.objects.PathObject;
 
	import flash.display.Sprite;
	import flash.events.Event;
 
	/**
	 * @author dominicg
	 */
	public class PathLayer extends Sprite {
		private var _pathVector:Vector.<Path>;
		private var _selected:int = -1;
		public function PathLayer() {
			_pathVector = new Vector.<Path>();
		}
		public function addPath(pathObject:PathObject):void{
			var path:Path = new Path(pathObject.firstPoint, pathObject.secondPoint, pathObject.controlPoint);
			path.addEventListener(PathEvent.PATH_CLICKED, _onPathClicked, false, 0, true);
			path.addEventListener(PathEvent.CONTROL_POINT_MOVED, _onControlPointMoved, false, 0, true);
			addChild(path);
			_pathVector.push(path);	
		}
 
		private function _onControlPointMoved(event : Event) : void {
			dispatchEvent(new PathEvent(PathEvent.CONTROL_POINT_MOVED, new PathObject(new PointObject(0,0,0), new PointObject(0,0,0), _pathVector.indexOf(Path(event.target)), Path(event.target).controlPoint)));
		}
 
		private function _onPathClicked(event : Event) : void {
			if (_selected > -1){
				_pathVector[_selected].deselect();
			}
			_selected = _pathVector.indexOf(Path(event.target));
		}
 
		public function updatePaths(updatedPathVector : Vector.<PathObject>) : void {
			for (var i : int = 0; i < updatedPathVector.length; i++) {
				_pathVector[updatedPathVector[i].id].update(updatedPathVector[i]);
			}
		}
		public function deselectAll():void{
			if (_selected > -1){
				_pathVector[_selected].deselect();
				_selected = -1;
			}
 
		}
	}
}

You will find more information about paths in the Path class inside the view folder.

Finally the last important class is the Model. This is where you keep information about the state of the application. With the information stored in the Model you can recreate exactly how the application is right now, which is really practical if you want to save the state to a file or export data. As you will see, it is mostly saving a data representation of visual objects in our views (points and paths).

package com.zedia.drawingtool.model {
	import com.zedia.drawingtool.events.PathEvent;
	import com.zedia.drawingtool.events.PointEvent;
	import com.zedia.drawingtool.events.PathVectorEvent;
	import com.zedia.drawingtool.model.objects.PathObject;
	import com.zedia.drawingtool.model.objects.PointObject;
 
	import org.robotlegs.mvcs.Actor;
 
	import flash.geom.Point;
 
	/**
	 * @author dominicg
	 */
	public class DrawingModel extends Actor {
		private var _pointVector:Vector.<PointObject>;
		private var _pathVector:Vector.<PathObject>;
		public function DrawingModel() {
			_pointVector = new Vector.<PointObject>();
			_pathVector = new Vector.<PathObject>();
		}
 
		public function addPoint(point:PointObject):void{
			point.id = _pointVector.length;
			_pointVector.push(point);
			dispatch(new PointEvent(PointEvent.ADD_POINT_APPROVED, point));
			var pointLength : int = _pointVector.length;
			if (_pointVector.length > 1) {
				var controlPoint:Point = new Point((_pointVector[pointLength - 1].x - _pointVector[pointLength - 2].x)/2, (_pointVector[pointLength - 1].y- _pointVector[pointLength - 2].y)/2);
				_pathVector.push(new PathObject(_pointVector[pointLength - 2], _pointVector[pointLength - 1], _pathVector.length, controlPoint));
				dispatch(new PathEvent(PathEvent.ADD_PATH_APPROVED, _pathVector[_pathVector.length -1]));
			}
		}
 
		public function updatePoint(point : PointObject) : void {
			trace (point.id);
			_pointVector[point.id].x = point.x;
			_pointVector[point.id].y = point.y;
			//Update paths now
			var resultingPathVector:Vector.<PathObject> = new Vector.<PathObject>();
			if (point.id == 0) {
				_pathVector[point.id].firstPoint = point;
				resultingPathVector.push(_pathVector[point.id]);
			} else if (point.id == _pointVector.length - 1){				
				_pathVector[point.id - 1].secondPoint = point;
				resultingPathVector.push(_pathVector[point.id - 1]);				
			} else {
				_pathVector[point.id].firstPoint = point;
				resultingPathVector.push(_pathVector[point.id]);
 
				_pathVector[point.id - 1].secondPoint = point;
				resultingPathVector.push(_pathVector[point.id - 1]);
			}
			dispatch(new PathVectorEvent(PathVectorEvent.UPDATE_PATHS, resultingPathVector));
		}
 
		public function updateControlPoint(path : PathObject) : void {
			_pathVector[path.id].controlPoint = path.controlPoint;
		}
	}
}

Well that is it for now. You can download the source code below and see the classes that I didn’t talk about. This is all good but this tool right now just draw paths but it doesn’t transform or export the data in any way. This will be the topic of a next post.

ZediaBezierTool

, , ,

1 Comment


Starting out with Alchemy (on a Mac)

So I’m a PC that now works on a Mac. It’s not my choice, but I went along with it to experience the Mac side of things. I don’t hate it, but I don’t like it that much either. That being said, it means that I am a complete noob user. For the past 2 days, I have been trying to make Alchemy work (compiler that let’s you compile C and C++ libraries to a SWC that can be used in Flash) and it wasn’t all that easy.

First I’m going to point you to two articles on how to setup Alchemy. The first one can be found on Adobe Labs and has a detailed list of steps to complete in order to make Alchemy works. The second one is from zaalabs and it gives further information to get it done.

Now, even with those articles I had a lot of trouble to get it to work, mostly because I don’t know a lot about command line stuff. The first thing that confused me was the mention of a bash / shell / terminal interchangeably. Now, I know there is a difference between all of those, but in this case they all mean the terminal. You can access the terminal by going to Applications and inside the Utilities folder you’ll find the terminal.

The second thing that I didn’t understand was how to add something to the system path. This is also referred later on as adding to your paths. This means editing a file that will put a certain path to be handled like a system path so that you can access whatever is in that folder from any directory. To do so you have to edit a certain file named .profile. The problem that I had was that looking around the interweb for adding to the system path I found that I had to edit a file named .bash_profile. Well it turns out that both works but you just need one of those, if you put some info in one and some info in the other, just one of the file is going to be used so it won’t work. Just use .profile as mentioned in Adobe doc. Now that file is a hidden file (it starts with a “.”) and to see if it exist, in terminal, you must, right after you open it, write “ls -a”, the -a option will show you file that starts with a “.”. If the file .profile doesn’t exist you can create it using an editor like pico by writing “pico .profile”, writing what you need in it and saving the file. Just to help out, here is what my .profile file looks like after I have completed all the steps:

source /Users/dominicg/library/Alchemy/alchemy-setup
PATH=$PATH:/Users/dominicg/Flex3/bin:/Users/dominicg/library/Alchemy/achacks
export PATH

Last note to be sure everything works, you need to use the Flex SDK 3.2 and no other version. That particular SDK can be found here.

Well I hope this will help some of you. I pretty much shifted focus from Alchemy since I started writing this article, but I am sure I will get back to it at some point.

, , , , , ,

1 Comment


Create your own ColorPicker using a Bitmap

A while ago I did an application that required a colorpicker, I didn’t know much at the time so I chose to use the ColorPicker component that came with Flash CS3. That component is ok but it kinda is limited. After a little while I wanted more than what it was providing me.  I wanted to imitate a bit the colorpicker that you can find in Photoshop. It turns out that it is pretty easy to do so. All you need is a picture of a color gamut and you are all set.

ColorPicker component in Flash CS3

What we are going to do in short is transform this image of a color spectrum (bitmap) into a Sprite and when the mouse is over that Sprite, get the color that is right under the mouse. For the image of the color spectrum i’ll use a picture I found on wikipedia and just resize it a bit. All you need is a picture with enough color on it, you could also use a picture of your dog if you wanted but the goal is more a picture with some organisation in the color.

Here is the picture I used:

Color Spectrum for a ColorPicker

Now all you need to do is add a little bit of code to it and you have the basis of a color picker. The method that will do most of the work for us is a method from BitmapData called getPixel. You basically tell that method which pixel in the Bitmap, by providing it’s x and y coordinates, and getPixel will return you the color of that pixel. Now, this method returns the color as a unsigned integer that is not so legible, so we will have to convert that to an hexadecimal base so that we can relate to it.

But to be able to use this method (getPixel) we will need a BitmapData of the spectrum. In Flash, you can turn most MoviClip into BitmapData by using the method draw. I’ll do it in the following code snippet.

Here we go:

//Add the mouse funcitonality to the color picker
myColorPicker.addEventListener(MouseEvent.ROLL_OVER, onRollOver, false, 0, true);
myColorPicker.addEventListener(MouseEvent.ROLL_OUT, onRollOut, false, 0, true);
 
var myBitmapData:BitmapData = new BitmapData(myColorPicker.width, myColorPicker.height);
myBitmapData.draw(myColorPicker);
 
function onRollOver(event:MouseEvent):void{
	myColorPicker.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove, false, 0, true);
}
function onRollOut(event:MouseEvent):void{
	myColorPicker.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
}
 
function onMouseMove(event:MouseEvent):void{
	var myColor:uint = myBitmapData.getPixel(myColorPicker.mouseX, myColorPicker.mouseY);
	trace (myColor.toString(16)); //The toString(16) convert the uint into a legible hexadecimal representation ike in Photoshop
}
Now you have it, this is just the basis, but with that you can build a full fledged color picker.

, ,

5 Comments