Author Archive
Hi,
I wrote 2 quick scripts for After Effects to export properties to XML. I thought it might be handy for some of you.
I mainly wrote them to export motion trackers to use in Flash afterwards, but you should be able to export other properties.
To use them, do the following:
1. In the menu: Preferences > General > and tick “Allow scripts to write files and access network”
2. open a project
3. select the properties you want to export (for example the 4 points “Feature Center” of motion trackers)
4. In the menu: File > Scripts > Run script file…
5. select one the following scripts
A file “export.txt” should have been created on your desktop (and opened), with the XML content inside.
You should be able to export other properties, such as Transform properties like “position”, and so on.
It is certainly not bug free, but it should get you started.
Export by properties
Export by time
Hope that helps!
2 Comments »
As requested, I Just made a quick demo how to implement the SomaAssets plugin in your application.
See the demo.
Download the demo.
View source.
Demo on github.
I'll make a quick descrition here. I'll be using the following XML config:
XML:
-
<?xml version="1.0" encoding="UTF-8"?>
-
<loader connection="1">
-
<asset id="image0" src="assets/img/image0.jpg" smoothing="true" transparent="true"/>
-
<asset id="image1" src="assets/img/image1.jpg" smoothing="true" transparent="true"/>
-
<group id="group0">
-
<group id="group00">
-
<asset id="image2" src="assets/img/image2.jpg" smoothing="true" transparent="true"/>
-
<asset id="image3" src="assets/img/image3.jpg" smoothing="true" transparent="true"/>
-
</group>
-
<group id="group01">
-
<asset id="css" src="assets/css/stylesheet.css" preventCache="true" weight="352"/>
-
<asset id="json" src="assets/json/data.json" preventCache="true" weight="582"/>
-
<asset id="sound" src="assets/sounds/sample.mp3" preventCache="true" weight="16718"/>
-
<asset id="text" src="assets/text/text.txt" preventCache="true" weight="574"/>
-
<asset id="xml" src="assets/xml/sample.xml" preventCache="true" weight="79"/>
-
<asset id="video" src="assets/video/sample.flv" weight="1550580"/>
-
<asset id="zip" src="assets/zip/file.zip" weight="3493"/>
-
</group>
-
</group>
-
</loader>
First step, I create a SomaCore application.
Actionscript:
-
public function Main() {
-
_app = new SomaApplication(this);
-
}
In the application facade, I create a command from a SomaAssets just to demo how to monitor the assets loading at a framework level. I also register 3 views and 3 mediators to show how to get the assets at different moments. I create the plugin SomaAssets and I finally create a simple wire class "InitializeWire" to handle some global events (config loaded, assets loaded, etc).
Actionscript:
-
package com.soma.plugins.assets.demo {
-
-
import com.soma.plugins.assets.demo.commands.ExampleAssetCommand;
-
import com.soma.plugins.assets.events.SomaAssetsEvent;
-
import com.soma.core.Soma;
-
import com.soma.core.di.SomaInjector;
-
import com.soma.core.interfaces.ISoma;
-
import com.soma.plugins.assets.SomaAssets;
-
import com.soma.plugins.assets.demo.views.ImageGroup;
-
import com.soma.plugins.assets.demo.views.ImageGroupMediator;
-
import com.soma.plugins.assets.demo.views.ImageWhenAllLoaded;
-
import com.soma.plugins.assets.demo.views.ImageWhenAllLoadedMediator;
-
import com.soma.plugins.assets.demo.views.ImageWhenNotLoaded;
-
import com.soma.plugins.assets.demo.views.ImageWhenNotLoadedMediator;
-
import com.soma.plugins.assets.demo.wires.InitializeWire;
-
import com.soma.plugins.assets.vo.SomaAssetsVO;
-
-
/**
-
* @author Romuald Quantin
-
*/
-
public class SomaApplication extends Soma implements ISoma {
-
-
private var _container:Main;
-
-
public function SomaApplication(container:Main) {
-
_container = container;
-
super(_container.stage, SomaInjector);
-
}
-
-
// create a command for a demo purpose to monitor the assets that are loaded
-
override protected function registerCommands():void {
-
addCommand(SomaAssetsEvent.ASSET_LOADED, ExampleAssetCommand);
-
}
-
-
// register mediators to views
-
// the views won't be created at the same moment to show how you can handle your loading
-
override protected function registerViews():void {
-
mediators.mapView(ImageWhenAllLoaded, ImageWhenAllLoadedMediator);
-
mediators.mapView(ImageWhenNotLoaded, ImageWhenNotLoadedMediator);
-
mediators.mapView(ImageGroup, ImageGroupMediator);
-
}
-
-
// create the plugin and register an external assets configuration to load
-
override protected function registerPlugins():void {
-
createPlugin(SomaAssets, new SomaAssetsVO(this, "xml/assets.xml"));
-
}
-
-
// create an wire where you could handle the "global" loading process
-
override protected function start():void {
-
injector.createInstance(InitializeWire);
-
}
-
-
// just the document class to add some views to
-
public function get container():Main {
-
return _container;
-
}
-
-
}
-
}
In the InitializeWire class, I add some event listeners to handle errors, when the XML config is loaded and when the assets are all loaded. I used it mostly to create views and mediators at different moments of the loading process to show you how to handle you loaders, events and assets.
Actionscript:
-
package com.soma.plugins.assets.demo.wires {
-
-
import com.soma.plugins.assets.demo.views.ImageGroup;
-
import com.soma.core.interfaces.IWire;
-
import com.soma.core.wire.Wire;
-
import com.soma.plugins.assets.demo.SomaApplication;
-
import com.soma.plugins.assets.demo.views.ImageWhenAllLoaded;
-
import com.soma.plugins.assets.demo.views.ImageWhenNotLoaded;
-
import com.soma.plugins.assets.events.SomaAssetsEvent;
-
import flash.display.DisplayObjectContainer;
-
import org.assetloader.core.IAssetLoader;
-
-
/**
-
* @author Romuald Quantin
-
*/
-
public class InitializeWire extends Wire implements IWire {
-
-
[Inject(name="assets")]
-
public var loader:IAssetLoader;
-
-
// register some SomaAssets events for monitoring
-
override public function initialize():void {
-
addEventListener(SomaAssetsEvent.CONFIG_LOADED, configLoaded);
-
addEventListener(SomaAssetsEvent.LOADER_COMPLETE, assetsComplete);
-
addEventListener(SomaAssetsEvent.ERROR, assetsErrorHandler);
-
}
-
-
// shortcut to get the document class
-
private function get container ()  isplayObjectContainer {
-
return SomaApplication(instance).container;
-
}
-
-
// in case there's an error for both the assets config or the assets
-
private function assetsErrorHandler(event:SomaAssetsEvent):void {
-
trace("Asset Error:", event.errorMessage, event.errorType);
-
}
-
-
// the external XML assets config has been loaded here
-
private function configLoaded(event:SomaAssetsEvent):void {
-
container.addChild(new ImageWhenNotLoaded());
-
container.addChild(new ImageGroup());
-
trace("config loaded");
-
loader.start();
-
}
-
-
// all assets container in the config XML have been loaded here
-
private function assetsComplete(event:SomaAssetsEvent):void {
-
container.addChild(new ImageWhenAllLoaded());
-
}
-
-
}
-
}
In the ImageWhenAllLoadedMediator mediator, I inject directly an asset (Bitmap) as everything is loaded when the mediator gets created.
Actionscript:
-
package com.soma.plugins.assets.demo.views {
-
-
import com.soma.core.interfaces.IMediator;
-
import com.soma.core.mediator.Mediator;
-
-
import flash.display.Bitmap;
-
-
/**
-
* @author Romuald Quantin
-
*/
-
public class ImageWhenAllLoadedMediator extends Mediator implements IMediator {
-
-
[Inject]
-
public var view:ImageWhenAllLoaded;
-
-
// all the assets are loaded at this point
-
// we can inject the asset (or loaders)
-
[Inject(name="image0")]
-
public var image:Bitmap;
-
-
override public function initialize():void {
-
image.scaleX = image.scaleY = 0.1;
-
image.x = 130;
-
view.addChild(image);
-
}
-
-
override public function dispose():void {
-
while (view.numChildren> 0) view.removeChildAt(0);
-
view = null;
-
image = null;
-
}
-
-
}
-
}
The ImageWhenNotLoadedMediator mediator gets created when the XML config has been loaded. The assets are not loaded yet and I show how to retrieve the loader of a specific asset to monitor when it starts, the loading progress and when it has been completed.
Actionscript:
-
package com.soma.plugins.assets.demo.views {
-
-
import flash.display.Bitmap;
-
import com.soma.core.interfaces.IMediator;
-
import com.soma.core.mediator.Mediator;
-
-
import org.assetloader.core.ILoader;
-
import org.assetloader.events.AssetLoaderErrorEvent;
-
import org.assetloader.events.AssetLoaderEvent;
-
import org.assetloader.events.AssetLoaderProgressEvent;
-
-
/**
-
* @author Romuald Quantin
-
*/
-
public class ImageWhenNotLoadedMediator extends Mediator implements IMediator {
-
-
[Inject]
-
public var view:ImageWhenNotLoaded;
-
-
// here we get the loader of an asset for monitoring purpose
-
// this one is an ImageLoader but we keep the interface as a type
-
[Inject(name="image1")]
-
public var imageLoader:ILoader;
-
-
// add some listeners to monitor the loading of a single loader
-
override public function initialize():void {
-
imageLoader.addEventListener(AssetLoaderErrorEvent.ERROR, errorHandler);
-
imageLoader.addEventListener(AssetLoaderEvent.START, startHandler);
-
imageLoader.addEventListener(AssetLoaderProgressEvent.PROGRESS, progressHandler);
-
imageLoader.addEventListener(AssetLoaderEvent.COMPLETE, completeHandler);
-
}
-
-
private function errorHandler(event:AssetLoaderErrorEvent):void {
-
trace("Error", event.errorType, event.message);
-
}
-
-
private function startHandler(event:AssetLoaderEvent):void {
-
trace("Loading started (" + ILoader(event.currentTarget).id + ")");
-
}
-
-
private function progressHandler(event:AssetLoaderProgressEvent):void {
-
trace("Loading progress (" + ILoader(event.currentTarget).id + ") progress:", event.progress, ", speed:", event.speed);
-
}
-
-
// the loader is complete, the asset is ready
-
private function completeHandler(event:AssetLoaderEvent):void {
-
trace("Loading completed (" + ILoader(event.currentTarget).id + ")");
-
var image:Bitmap = event.data;
-
image.scaleX = image.scaleY = 0.1;
-
view.addChild(image);
-
}
-
-
override public function dispose():void {
-
while (view.numChildren> 0) view.removeChildAt(0);
-
view = null;
-
imageLoader = null;
-
}
-
-
}
-
}
The ImageGroupMediator mediator does the same job as the mediator above but applied to an IAssetLoader (loader containing others loaders). The way to monitor the loading process is exactly the same. I also show different ways to retrieve the assets of this group, once the groupe has been loaded. You will notice the special injection name of the loader, it is a path generated from the XML config using the group and assets ids and a delimiter.
Actionscript:
-
package com.soma.plugins.assets.demo.views {
-
-
import flash.display.Bitmap;
-
import com.soma.plugins.assets.SomaAssets;
-
import com.soma.core.interfaces.IMediator;
-
import com.soma.core.mediator.Mediator;
-
import org.assetloader.core.IAssetLoader;
-
import org.assetloader.core.ILoader;
-
import org.assetloader.events.AssetLoaderErrorEvent;
-
import org.assetloader.events.AssetLoaderEvent;
-
import org.assetloader.events.AssetLoaderProgressEvent;
-
import flash.utils.Dictionary;
-
-
/**
-
* @author Romuald Quantin
-
*/
-
public class ImageGroupMediator extends Mediator implements IMediator {
-
-
[Inject]
-
public var view:ImageGroup;
-
-
// here we get the plugin
-
[Inject(name="assets")]
-
public var assets:SomaAssets;
-
-
// here we get a group using a path (ids + delimiter)
-
[Inject(name="group0/group00")]
-
public var imageGroup:IAssetLoader;
-
-
// add some listeners to monitor the loading of a single group
-
override public function initialize():void {
-
imageGroup.addEventListener(AssetLoaderErrorEvent.ERROR, errorHandler);
-
imageGroup.addEventListener(AssetLoaderEvent.START, startHandler);
-
imageGroup.addEventListener(AssetLoaderProgressEvent.PROGRESS, progressHandler);
-
imageGroup.addEventListener(AssetLoaderEvent.COMPLETE, completeHandler);
-
}
-
-
private function errorHandler(event:AssetLoaderErrorEvent):void {
-
trace("Error", event.errorType, event.message);
-
}
-
-
private function startHandler(event:AssetLoaderEvent):void {
-
trace("Loading started (" + ILoader(event.currentTarget).id + ")");
-
}
-
-
private function progressHandler(event:AssetLoaderProgressEvent):void {
-
trace("Loading progress (" + ILoader(event.currentTarget).id + ") progress:", event.progress, ", speed:", event.speed);
-
}
-
-
// now the group is loaded, get the 2 images from the group
-
private function completeHandler(event:AssetLoaderEvent):void {
-
trace("Loading completed (" + ILoader(event.currentTarget).id + ")");
-
var images:Dictionary = event.data;
-
trace("asset from dictionary", images["image3"]);
-
trace("asset from loader:", imageGroup.getAsset("image3"));
-
trace("asset from plugin:", assets.getAssets("group0/group00/image3"));
-
var image2:Bitmap = images["image2"];
-
var image3:Bitmap = images["image3"];
-
image2.x = 290;
-
image2.scaleX = image2.scaleY = 0.1;
-
image3.x = 340;
-
image3.scaleX = image3.scaleY = 0.1;
-
view.addChild(image2);
-
view.addChild(image3);
-
}
-
-
override public function dispose():void {
-
while (view.numChildren> 0) view.removeChildAt(0);
-
view = null;
-
imageGroup = null;
-
}
-
-
}
-
}
The ExampleAssetCommand command is just a demo to show that you can use the SomaAssetsEvent class to directly create commands from it. In this example I used the type SomaAssetsEvent.ASSET_LOADED. The command will get created every time an asset is loaded.
Actionscript:
-
package com.soma.plugins.assets.demo.commands {
-
-
import com.soma.core.controller.Command;
-
import com.soma.core.interfaces.ICommand;
-
import com.soma.plugins.assets.SomaAssets;
-
import com.soma.plugins.assets.demo.SomaApplication;
-
import com.soma.plugins.assets.events.SomaAssetsEvent;
-
-
import flash.display.DisplayObjectContainer;
-
import flash.events.Event;
-
import flash.media.Sound;
-
import flash.media.Video;
-
import flash.net.NetStream;
-
import flash.text.TextField;
-
import flash.utils.getQualifiedClassName;
-
-
/**
-
* @author Romuald Quantin
-
*/
-
public class ExampleAssetCommand extends Command implements ICommand {
-
-
[Inject]
-
public var evt:SomaAssetsEvent;
-
-
[Inject(name="assets")]
-
public var assets:SomaAssets;
-
-
// just some examples
-
public function execute(event:Event):void {
-
var container:DisplayObjectContainer = SomaApplication(instance).container;
-
trace("Command Example (" + evt.path + ")> " + assets.getLoader(evt.path).type + " Loaded: " + getQualifiedClassName(evt.asset));
-
// you can use a switch to find the assets:
-
switch (evt.path) {
-
case "group0/group01/css":
-
break;
-
case "group0/group01/json":
-
break;
-
case "group0/group01/sound":
-
var sound:Sound = evt.asset;
-
sound.play(0);
-
break;
-
case "group0/group01/text":
-
var textfield:TextField = new TextField();
-
textfield.multiline = textfield.wordWrap = true;
-
textfield.text = evt.asset;
-
container.addChild(textfield);
-
break;
-
case "group0/group01/xml":
-
break;
-
case "group0/group01/video":
-
var video:Video = new Video();
-
var stream:NetStream = evt.asset;
-
container.addChild(video);
-
video.y = 80;
-
video.smoothing = true;
-
video.attachNetStream(stream);
-
stream.resume();
-
break;
-
case "group0/group01/zip":
-
break;
-
}
-
}
-
-
}
-
}
This implementation is just an example as it could be handled in very different ways, but that should get you started.
No Comments »
Two new releases today, an asset loader and the SomaCore plugin: SomaAssets.
The AssetLoader library is a port from Matan's AssetLoader library to be event-based, it makes you able to load and manage multiple assets (image, video, xml, sound, etc) in your application.
SomaAssets is a plugin based on the AssetLoader library to easily access to your assets and effectively integrate them in your SomaCore application with paths and automatic mapping name generation for injection.
Special thanks to Matan for his help with the AssetLoader and his joy in general, a pleasure to "meet" him.
You can read the SomaAssets wiki section to get started with it, but I'll post below a few hints of what you can easily do with it within a SomaCore application.
AssetLoader source
AssetLoader wiki
SomaAssets source
SomaAssets wiki
Easily create the plugin and add a XML config file for the assets.
Actionscript:
-
createPlugin(SomaAssets, new SomaAssetsVO(this, "xml/assets_config.xml"))
Easily retrieve the assets with paths through the XML config.
Actionscript:
-
var image:Bitmap = assets.getAssets("group0/group00/img0");
Easily retrieve the plugin, main loader, config and assets with injection in a SomaCore application. The following mapping names have been automatically generated from the XML config.
Actionscript:
-
[Inject(name="assets")]
-
public var plugin:SomaAssets;
-
-
[Inject(name="assets")]
-
public var loader:IAssetLoader;
-
-
[Inject(name="group0/group00/img0")]
-
public var loaderType1:ImageLoader;
-
-
[Inject(name="group0/group00/img0")]
-
public var assetType1:Bitmap;
3 Comments »
BinderUI is a debugging tools to help you create interfaces and debug values.
Very often I’m sure you spend time building visual interfaces to set, to see and to debug some values.
This can be useful for example to show to the creative (or even the client?) and extract the right values instead of tweaking thing for ages, I’m sure you know what I mean.
That can be time consuming and is often very annoying so I wanted to ease the process (1 line of code and a metadata tag).
BinderUI is a simple static class and the idea is to “bind” a value to visual components such as slider, knob, meter, text input, and so on. For the components I used the library minimalComps.
That means that the bound values will update the components in real-time and the components will update the values (two-ways). I used the BindingUtils and ChangeWatcher classes from the mx package but as it will be for debugging, you can use it on project that will be pure AS3 as well.

