Shared Object – utilizing the Flash cookie

Overview

The Shared Object is like a cookie for flash. It lets flash store some data on the local machine, so between sessions it can remember things. Learn more from wikipedia.
Shared Objects are used to store data on the client machine in much the same way that data is stored in a cookie created through a web browser. The data can only be read by movies originating from the same domain that created the Shared Object. This is the only way Macromedia Flash Player can write data to a user’s machine. Shared Objects can not remember a user’s e-mail address or other personal information unless they willingly provide such information.

I’ve seen many Local Shared Object tutorials and examples, which have users input their name and/or hometown and other filler data. But I wanted to show how to creatively incorporate shared objects into interactions. So I’ve thrown in many simultaneous examples including the uber-simple ‘input your name and I’ll remember it’ approach. I hope I didn’t throw in so much that it got confusing… just let me know if you have any questions or anything is unclear. Keeping it simply and broad there’s only a few things to know about Shared Objects.

Steps

    Simply put there are only a couple things to worry about with Local Shared Objects

  • Create them.
    • As in create the shared object
  • Write them.
    • As is write to the shared object
  • Set them.
    • As in setting variables in the shared object
  • Get them.
    • As in getting variables back out of the shared object
  • Clear them.
    • As in clearing the shared objec

Actionscript

here’s samples on how to do each of those
[cc lang=”actionscript” tab_size=”2″ lines=”40″]
/* Create them. */
//make Local Shared Object named myLocalSO(in as) called “myflashcookie” on disk
var myLocalSO:SharedObject = SharedObject.getLocal(“myflashcookie”);

/* Write them. */
//flush the SO, write the SO to disk
myLocalSO.flush();

/* Set them. */
//set key’s value to specified value in SO
//key is the name of the data
//val is key’s value
function setVal(key, val) {
myLocalSO.data[key] = val;
trace(key +” set to “+val);
/* including writing to Shared Object in the setter function */
//flush the SO, write the SO to disk
myLocalSO.flush();
}
/* Get them. */
//get key’s value from SO
function getVal(key) {
return myLocalSO.data[key];
trace(myLocalSO.data[key] +” received from “+key);
}
/* Clear them. */
myLocalSO.clear();
[/cc]

Example

