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

    /* 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();

    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,

    Get Adobe Flash player

    and source code:

    ////////////////////////  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();
    }

    Source

    download the source for this example: sharedObject.fla

    This entry was posted in tutorial and tagged , , , , , , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

    One Comment

    1. Posted March 12, 2010 at 10:43 am | Permalink

      Hi,
      Thanks for the creative example. I used these once for a flash header on a website. The client wanted the movie to continue to play as people navigated through different pages and it was pretty amazing.

      Thanks!

    One Trackback

    1. [...] Flash Cookies (hard to handle/delete properly) [...]

    Post a Comment

    Your email is never published nor shared. Required fields are marked *

    *
    *

    You may use these HTML tags and attributes: <a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

    • Recent Posts

      WordPress updates plugin directory

      New additions to the plugin directory include: favorites, incorporating support forums into it's own tab for each plugin as well as support stats being displayed! Great! I think we also need the ability to give plugins ratings and reviews (bonus points if it can be done from within a wordpress admin dashboard when installing plugins). [...]

      Short Head

      Use zipf's short head to tune your website rather than redesign the whole thing. To make a website successful it needs to meet the needs of the users. Find out what those needs are by using the short head philosophy to equate most searched things as the biggest needs of the users. Use personas to [...]

      Img Set?

      Great article at a list apart discusing the state of the industry regarding responsive images. This picks apart the set attribute of the img element from a surprisingly objective view coming from someone so close to the picture element. Insightful discussion about the principle behind the proposals than the actual solution too. If the working [...]

      Triudo

      A mesmerizing animated triangle-ish shape form. Embedded Link triduo triduo Tweet

      Git – the paradigm shift

      A great developer story about the differences on what Git is vs other version control and what Git is not. This is how we should learn it. I heard over and over that it was distributed, but never grasped what that meant, so here are a few links and explanations that will help unlearn version [...]

      Tweening Lib comes to Javascript!

      I'm very excited to share the news that the tween library from GreenSock (hands down the best tweening library I used in flash) is not ported for use in javascript! This will be great! I missed that simple syntax from as3 when animating javascript, and now I can have my cake and eat it too. [...]

      Responsive CSS Tricks

      Here are a few useful css tricks to remember when building responsive design sites from web designer wall Embedded Link 5 Useful CSS Tricks for Responsive Design Making the design to be responsive is very easy as shown in my Responsive Design in 3 Steps tutorial, but maintaining the elements to look aesthetically balanced on [...]

      Picture element of srcset attribute?

      Bruce details the reasons and story behind the srcset attribute which is now introduced as an alternative to the picture element. Some aspects of the attribute are nice (like the fact that it's an attribute and not a new element, so it's creating up new elements with for problems. It's adapting currently used elements to [...]

      SVG Preloader with Raphael JS

      Here's a very creative use of using a newly available technology. Using svg graphics which are very lightweight, for a website preloader. I like the animation used as well. Embedded Link Make a stylish preloader with SVG | Tutorial | .net magazine Many sites neglect users with slow connections. Ian Culshaw explains how to use [...]

      CSS3 Button/Icon set

      I've been secretly hoping to see a few of these pop up once the whole icon font idea spread through the nets. I really like this idea and it's a very nice implementation too! I only see some quality issues on a couple of the icons (such as youtube), but it's awesome and I hope [...]

    • Recent Comments

      Bruce Brownlee

      Bruce Brownlee

      Ah IE6. I'd have 2 more years of sleep without IE6. Margin doubling, no properties,...
      versaena

      versaena

      how to give color at runtime…… thank you
      Mobile Websites

      Mobile Websites

      I disagree, mobile websites are the future – desktop websites and mobile websites...
      Matt Fasick

      Matt Fasick

      That's cool. I like the ripple effect as well.
      Nico

      Nico

      hi! really great job guy! very impressive.. just a question… do u have a solution to do a refresh...
      Evan Mullins

      Evan Mullins

      Agreed! I've just seen some people get pretty heated about separating all functionality...