Click here to see the demo.
As a quick example, imagine you have a custom darkness property on your custom class, you can bind the value this way:
Actionscript:
-
BinderUI.displaySliderHorizontal(this, _mySprite, "darkness", "darkness", null, 0.1, 1, -255, 255);
This will create a slider that will update (and be updated) for your darkness property.
You’ll also need to add a Bindable metadata in your class:
Actionscript:
-
[Bindable]
-
public class MySprite extends Sprite {
Note: in case you want to debug built-in flash properties (such as x and y), you’ll need to override the properties in your custom class even if it does nothing.
Actionscript:
-
override public function get x():Number {
-
return super.x;
-
}
-
override public function set x(value:Number):void {
-
super.x = value;
-
}
For now you can debug only properties (getters and setters), and types that are String, Number, Boolean (and color).
Here is a list of component that can be used.
Actionscript:
-
BinderUI.displayLabel(this, s, "x")
-
BinderUI.displayColorChooser(this, sprite, "color", 0xFFFF00);
-
BinderUI.displayCheckBox(this, sprite, "halfTransparent", "half transparent");
-
BinderUI.displayIndicatorLight(this, sprite, "halfTransparent", "half transparent");
-
BinderUII.displayNumericStepper(this, sprite, "x", 5, null, 0, 900, 1);
-
BinderUI.displayInput(this, sprite, "x");
-
BinderUI.displaySliderHorizontal(this, sprite, "x", "x", null, 0.1, 1, 0, 900);
-
BinderUI.displaySliderVertical(this, sprite, "x", "x", null, 0.1, 1, 0, 900);
-
BinderUI.displayTextarea(this, sprite, "x");
-
BinderUI.displayKnob(this, sprite, "x", "x", null, Knob.VERTICAL, 20, 0, 900);
-
BinderUI.displayMeter(this, sprite, "x", "x", null, 0, 900);
In some case, it is harder to bind values, such as when you want to update a component from what you type in a textfield. You’ll need to dispatch an event yourself (usually these events are added by the compiler with the Bindable metadata tag).
Actionscript:
-
dispatchEvent(new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE, false, false, PropertyChangeEventKind.UPDATE, 'text', oldValue, newValue, this));
About colors, you can use the displayColorChooser method. The easiest is using a “color” property for example.
Actionscript:
-
BinderUI.displayColorChooser(this, mySprite, "color");
You can also use the colorTransform property but this property is not bindable, so it will work only in one way (component —> target):
Actionscript:
-
BinderUI.displayColorChooser(this, mySprite.transform, "color");
You can also use the MinimalConfigurator to create your interface from an XML file.
Three methods are available to dispose (remove and destroy) components. You can dispose by target, by component or dispose everything.
Actionscript:
-
BinderUI.disposeByTarget(mySprite);
-
BinderUI.disposeByComponent(myComponent)
-
BinderUI.dispose();
Download source and demos.
Source on github.
No Comments »
Posted by: Romuald in talking
I needed some knobs for a debug interface. I share this very simple class to use so you don't have to rebuild it from scratch, it should be pretty flexible.