here’s my colorful example.
The purple/yellow circle is draggable, so place it where you want it. Enter your name and age in the input boxes. Press the center red ‘Set cookie’ button to copy those values to the shared object that is on your computer now. The red transparent circle represents the cookie positions. You can position the purple/yellow circle from the cookie contents with the dark green ‘Position from cookie’ button, or position it randomly with the blue ‘Position randomly’ button. Erase the cookie with the orange ‘Erase cookie’ button. Toggle easing (animation) with the Bright green button (which changes to dark red when off), it tells the current mode of ease. I have the cookie coordinates displayed and the current coordinates of the purple/yellow circle also displayed.
The cookie includes a date object, which is used to calculate the age of the cookie (watch it reset when you erase the cookie (orange button)).
The ‘All Time Visit’ stat is the only thing that does not get reset when you erase the cookie,
[kml_flashembed fversion=”9.0.0″ movie=”https://circlecube.com/circlecube/wp-content/uploads/sites/10/2008/04/sharedObject.swf” targetclass=”flashmovie” publishmethod=”dynamic” width=”300″ height=”400″]

Get Adobe Flash player

[/kml_flashembed]

and source code:
[cc lang=”actionscript” tab_size=”2″ lines=”40″]
//////////////////////// Initialize variables ///////////////////////

//make Local Shared Object named myLocalSO(in as) called “myflashcookie” on disk
var myLocalSO:SharedObject = SharedObject.getLocal(“myflashcookie”);
//speed var for easing
var speed = 3;
var w = myCircle._width/2;
//toggle var for easing
var ease = true;
//as var to store alltime cookie
var allTimeVisitCount=0;
countVisit();
cookieFeedback();
//line style for tracing movement
lineStyle(1, 0, 50);

//////////////////////// Functions ///////////////////////

//set key’s value to specified value in SO
//key is the name of the data
//val is key’s value
function setVal(key, val) {
myLocalSO.data[key] = val;
trace(key +” set to “+val);
//flush the SO, write the SO to disk
myLocalSO.flush();
}
//get key’s value from SO
function getVal(key) {
return myLocalSO.data[key];
trace(myLocalSO.data[key] +” received from “+key);
}

function countVisit() {
//if first visit
if (getVal(‘visitCount’) == undefined) {
//create date for now and store in cookie
var todayDate:Date = new Date();
setVal(‘date’, todayDate);
trace(“creating date”);
//start/reset counting visits
var visitCount = 0;
//notice allTimeVisitCount is not reset, but stored still as a var in actionscript
}

//not first visit
else {
visitCount = getVal(‘visitCount’);
allTimeVisitCount = getVal(‘allTimeVisitCount’);
}
//increment visit counter
setVal(‘visitCount’, visitCount+1);
setVal(‘allTimeVisitCount’, allTimeVisitCount+1);
//feedback of visit counting
visitsFeedback.text = getVal(‘visitCount’);
allTimeVisitsFeedback.text = getVal(‘allTimeVisitCount’);
}
//feedback of cookie contents
function cookieFeedback() {
//in defined print coordinate contents
cookiex.text = getVal(‘circleX’) == undefined ? “no cookie” : getVal(‘circleX’);
cookiey.text = getVal(‘circleY’) == undefined ? “no cookie” : getVal(‘circleY’);

//if not easing assign coordinates from cookie
if (!ease) {
myCookie._x = getVal(‘circleX’);
myCookie._y = getVal(‘circleY’);
}
//set target to cookie coordinates
else {
ctargetx = getVal(‘circleX’);
ctargety = getVal(‘circleY’);
}
//if name then trace cookie contents
if (getVal(‘name’) != undefined) {
visitorFeedback.text = “Returning Visitor”;
nameInput.text = getVal(‘name’);
ageInput.text = getVal(‘age’);
}
//no name then a new visitor
else {
visitorFeedback.text = “First Time Visitor”;
nameInput.text = “”;
ageInput.text = “”;
}
calculateCookieAge();
}
function calculateCookieAge() {
//make a date now
todayDate = new Date();
//get the cookie’s stored date
cookieDate = getVal(‘date’);
//difference between two dates
cookieDateAge = Math.floor(todayDate – cookieDate);
//convert miliseconds to a timecode
cookieAge.text = msToTimeCode(cookieDateAge);cookieDateAge;
}

//convert miliseconds to a hh:mm:ss
function msToTimeCode(ms) {
//make sure value is within bounds. if a number grater than zero and less than the duration of video
if (isNaN(ms) || ms< 0) { ms = 0; } //find seconds var sec = ms/1000; //find minutes var min = Math.floor(sec/60); //adjust seconds sec = sec - min*60; //find hours var hour = Math.floor(min/60); //adjust minutes min = min - hour*60; //floor seconds down to whole number sec = Math.floor(sec); //make time code with hours if (hour == 0) { if (sec < 10) { sec = "0"+sec; } if (min < 10) { min = "0"+min; } var tc = min+":"+sec; } //make time code without hours else { if (sec < 10) { sec = "0"+sec; } if (min < 10) { min = "0"+min; } var tc = hour+":"+min+":"+sec; } return tc; }////// Actionscript attached to Objects/handlers ////////////place data on stage into cookie (circle coordinates and input text) setCookieButton.onRelease = function() { setVal('circleX', myCircle._x); setVal('circleY', myCircle._y); setVal('name', nameInput.text); setVal('age', ageInput.text); //update the display on stage cookieFeedback(); } //make random coordinates on stage randomButton.onRelease = function() { //if not easing assign coordinates to myCircle if (!ease) { myCircle._x = Math.random() * (Stage.width - w); myCircle._y = Math.random() * (Stage.height - w); } //if easing assign coordinates to myCircle's target coords else { targetx = Math.random() * (Stage.width - w); targety = Math.random() * (Stage.height - w); } }myCircle.onPress = function() { this.startDrag(); dragging = true; lineStyle(1, 200, 30); }myCircle.onRelease = myCircle.onReleaseOutside = function() { targetx = this._x; targety = this._y;lineStyle(1, 0, 50);dragging = false; this.stopDrag(); }myCircle.onEnterFrame = function() { //print position feedback currentx.text = this._x; currenty.text = this._y; //if eas move to target if (ease) { if (!dragging) { moveTo(this._x+w, this._y+w); this._x+=(targetx-this._x)/speed; this._y+=(targety-this._y)/speed; } //draw line lineTo(this._x+w, this._y+w); } }myCookie.onEnterFrame = function() { //if ease move cookie to target if (ease) { this._x+=(ctargetx-this._x)/speed; this._y+=(ctargety-this._y)/speed; } calculateCookieAge(); }//Position from Cookie cookieButton.onRelease = function() { //if not easing set coordinates from cookie if (!ease) { myCircle._x = getVal('circleX'); myCircle._y = getVal('circleY'); } //if easing set target coordinates from cookie else { targetx = getVal('circleX'); targety = getVal('circleY'); } } easeBtn.onRelease = function () { //toggle easing ease = !ease; //advance the frame of this button... this.play(); } clearCookieBtn.onRelease = function() { //clear the cookie (swipe all data) myLocalSO.clear(); //restart visit count countVisit(); //read cookie and give feedback cookieFeedback(); } [/cc]

Source

download the source for this example: sharedObject.fla

XML and Flash Actionscript made Easy | Parse XML to Object | Tutorial

XML and flash is something that always seemed to be more complicated than it needed to be. Then I had an idea to parse the xml nodes into actionscript as objects, that would make working with xml tons easier for me, I could just parse it once and then forget about the xml, I could refer to something with the familiar dot syntax rather than worry about firstChild and nextChild and so forth…

This is for AS2. (AS3 has similar functionality built-in via E4X!)

And then I found someone who’d already done that with XML2Object.as, here it is:

[email protected] Class

Actionscript Class:
[cc lang=”actionscript” tab_size=”2″ lines=”40″]
//////////////////
// – Derived from code written by Alessandro Crugnola – http://www.sephiroth.it/file_detail.php?id=129#
// – Refactored and documented by Phil Powell – http://www.sillydomainname.com
// – 25 July 2006 – Added helper method to sanitize Windows line breaks.
//////////////////
// Convert an XML object to an object with nested properties.
//
// Example usage:
//
// import net.produxion.util.XML2Object;
// var contentObj:Object;
// var xml:XML = new XML();
// var xmlLoaded = function( success:Boolean )
// {
// if( success )
// {
// contentObj = XML2Object.deserialize( this );
// this[‘timeline’].play();
// }
// }
//
// xml.ignoreWhite = true;
// xml[‘timeline’] = this;
// xml.onLoad = xmlLoaded;
// xml.load( ‘some.xml’ );
//
/////////////////
// What do you get back?
//
//
//My Title
// // Here be links!
//http://somewhere.com //http://somewhere-else.com //
//

//
// Becomes:
//
// contentObj.content.title.data => “My Title”
// contentObj.content.links.title.data => “Here be links!”
// contentObj.content.links.link => [Array]
// contentObj.content.links.link[0].data => “http://somewhere.com”
// contentObj.content.attributes.created => “22-May-2006”
/////////////////
class XML2Object {private var _result:Object;
private var _xml:XML;
private var _path:Object;
private static var xml2object:XML2Object;public function XML2Object()
{
this._result = new Object();
}

public static function deserialize( xml:XML ):Object
{
xml2object = new XML2Object();
xml2object.xml = xml;
return xml2object.nodesToProperties();
}

public function get xml():XML
{
return _xml;
}

public function set xml( xml:XML ):Void
{
this._xml = xml;
}

private function nodesToProperties( parent:XMLNode, path:Object, name:String, position:Number ):Object
{
var nodes:Array;
var node:XMLNode;

path == undefined ? path = this._result : path = path[name];
if( parent == undefined) parent = XMLNode( this._xml );

if( parent.hasChildNodes() )
{
nodes = parent.childNodes;
if (position != undefined) path = path[position];

while( nodes.length > 0 )
{
node = XMLNode( nodes.shift() );

if ( node.nodeName != undefined )
{
var obj = new Object();
obj.attributes = node.attributes;
obj.data = sanitizeLineBreaks( node.firstChild.nodeValue );

if( path[node.nodeName] != undefined )
{

if( path[node.nodeName].__proto__ == Array.prototype )
{
path[node.nodeName].push( obj );
}
else
{
var copyObj = path[node.nodeName];
delete path[node.nodeName];
path[node.nodeName] = new Array();
path[node.nodeName].push( copyObj );
path[node.nodeName].push( obj );
}
position = path[node.nodeName].length – 1;
}
else
{
path[node.nodeName] = obj;
position = undefined;
}
name = node.nodeName;
}

if( node.hasChildNodes() )
{
this.nodesToProperties( node, path, name, position );
}
}

}
return this._result;
}

private function sanitizeLineBreaks( raw:String )
{
if( raw.indexOf( “\r\n” ) > -1 )
{
return raw.split( “\r\n” ).join( “\n” );
}
return raw;
}
}
[/cc]

Example:

[kml_flashembed fversion=”9.0.0″ movie=”https://circlecube.com/circlecube/wp-content/uploads/sites/10/2008/04/xmltoobject.swf” targetclass=”flashmovie” publishmethod=”dynamic” width=”500″ height=”400″]

Get Adobe Flash player

[/kml_flashembed]

Source:

Here is my example file. But since you cant really see Objects in the code on the stage, I’ve included a recursive trace function to loop through the object and print the data.
[cc lang=”actionscript” tab_size=”2″ lines=”40″]
import XML2Object;

var xmlObject:Object;
var xml:XML = new XML();

var xmlLoaded = function( success:Boolean ){
if( success ) {
xmlObject = XML2Object.deserialize( this );
this[‘timeline’].play();
recurseTrace(xmlObject, ” “);
myTrace(“\n\n”)
myTrace(“xmlObject.catagories.catagory[10].name.data = “+xmlObject.catagories.catagory[10].name.data);
}
}

xml.ignoreWhite = true;
xml.onLoad = xmlLoaded;
xml.load( ‘sampleXML.xml’ );

function recurseTrace(info:Object, indent:String) {
for (var i in info) {
if (info[i] == null){}
else if (typeof info[i] == “object”) {
myTrace(indent + i + ” -“);
recurseTrace(info[i], indent);
}
else {
myTrace(indent + i + ” = ” + info[i] +”, “);
}
}
}

function myTrace(myLine:String){
feedback.text += “|”+myLine;
trace(myLine);
}
[/cc]

And here’s my sample xml file: (it’s the same one I use in my Dynamic Flash Scrolling Link List files)
[cc lang=”xml” tab_size=”2″ lines=”40″]


3D
https://circlecube.com/circlecube/tag/3d/


abstract
https://circlecube.com/circlecube/tag/abstract/


actionscript
https://circlecube.com/circlecube/tag/actionscript/


animation
https://circlecube.com/circlecube/tag/animation/


blog
https://circlecube.com/circlecube/tag/blog/


book
https://circlecube.com/circlecube/tag/book/


CG
https://circlecube.com/circlecube/tag/cg/


charcoal
https://circlecube.com/circlecube/tag/charcoal/


circle cube
https://circlecube.com/circlecube/tag/circle-cube/


collage
https://circlecube.com/circlecube/tag/collage/


color
https://circlecube.com/circlecube/tag/color/


css
https://circlecube.com/circlecube/tag/css/


drawing
https://circlecube.com/circlecube/tag/drawing/


dreamweaver
https://circlecube.com/circlecube/tag/dreamweaver/


experiment
https://circlecube.com/circlecube/tag/experiment/


film
https://circlecube.com/circlecube/tag/film/


final cut
https://circlecube.com/circlecube/tag/final-cut/


flash
https://circlecube.com/circlecube/tag/flash/


[/cc]

Download:

Here’s the XML2Object.as class: XML2Object.as class

 

Here’s a zip containing everything and the working example: xmlToObject.zip

Poll Results are in!

You have spoken, and here’s the Flash and XML made easy Post!
XML and Flash Actionscript made Easy | Parse XML to Object | Tutorial

[poll=4]

Be sure to vote on the new poll, for your Most Wanted Post (here or over in the sidebar)

[poll=5]

Choose your most wanted post(s):

  • Flash cookie | Shared Object
  • Reference Dynamic Instances in Actionscript
  • Flashvar
  • Visual Flash Preloader
  • Dynamic 3d space | Floating Sketches Tutorial

Stomper Scrutinizer Browser AIR App

scrut_4
Software for viewing websites through a simulated fovea vision. Since not everyone could set-up, let alone afford a real eye-tracker. This software uses the mouse pointer as the user’s focal point, or foveal view. It blurs everything except where your focal point (the mouse) is. It is helpful because it forces you to re-think web design from an extreme usability standpoint. This browser software was built using AIR and Flex. Using this software as an eye-tracking simulation, you can get a better idea of how users interact with your site design.
scrut_2scrut_1scrut_3

I was responsible for programming and designing some key functionality of the app: the menu bar logic, bookmarking engine, capturing and saving of screenshots, and the loading bar which shows page load progress, and the overall browser chrome/skin.

Custom Flash Video Player @ FreeIQ and StomperNet

squambido_1
The flash video player designed and developed for Free IQ and StomperNet. Plays video and audio content for a user. I implemented 85% of the actionscript, creating intuitive interactivity and functionality. External xml plsylist, author biography display, content details, share by email, social bookmarking, get embed codes, and more. Sleek design for maximum intuitive user engagement including navigable playlist, author biography, video detail, embedding, email, social bookmarking, volume control, full screen, multiple size options, etc.
squambido_2squambido_4squambido_5squambido_6squambido_7squambido_8

More About Squambido

squambido_3

Dynamic Flash Scrolling Link List XML driven Component on FlashDen

Go get the file at ActiveDen

Dynamic Scrolling Link List XML driven (No Wrap)

An interactive link list. Vertically scrolling list of links or just text. Could be used for a nav menu or a link list, or even just a scrolling list. Scroll speed calculated dynamically from mouse position to give not only scrolling control, but also speed control. Reads an external XML file containing just titles and url paths and creates this interactive click-able link list! On click the link is highlighted and on release loads the url either in a blank window or not (configurable). On rollover the list item grows with animation and is highlighted (all configurable, size speed etc). Once end of list is reached scrolling stops, another version is available with a wrap-around feature: Dynamic Scrolling Link List XML driven Auto wrapping

[kml_flashembed fversion=”9.0.0″ movie=” https://circlecube.com/circlecube/wp-content/uploads/sites/10/2008/03/LinkListNoWrap.swf” targetclass=”flashmovie” publishmethod=”dynamic” width=”550″ height=”250″]

Get Adobe Flash player

[/kml_flashembed]

Circlecube Flash Items at ActiveDen

21075 24687 45713 45893 22018

Get Current URL and Query String Parameters to Flash | Tutorial

Update: please see the newer tut talking about getting the current url, query string vars and more with as3

Overview

This tutorial / how to / example will show how to get the current url from the browser to flash, and even how to get the query string parameters from the url into actionscript using ExternalInterface.
It has been a dilemma for many people to get this information into flash across browsers and without having to rely on flashvars or javascript, but to just have it work.
I wrote a post on it earlier, although it seemed it wouldn’t play nice with Internet Explorer IE, I later realized that it was only because of the way my blog is configured to embed flash. The call ExternalInterface.call(“window.location.href.toString”); or even ExternalInterface.call(‘eval’, ‘window.location.href’); which basically do the same thing.
This can be taken even further and we can read the query string, which, if you don’t know what that is, is the data contained in the url. The data is sent as paired strings, the key and the value. So, for example I could have a url http://example.com/index.html?var1=one&var2=two&var3=three. The question mark separates the actual url path from the query string. So following the ‘?’ we see three variables: var1, var2 and var3, and their corresponding values: one, two and three. They are seperated as pairs with an ampersand (&) and then the key and value are seperated by an equals sign (=). So it goes url?key=value&key=value&key=value…
Once we pass the complete url into our swf, it’s pretty easy to parse the keys and corresponding values.

Steps

  1. Rather than use url with ExternalInterface.call(“window.location.href.toString”); implement the QueryString class make a new QueryString This will do most of the work for you: var myPath:QueryString = new QueryString();
    1. Upon creation of the QueryString object the class reads the parameters automatically by parsing the parameters after the ‘?’ and delimiting on the ‘&’. So you get var1=one and var2=two
    2. Set up each parameter (key) as a variable in the parameter object of the QueryString class assigning it’s value to that variable.
  2. Access your values as myPath.parameters.var1 and myPath.parameters.var2
  3. unescape() your values to make the usable, unless you need them to be encoded or course. Unescape decodes the string from URL-encoded format (converting all hexadecimal sequences to ASCII characters). If your parameter had been some funky encoded string like var4=this+stuff%3E%22%28%29%3F, after you unescape(myPath.parameters.var4) you get: this stuff>”()?.

Example

get url params screenshot
Here’s a working example. This link has the parameters appended to it following the question mark ‘?’ and separated with an ampersand ‘&’ like all query string parameters. I have one for myName (Circlecube) another for myText (Jo Jo is a monkey) which are both pulled out and put into their own text box after they are unescaped, and then there are a couple more parameters just to show, the aNum (3013), anotherParam (more), and ref (https://circlecube.com/circlecube/…)

Special thanks to Abdul Qabiz example. I rewrote it for as2 so it would work with some flash projects I’m working on.

I use the new swf object 2 to embed the swf. Go get it here: swfobject

Actionscript:

The actionscript layer of the swf
[cc lang=”actionscript” tab_size=”2″ lines=”40″]
import flash.external.*; //so we can use externalInterface
import QueryString.as; //so we can use the QueryString Class//make a new QueryString named myPath
var myPath:QueryString = new QueryString();
assignVariables();

//custom function to handle all the query string parameters
function assignVariables() {
//if myName parameter exists
if (myPath.parameters.myName) {
//assign it to the text of the myName text box
//unescape() will translate/unencode the url characters
myName.text = unescape(myPath.parameters.myName);
}
if (myPath.parameters.myText) {
myText.text = unescape(myPath.parameters.myText);
}
if (myPath.url) {
//get the complete url (including any parameters)
thisUrl.text = myPath.url;
}
recurseTrace(myPath.parameters, ” “);
}

//function to recursivly print objects in heirarchy as string
//so we get all parameters no matter what the key traced into
//the allParams text box.
function recurseTrace(info:Object, indent:String) {
for (var i in info) {
if (typeof info[i] == “object”) {
traceParams(indent + i + “:”);
recurseTrace(info[i], indent + ” “);
}
else {
traceParams(indent + i + “: ” + info[i] + “\n”);
}
}
}

function traceParams(traceMe:String) {
allParams.text += traceMe;
}
[/cc]

The QueryString.as class for as2
[cc lang=”actionscript” tab_size=”2″ lines=”40″]
class QueryString {
//instance variables
var _queryString;
var _all;
var _params:Object;

public function QueryString() {
readQueryString();
}
public function get getQueryString():String {
return _queryString;
}
public function get url():String {
return _all;
}
public function get parameters():Object {
return _params;
}

private function readQueryString() {
_params = {};
try {
_all = ExternalInterface.call(“window.location.href.toString”);
_queryString = ExternalInterface.call(“window.location.search.substring”, 1);
if(_queryString) {
var allParams:Array = _queryString.split(‘&’);
//var length:uint = params.length;

for (var i = 0, index = -1; i < allParams.length; i++) {
var keyValuePair:String = allParams[i];
if((index = keyValuePair.indexOf(“=”)) > 0) {
var paramKey:String = keyValuePair.substring(0,index);
var paramValue:String = keyValuePair.substring(index+1);
_params[paramKey] = paramValue;
}
}
}
}
catch(e:Error) {
trace(“Some error occured. ExternalInterface doesn’t work in Standalone player.”);
}
}
}
[/cc]

Download

Here’s a zip file containing the sample files, the QueryString Class file, and even the swfobject javascript file.
getURLParams.zip

Interactive Spin Actionscript Tutorial

I have been thinking of different interactions that are possible with objects. If you’ve read this blog at all you’ll know that I’ve played with physics and gravity and throwing balls and bouncing balls and all sorts. But I hadn’t wrapped my head around an interactive spinner. I know it’d be easy to make a slider or something that would apply a spin to an object, but this just isn’t interactive enough for me.

Circle with slider to rotate and button for random spin:

[kml_flashembed publishmethod=”dynamic” fversion=”9.0.0″ movie=”https://circlecube.com/circlecube/wp-content/uploads/sites/10/2008/03/spin.swf” width=”500″ height=”300″ targetclass=”flashmovie”]Get Adobe Flash player

[/kml_flashembed]

This attempt at spinning is ok. I mean, it spins the object and it even glides to a stop if you press the button for a random spin… But it’s just not intuitive and not fun. But if you want this, here’s how I did it.

Actionscript:

[cc lang=”actionscript” tab_size=”2″ lines=”40″]
drag = .96;
speed = 0;

slider.handle.onPress = function() {
spinning = false;
//drag along the line
this.startDrag(true, slider.line._x-slider.handle._width/2, slider.line._y-slider.handle._height/2, slider.line._width-slider.handle._width/2, slider.line._y-slider.handle._height/2);
}
slider.handle.onRelease = slider.handle.onReleaseOutside = function() {
this.stopDrag();
}
_root.onEnterFrame = function() {
if (spinning) {
//apply the speed to the rotation
knob._rotation += speed;
//recalculate speed
speed = speed*drag;
//if speed gets unnoticeably tiny just set it to 0
if (Math.pow(speed, 2) < .0001) {
speed = 0;
}
}
else {
//set the rotation from the slider position
knob._rotation = slider.line._x + slider.handle._x + slider.handle._width/2;
}

//spit out feedback continuously
feedbackr.text = knob._rotation;
feedbackaccr.text = speed;
}
spinner.onRelease = function() {
//find a random speed
speed = (Math.random()* 50) – 25;
spinning = true;
}
[/cc]

I want to grab it and spin it though. I want to apply the same principles from physics, like acceleration and friction as forces to the object, so I can grab to spin and release to watch it glide gracefully to a stop. I’ve been thinking about this and how I’d have to use trigonometry and stuff to do it. One day I finally had the time and tried it out. It took me a minute but I figured out that what I needed was arctangent. So (with pointers from jbum, thanks Jim!) I came up with this:

Interactive grab-able circle to spin and twirl:
[kml_flashembed publishmethod=”dynamic” fversion=”9.0.0″ movie=”https://circlecube.com/circlecube/wp-content/uploads/sites/10/2008/03/interactivespin.swf” width=”500″ height=”300″ targetclass=”flashmovie”]Get Adobe Flash player

[/kml_flashembed]

This one is much more interactive and intuitive. I really think this is because there are no sliders or buttons, no controls, just an object to interact with. It’s much more like real life!

Steps:

In order to make a grab and spin object
1. You have to know where you grab. The user clicks on the shape (knob) and you must figure out what degree or rotation point they have started at. (atan2)
2. As the knob is clicked and the mouse moves (dragging), calculate new rotation by mouse position
3. When mouse is released figure out the current speed of rotation and apply it to the knob with friction, so it can be thrown and spun in that way. (Of course this is optional, if you just want to spin it when the mouse is down you’re done at step 2)

Actionscript:

[cc lang=”actionscript” tab_size=”2″ lines=”40″]
damp = .96; //friction
r = 0; //rotation
accr = 0; //speed of rotation

knob.onPress = function() {
dragging = true;
//find mouse y coordinate in relation to knob origin
a = _root._ymouse – knob._y;
//find mouse x coordinate in relation to knob origin
b = _root._xmouse – knob._x;
//using arctangent find the spot of rotation (in degrees)
oldr = Math.atan2(a,b)*180/Math.PI;
}

knob.onRelease = knob.onReleaseOutside = function() {
dragging = false;
}

knob.onEnterFrame = function() {
if (dragging) {
//find mouse y coordinate in relation to knob origin
a = _root._ymouse-knob._y;
//find mouse x coordinate in relation to knob origin
b = _root._xmouse-knob._x;
//using arctangent find the spot of rotation (in degrees)
r = Math.atan2(a,b)*180/Math.PI;

//use current rotation and previous rotation
//to find acceleration
//averages the acceleration with the
//previous acceleration for smoother spins
accr = ((r – oldr) + accr)/2;
//apply the acceleration to the rotation
knob._rotation += accr;
//remember current rotation as old rotation
oldr = r;
feedbacka.text = a;
feedbackb.text = b;
}
else {
knob._rotation += accr;
//apply friction to acceleration force
//and if acceleration gets tiny, just set it to zero
if (Math.pow(accr, 2) > .0001 ) {
accr *= damp;
}
else{
accr = 0;
}
}
//spit out feedback continuosly
feedbackr.text = knob._rotation;
feedbackaccr.text = accr;
}
[/cc]

I commented the code to explain what is happening, if you need more just post a comment. Let me know if you find this useful and what you end up making with it.

Downloads:

spin.fla and interactiveSpin.fla

Local Connection Actionscript – Communicate between seperate Flash files | Tutorial

Overview:

Local Connection
Communication between two separate flash files placed on the same page (or even running simultaneously on one machine) is a nice way to spread a project out. You can send variable, call functions, pretty much do anything in one swf from another. Easiest case use would be a navigation menu set up in one flash file to control the other one containing the content. I’ve made an example here showing how to send text from one to another. I’ve done it both directions here. Send text from the red swf to the blue swf, and from mr. Blue you send to the red flash file. I have named the flash functions in actionscript accordingly (or tried to, now I notice a few places I misspelled receive, ‘i’ before ‘e’, right? oh yea, except after ‘c’)…
Anyways, try out the example here, I made it a little easier by putting a keyListener on ‘Enter’, so you don’t have to actually press the send button. Didn’t realize it before, but this is like a chat app built in flash! So go ahead and chat with yourself to prove that it works!

Execute actionscript in one swf from another! Inter-swf communication.

Example:

Type here to send Red text to Blue flash file
[kml_flashembed publishmethod=”dynamic” fversion=”9.0.0″ movie=”https://circlecube.com/circlecube/wp-content/uploads/sites/10/2008/03/localConnectionRed.swf” width=”550″ height=”400″ targetclass=”flashmovie”]Get Adobe Flash player

[/kml_flashembed]

And see it received here, and go ahead and send some back to Red.
[kml_flashembed publishmethod=”dynamic” fversion=”9.0.0″ movie=”https://circlecube.com/circlecube/wp-content/uploads/sites/10/2008/03/localConnectionBlue.swf” width=”550″ height=”400″ targetclass=”flashmovie”]Get Adobe Flash player

[/kml_flashembed]

Actionscript:

Red:
[cc lang=”actionscript” tab_size=”2″ lines=”40″]
// Receiving
//create a local connection for reciept of text
var receiving_lc:LocalConnection = new LocalConnection();
//function called from other swf
receiving_lc.recieveBlueText = function(textRecieved:String) {
feedback.text += textRecieved+”\n”;
};
//receive connection of specified name
receiving_lc.connect(“fromBlue”);

//Sending
sendButton.onRelease = function() {
//create local connection for sending text
var sending_lc:LocalConnection = new LocalConnection();
//put text from input into a var
var textToSend = inputText.text;
//send through specified connection, call specified method, send specified parameter
sending_lc.send(“fromRed”, “recieveRedText”, textToSend);
//set the input empty
inputText.text = “”;
}
[/cc]

Blue:
[cc lang=”actionscript” tab_size=”2″ lines=”40″]
// Receiving
var receiving_lc:LocalConnection = new LocalConnection();
receiving_lc.recieveRedText = function(textRecieved:String) {
feedback.text += textRecieved+”\n”;
};
receiving_lc.connect(“fromRed”);

//Sending
sendButton.onRelease = function() {
var sending_lc:LocalConnection = new LocalConnection();
var textToSend = inputText.text;
sending_lc.send(“fromBlue”, “recieveBlueText”, textToSend);
inputText.text = “”;
}
[/cc]

And the code to listen to the ‘enter’ key(this is in both files):
[cc lang=”actionscript” tab_size=”2″ lines=”40″]
//Enter button to send
var keyListener:Object = new Object();
keyListener.onKeyDown = function() {
if (Key.getCode() == “13”) {
sendButton.onRelease();
}
};
Key.addListener(keyListener);
[/cc]

Download Source:

localConnectionRedBlue.zip

StomperNet Scrutinizer Update | Features include Bookmarking, Screenshots & Loader

Scrutinizer is constantly being updated and enhanced and with the launch of Adobe AIR 1.0 is easier than ever to install!

It now supports bookmarking, capturing and saving screenshots and displays progress as pages load.
With even more to come soon!

Go check it out at StomperNet’s public site for free download!
Here’s some images to show off scrutinizer!

Watching the loader while my page loads:
scrutinizer loader

Scrutinizing this circlecube blog:
scrutinizer screenshot

Bookmarking my page for quick access:
scrutinizer bookmark