Click here to see the demo.
Download source.
The knob can be used as circle or ellipse, here is how to create one:
Actionscript:
-
var knob:Knob = new Knob();
-
knob.addEventListener(Event.CHANGE, changeHandler);
-
addChild(knob);
-
-
function changeHandler(event:Event):void {
-
var knob:Knob = event.currentTarget as Knob;
-
trace(knob.value);
-
trace(knob.valuePercent);
-
}
Set the radius, a custom handler and a custom graphic:
Actionscript:
-
var customHandler:Sprite = new Sprite();
-
customHandler.graphics.beginFill(0xFF0000);
-
customHandler.graphics.drawRect(-10, -10, 20, 20);
-
customHandler.graphics.endFill();
-
var knob:Knob = = new Knob(100, 50, customHandler);
-
knob.stylePathColor = 0x00FF00;
-
knob.stylePathThickness = 3;
-
knob.stylePathAlpha = 0.3;
That's pretty much it, here is the class:
Actionscript:
-
package {
-
-
import flash.display.DisplayObject;
-
import flash.display.Sprite;
-
import flash.events.Event;
-
import flash.events.MouseEvent;
-
-
/**
-
* @author Romuald Quantin
-
*/
-
public class Knob extends Sprite {
-
-
private var _radiusX:Number;
-
private var _radiusY:Number;
-
private var _handler:DisplayObject;
-
private var _sector:Sector;
-
-
private var _stylePathColor:uint = 0xCCCCCC;
-
private var _stylePathAlpha:Number = 1;
-
private var _stylePathThickness:Number = 0;
-
-
public function Knob(radiusX:Number = 100, radiusY:Number = 100, handler:DisplayObject = null) {
-
setRadius(radiusX, radiusY);
-
setHandler(handler);
-
updatePositionFromDegree(-90);
-
}
-
-
private function setRadius(radiusX:Number, radiusY:Number):void {
-
_radiusX = radiusX;
-
_radiusY = radiusY;
-
if (!_sector) _sector = new Sector(0, _radiusX, _radiusY);
-
draw();
-
updatePosition();
-
}
-
-
private function setHandler(value:DisplayObject):void {
-
disposeDragabble();
-
_handler = (!value) ? createNewHandler() : value;
-
setHandlerListeners();
-
addChild(_handler);
-
updatePosition();
-
}
-
-
private function setHandlerListeners():void {
-
_handler.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
-
}
-
-
private function removeHandlerListeners():void {
-
_handler.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
-
stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
-
stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
-
stage.removeEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler);
-
}
-
-
private function mouseLeaveHandler(event:Event):void {
-
stopDragging();
-
}
-
-
private function mouseDownHandler(event:MouseEvent):void {
-
startDragging();
-
}
-
-
private function mouseUpHandler(event:MouseEvent):void {
-
stopDragging();
-
}
-
-
private function startDragging():void {
-
stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
-
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
-
stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
-
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
-
stage.removeEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler);
-
stage.addEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler);
-
}
-
-
private function stopDragging():void {
-
stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
-
stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
-
stage.removeEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler);
-
}
-
-
private function mouseMoveHandler(event:MouseEvent):void {
-
updatePosition();
-
}
-
-
private function updatePosition():void {
-
var ratio:Number = _radiusX / _radiusY;
-
var angle:Number = Math.atan2(mouseX, mouseY);
-
updatePositionFromDegree(90 - (Math.atan2(Math.sin(angle), Math.cos(angle) * ratio)) * (180 / Math.PI));
-
dispatchEvent(new Event(Event.CHANGE));
-
}
-
-
private function updatePositionFromDegree(value:Number):void {
-
_sector.degree = value;
-
_sector.radiusX = _radiusX;
-
_sector.radiusY = _radiusY;
-
if (_handler) {
-
_handler.x = _sector.x;
-
_handler.y = _sector.y;
-
}
-
}
-
-
private function createNewHandler() : DisplayObject {
-
var circle:Sprite = new Sprite();
-
circle.graphics.beginFill(0x434F6C);
-
circle.graphics.drawCircle(0, 0, 5);
-
return circle;
-
}
-
-
private function draw():void {
-
graphics.clear();
-
graphics.lineStyle(_stylePathThickness, _stylePathColor, _stylePathAlpha);
-
graphics.moveTo(_sector.x, _sector.y);
-
var i:Number = 0;
-
var l:Number = 360;
-
for (; i <= l; ++i) {
-
_sector.degree = i;
-
_sector.radiusX = _radiusX;
-
_sector.radiusY = _radiusY;
-
graphics.lineTo(_sector.x, _sector.y);
-
}
-
graphics.endFill();
-
}
-
-
public function get radiusX():Number {
-
return _radiusX;
-
}
-
-
public function set radiusX(value:Number):void {
-
setRadius(value, _radiusY);
-
}
-
-
public function get radiusY():Number {
-
return _radiusY;
-
}
-
-
public function set radiusY(value:Number):void {
-
setRadius(_radiusX, value);
-
}
-
-
public function get handler() : DisplayObject {
-
return _handler;
-
}
-
-
public function set handler(value:DisplayObject):void {
-
setHandler(value);
-
}
-
-
public function get value():Number {
-
return _sector.degree + 90;
-
}
-
-
public function set value(value:Number):void {
-
updatePositionFromDegree(value - 90);
-
}
-
-
public function get valuePercent():Number {
-
return value / 360;
-
}
-
-
public function set valuePercent(value:Number):void {
-
this.value = 360 * Math.min(1, Math.max(0, value));
-
}
-
-
public function disposeDragabble():void {
-
if (!_handler) return;
-
removeHandlerListeners();
-
if (_handler.hasOwnProperty("dispose")) {
-
_handler['dispose']();
-
}
-
removeChild(_handler);
-
_handler = null;
-
}
-
-
public function dispose():void {
-
disposeDragabble();
-
_sector = null;
-
}
-
-
public function get stylePathColor():uint {
-
return _stylePathColor;
-
}
-
-
public function set stylePathColor(value:uint):void {
-
_stylePathColor = value;
-
draw();
-
}
-
-
public function get stylePathAlpha():Number {
-
return _stylePathAlpha;
-
}
-
-
public function set stylePathAlpha(value:Number):void {
-
_stylePathAlpha = value;
-
draw();
-
}
-
-
public function get stylePathThickness():Number {
-
return _stylePathThickness;
-
}
-
-
public function set stylePathThickness(value:Number):void {
-
_stylePathThickness = value;
-
draw();
-
}
-
}
-
}
-
-
class Sector {
-
-
public var degree:Number;
-
public var radiusX:Number;
-
public var radiusY:Number;
-
-
public function Sector(degree:Number = 0, radiusX:Number = 10, radiusY:Number = 10) {
-
this.degree = degree;
-
this.radiusX = radiusX;
-
this.radiusY = radiusY;
-
}
-
-
public function get x():Number {
-
return radiusX * Math.cos(degree * Math.PI / 180);
-
}
-
-
public function get y():Number {
-
return radiusY * Math.sin(degree * Math.PI / 180);
-
}
-
-
public function toString():String {
-
return "[Sector] degree: " + degree + ", radiusX: " + radiusX + ", radiusY: " + radiusY + ", x: " + x + ", y: " + y;
-
}
-
}
1 Comment »
|