circlecube Relaunch

Not just a redesign but a whole new site and location! After having built loads of sites for clients/friends I kept learning things I wanted to employ on my own site, but the cobblers kids are always barefoot right? I kept implementing new things and knew that they were making my clients lives easier and I wanted it easier as well.

circlecube logo
I’d already updated my logo a number of times since my last redesign and I wasn’t happy with how my collection of sites all looked different and required repetitive work to maintain. circlecube-sketch-3Well, I did some sketches and committed to working on it just a few minutes a day. I really work best as I visually think through a design so sketching is always the first step in my designs. After I nailed down the basic elements and concepts I needed in the site through sketches I installed a new wordpress site, the thematic framework and then got started on a child theme. I really surprised myself and in a mere couple weeks I had a short list of things to do before I could “flip the switch”. The hardest part by far was trying to do 301 redirects from all the old posts which lived on either my blog or portfolio sub-domains. But thanks to my friend we were able to iron that out and I learned more than I ever wanted to know about mod rewrites and such. I was able to combine my blog and portfolio and my home page all into one site. I always felt weird pushing friends/potential clients and everyone else to my blog or my landing page or portfolio… but now they can all simply go to the same place!

circlecube-sketch-1My goal was to enable all content to be updated in the back-end, I didn’t want any content in the theme. And I didn’t want to have to redo the css or layout to move something from the header to the footer or sidebar for example. I placed a lot of content in widgets and a few pages that were wholly widget areas. I also needed a portfolio section that displayed a little gallery of images and possibly flash content automatically. It needed to be easy if I were going to ever update the portfolio, so I used custom post types and custom fields to attach images and other data to each portfolio item. Then one of my favorite pages is the social page, it’s just a collection of my social feeds all displayed neatly in one place.

While I’d love to release the theme for everyone, I cheated and used quite a few plug-ins to accomplish my designs so the theme itself doesn’t include all the functionality and I’m pretty sure it’s bad for to require plug-ins and set up to get a theme functional, but if you’re interested, let me know.

As usually happens though, I learned some more tricks as I built this site. So I have a list of things I’m ready to write and share about on the blog: custom post types, custom taxonomies, thematic customizations, css tricks, fancybox, custom fields, jquery, widgets, htaccess, importing/exporting wordpress, new favorite plug-ins and more… So be excited!

My only regret so far is the lack of texture on the site so I may come back and apply slight noise to the site background to make it more tangible. But I also like the clean look. Well, to see snapshots of the site I added the circlecube redesign to the portfolio section of this site (cheesy to include my own site in my portfolio? yep, but I’m excited to use the feature and I always retrospectively wish I’d documented site updates).

Still, there may be a few things that don’t fully connect, so please, please let me know if you see anything broken or experience a broken link. But stay tuned for some posts since I’m not spending time building the site I’ll put a little time each day into putting content on the site again.

Javascript to show/hide elements update with jQuery

I never expected it, but one of the most popular (most commented) posts on this blog is a javascript post from about 3 years ago. I was showing how to hide and show elements on a web page with some simple javascript using getElementById and altering the display or visibility attributes of the element. It still works – although I hear every once in a while that certain browsers have issues with is sometimes, but the truth is I haven’t used this code almost since I wrote it. I have converted to jQuery! And it is much easier to code, easier to read and even nicer to browsers. So I’m writing this update post to proclaim the antiquity (3 years on the internet is a long time) of getElementById and the benefits of jQuery!

There isn’t much more to say about it really. I hope you’ve heard of jquery and if not, please go check it out it’s pretty easy to pick up! One thing I will mention is the potential bloat to having to load a javascript library. But most of my projects lately have included jQuery because I’ve been using it much more than just showing and hiding elements. But remember our friend cache? Remember that if you’re using jQuery on a whole site, the user only loads it once, and if you load it from the google hosted version of jQuery they likely will already have the script in their cache. The current version is hosted at http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js, so just link to that script on your page and you’re free to throw in any jquery onto your page.

Well, check out the code; I hope it’s pretty self explanatory and you can see it in action. I always have to see things work to understand them and learn from them.

Javascript

[cc lang=”javascript”]
$(document).ready(function() {

$(‘.hide_it’).click(function(){ $(‘.to_hide’).hide(); });

$(“.show_it”).click(function () { $(“.to_show”).show(“slow”); });

$(“#toggle_it”).click(function () { $(“.to_toggle”).toggle(); });

$(‘.fade_it’).click(function() { $(“.to_fade”).fadeTo(“slow”,0); });

$(‘.fade_out’).click(function() { $(“.to_fade_out”).fadeOut(); });

$(‘.reset_all’).click(function() {
$(‘.to_hide’).show();
$(“.to_show”).hide();
$(“.to_toggle”).show();
$(“.to_fade”).fadeTo(“slow”,100);
$(“.to_fade_out”).fadeIn();
});
});
[/cc]

show-hide-jquery-screenshot

HTML Code

see it in action on the demo page
[cc lang=”html”]

testing hide js div

hide it


Show me slowly.


testing the toggle functionality of jQuery


testing fade out. you’ll notice that this is set to display:none once the fade is complete.

fade out


testing fade to 0. this fades out just as fadeOut, but it does no make the display none, so the page layout isn’t modified, just the visibility of this element.

fade it


[/cc]

Notice that with jQuery we can use a class or an id as a selector. This is great because you can show a whole slew of elements that share the same class at once. Remember that you can only have one id on a page at once since it must be unique.

See the demo page for working examples.

And don’t forget to read up on the api for jQuery here jQuery hide, jQuery show, jQuery toggle, jQuery fadeOut, jQuery fadeIn, jQuery fadeTo.

Update a thematic child-theme for wordpress 3.0 menu


The new menu system in wordpress, while not perfect (yet), is a huge step in the right direction. I have had to update many old themes to support this feature, and as most of my theming is down with thematic, I finally got a standard block of code together to add to a functions.php file of a child theme to add theme support for menus and add them to the theme. Here is the code, all you do is add it to your functions file and then you can manage menus thorugh the new menu page in your pw dashboard! Enjoy!
[cc lang=”php”]
//// Add support for new menu in WP3
// declare that our theme supports wp_nav_menu()
add_theme_support( ‘menus’ );

// Register the a new menu for the theme called “Primary Menu”
function register_primary_menu() {
register_nav_menu( ‘primary-menu’, __( ‘Primary Menu’ ) );
}
add_action( ‘init’, ‘register_primary_menu’ );

// Remove the standard Thematic menu
function remove_menu() {
remove_action(‘thematic_header’,’thematic_access’,9);
}
add_action(‘init’, ‘remove_menu’);

// Create the new wp_nav_menu called “Primary Menu” in theme
function new_access() { ?>

Better jquery mega-menu tutorial

My earlier simple mega menu implementation post displayed some simple css and jquery to explode a standard navigation menu into a mega-menu… I’ve made it even better. My biggest issue with that implementation was that it did not keep the order like you’d expect. It read left to right in columns rather than down each column. In the example you can see the first column of three would read from the top: a, d, g, j… this could potentially be confusing. So I wanted to update it to keep the order better and just stack the columns of elements rather than the elements themselves.

I used some different jquery to execute this. First we walk through the menu elements and calculate which column they should be in. We basically map that element’s (li)index to the column it should be, some big math. Luckily I had some experience from actionscript in my arsenal doing just that, so porting the function to javascript I was ready to go. If your number X falls between A and B, and you would like to convert it to Y which falls between C and D follow this formula: Y = (X-A)/(B-A) * (D-C) + C. Plugging this function in and cancelling out the zeros and adding some rounding to get integers I got: Math.floor((liindex / $total * $cols)+1). Using this I added a class to each ‘li’ designating which column it should be in, and then used wrapAll to wrap them into column divs. Very simple and a much better implementation overall anyways. Better code, better user experience… what more can you ask… so here’s the example and jquery code. I’m thinking I should make this into a jquery plugin or something, any thoughts?

better-mega-menu-screenshot

See the mega menu in action

Javascript code

[cc lang=”javascript”]
jQuery(document).ready(function() {
//clean up the row of the mega menu. add css class to each element on bottom row.
//only if more than 7 elements. if more than 16, mm-3
jQuery(‘#nav li ul’).each(function(ulindex, ulele){
$total = jQuery(this).children(‘li’).size();
if ($total <= 7) { jQuery(this).addClass('mm-1'); } else { $cols = Math.floor(($total) / 8) + 1; $remainder = $total % $cols; $rows = Math.ceil($total / $cols); jQuery(this).addClass('mm-' + $cols + ' total-' + $total + ' rem-'+$remainder );jQuery(this).children().each(function(liindex, liele){ //alert("total: "+$total+", remainder: "+ $mod+", ulindex: "+ulindex+", liindex: "+liindex); //If your number X falls between A and B, and you would like to convert it to Y which falls between C and D follow this formula: Y = (X-A)/(B-A) * (D-C) + C. jQuery(this).addClass('col-' + Math.floor((liindex / $total * $cols)+1) ); if( (liindex+1) % $rows == 0) { jQuery(this).addClass('last'); } });for (var colcount = 1; colcount<= $cols; colcount++){ jQuery(this).children('.col-'+colcount).wrapAll('

‘);
}
}
});
});
[/cc]

css

[cc lang=”css”]
ul { list-style:none; }

/********** < Navigation */ .nav-container { float:left; background: #398301; margin: 10em 0; width: 960px; } #nav { border: 0px none; padding:3px 0 2px 44px; margin:0; font-size:13px; }/* All Levels */ #nav li { text-align:left; position:relative; } #nav li.over { z-index:999; } #nav li.parent {} #nav li a { display:block; text-decoration:none; } #nav li a:hover { text-decoration:none; } #nav li a span { display:block; white-space:nowrap; cursor:pointer; } #nav li ul a span { white-space:normal; }/* 1st Level */ #nav li { float:left; } #nav li a { float:left; padding:5px 10px; font-weight:normal; color: #fff; text-shadow: 1px 1px #1b3f00; } #nav li a:hover { color: #fff; text-shadow: 1px 1px 3px #ccc; } #nav li.over a, #nav li.active a { color:#fff; }/* 2nd Level */ #nav ul { position:absolute; width:15em; top:26px; left:-10000px; border:1px solid #1b3f00; border-width: 0 1px 2px 1px; background:#398301; padding: 6px 0 6px; } #nav ul div.col { float:left; width: 15em; } #nav ul li { float:left; padding: 0; width: 15em; } #nav ul li a { float:none; padding:6px 9px; font-weight:normal; color:#FFF !important; text-shadow: 1px 1px #1b3f00; border-bottom:1px solid #1b3f00; background:#398301; } #nav ul li a:hover { color:#fff !important; text-shadow: 1px 1px 3px #ccc; background: #2b6301; } #nav ul li.last > a { border-bottom:0; }
#nav ul li.last.parent > a { border-bottom:0; }

#nav ul li.over > a { font-weight:normal; color:#fff !important; background: #1b3f00; }
#nav ul.mm-1 { width: 15em; }
#nav ul.mm-2 { width: 30em; }
#nav ul.mm-3 { width: 45em; }
#nav ul.mm-4 { width: 60em; }
/* 3rd+ leven */
#nav ul ul { top:-6px; background: #1b3f00; }

/* Show Menu – uses built-in magento menu hovering */
#nav li.over > ul { left:0; }
#nav li.over > ul li.over > ul { left:14em; }
#nav li.over ul ul { left:-10000px; }

/* Show Menu – uses css only, not fully across all browsers but, for the purpose of the demo is fine by me */
#nav li:hover > ul { left:0; z-index: 100; }
#nav li:hover > ul li:hover > ul { left:14em; z-index: 200; }
#nav li:hover ul ul { left:-10000px; }
[/cc]

Download

Visit this demo page and view source or save as…

A simple mega menu implementation with CSS and jquery

I’ve been skinning quite a few ecommerce sites with the magento platform and wanted a simple way to explode the navigation menus. Some sites end up getting a long list of categories and sub-categories, so I wanted to do a mega-menu style navigation. One way to do it was to rewrite the html code for the navigation and pop each column into another nested unordered list. I’m not a fan of doing this because one – I didn’t want to manipulate the html. I like the simplicity of ul navigation with a clear flat list of li elements. Of course for nested sub-navigation any li can contain another ul. I wanted to just use some css and maybe javascript to visually accomplish the same thing. I also wanted it to be portable, so I could take it and use it on a wordpress install or even a plain html site. I went to my favorite: jquery. I knew there was a likely plugin out there already that would do something similar, but nothing after my initial search, but I realized that it was a simple procedure and mostly accomplished with some css.
mega menu screenshot
I’ll walk you through the process here and let you inspect the code yourself and see it in action on the demo page. Assign each ul to be a default width of 15em, then each li element we float:left and also give it a width of 15em. This way we can change the ul width to 30em and automatically I have 2 columns! Assigning the nested ul a specific width according to it’s class is done through css, mm-0 will be 15em and incrementally each next one will be 15em more. mm-1 is 30 and mm-2 is 45. Then we use jquery to determine the number of elements in the list and assign it a class accordingly. This involves some math and some preferences. Using the magic ui number 7, I determined that a menu with more than 7 elements should explode into multiple columns. So anything less than or equal to 7 I assign the class ‘mm-1’ which in the css sets the width to the standard 15em (ie 1 mega menu column). More than 7 should pop into columns no more than 8 tall. So dividing the total by 8 will give us the number of columns we want. We’ll add a class of mm-x, where x would be the number of columns. And the li elements will float to the left and fill in the space in columns.
One specific issue is the last element in the menu, sometimes we need to style that element differently. I’ll loop through each child of the nested ul element and if it is on the bottom row apply a class of ‘last’. But this was a little tricky in calculating which would be last because were never sure how many elements there will be or how many columns. I just used the remainder after dividing the total by the number of columns, then if the remainder could be used to know which elements are on the bottom row.

OK, now that that’s out of the way, let’s look at the code.

HTML

This I won’t show, you can inspect the source of the demo if you wish to see it, it a basic nested collection of unordered lists. It’s the standard that is created by magento, wordpress and most other CMS platforms.

CSS

[cc lang=”css”]
html, body { margin:0; padding:0; }
ul { list-style:none; }

/********** < Navigation */ .nav-container { float:left; background: #186C94; margin: 10em 0; width: 960px; } #nav { border: 0px none; padding:3px 0 2px 44px; margin:0; font-size:13px; }/* All Levels */ #nav li { text-align:left; position:relative; } #nav li.over { z-index:999; } #nav li.parent {} #nav li a { display:block; text-decoration:none; } #nav li a:hover { text-decoration:none; } #nav li a span { display:block; white-space:nowrap; cursor:pointer; } #nav li ul a span { white-space:normal; }/* 1st Level */ #nav li { float:left; } #nav li a { float:left; padding:5px 10px; font-weight:normal; color: #fff; text-shadow: 1px 1px #111; } #nav li a:hover { color: #fff; text-shadow: 1px 1px 3px #ccc; } #nav li.over a, #nav li.active a { color:#fff; }/* 2nd Level */ #nav ul { position:absolute; width:15em; top:26px; left:-10000px; border:1px solid #104A65; border-width: 0 1px 2px 1px; background:#186C94; padding: 6px 0 6px; } #nav ul div.col { float:left; width: 15em; } #nav ul li { float:left; padding: 0; width: 15em; } #nav ul li a { float:none; padding:6px 9px; font-weight:normal; color:#FFF !important; text-shadow: 1px 1px #111; border-bottom:1px solid #104A65; background:#186C94; } #nav ul li a:hover { color:#fff !important; text-shadow: 1px 1px 3px #ccc; background: #135575; } #nav ul li.last > a { border-bottom:0; }
#nav ul li.last.parent > a { border-bottom:0; }

#nav ul li.over > a { font-weight:normal; color:#fff !important; background: #104A65; }
#nav ul.mm-1 { width: 15em; }
#nav ul.mm-2 { width: 30em; }
#nav ul.mm-3 { width: 45em; }
#nav ul.mm-4 { width: 60em; }
/* 3rd+ leven */
#nav ul ul { top:-6px; background: #104A65; }

/* Show Menu – uses built-in magento menu hovering */
#nav li.over > ul { left:0; }
#nav li.over > ul li.over > ul { left:14em; }
#nav li.over ul ul { left:-10000px; }

/* Show Menu – uses css only, not fully across all browsers but, for the purpose of the demo is fine by me */
#nav li:hover > ul { left:0; z-index: 100; }
#nav li:hover > ul li:hover > ul { left:14em; z-index: 200; }
#nav li:hover ul ul { left:-10000px; }
[/cc]

Javascript

Don’t forget to include jQuery (I prefer using the google hosted version at http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js)
[cc lang=”javascript”]
jQuery(document).ready(function() {
//clean up the row of the mega menu. add css class to each element on bottom row.
//only if more than 7 elements. if more than 16, mm-3
jQuery(‘#nav li ul’).each(function(ulindex, ulele){
$total = jQuery(this).children(‘li’).size();
if ($total <= 7) { jQuery(this).addClass('mm-1'); } else { $cols = Math.floor(($total) / 8) + 1; $remainder = $total % $cols; jQuery(this).addClass('mm-' + $cols + ' total-' + $total + ' rem-'+$remainder );jQuery(this).children().each(function(liindex, liele){ //alert("total: "+$total+", remainder: "+ $mod+", ulindex: "+ulindex+", liindex: "+liindex); if( liindex + $remainder >= $total || $remainder == 0 && liindex + $cols >= $total ){
//alert(“total: “+$total+”, remainder: “+ $remainder+”, index: “+liindex);
jQuery(this).addClass(‘last’);
}
});
}
});

});
[/cc]

See the demo in action

Flashvars and as3

flashvars_as3_thumbFlashvars and actionscript 3! Flashvar is a way that in your html embed codes (object tags) you can send variables and values into your swf file. These variables can then be grabbed internally and used your programming! Examples of these could be images that you want to use in your swf but don’t want to import or hardcode them into the flash file or paths to xml or flv files to use as well. Actionscript 3 has a different procedure than as2 did as to how you read these flashvars from the actionscript side. The embed codes and html side of things are still the same, but in case your new to actionscript altogether, I’ll give an example of the html as well. [cc lang=”html”] [/cc] In actionscript 3 we use the loaderInfo object to access the flashvars. The parameters Object of the loaderInfo will contain all the flashvar variables and values. [cc lang=”actionscript”] this.loaderInfo.parameters [/cc] As an example of something that is visual I’ve created this little app to read some options from flashvars about colors. An app that will read a list of colors and update a box that is on the stage already to those colors with the specified delay. I always have fun with randomness so I threw in the option for random colors as well. This file looks for certain flashvars: color, loop, delay and random. These are the keys or names of the variables and they are followed by the values you want them to hold. Note that flashvars can be set in any order, so you don’t have to start with color and end with random. In this example I’m looking for 4 flashvars specifically (in any order):

  • colors:String – a comma delimited list of hex colors or simply a string “random” for randomly generated colors (the hex for black #000000 needs to be 0x000000 in flash) (default is random)
  • loop:Boolean – whether or not to repeat these colors (default is true)
  • delay:Number – the delay between colors (in seconds). (default is 1 second)
  • random:Boolean – determines whether to cycle through colors in given order or randomize. selecting random overrides the loop to true. (default is false)

This is much more than is required for this example, but I was having fun playing with random colors and timing and options. I figured it doesn’t hurt to show the effect you can have with a couple different variables on one file. Here is an example using the object tags above: [kml_flashembed publishmethod=”dynamic” fversion=”9.0.0″ movie=”https://circlecube.com/circlecube/wp-content/uploads/sites/10/2009/12/flashvars_as3.swf” width=”200″ height=”200″ targetclass=”flashmovie” fvars=”colors=0xFF0000,0x0FF000,0x00FF00,0x000FF0,0X0000FF,0xF0000F&delay=.66&loop=true&random=false”] Get Adobe Flash player [/kml_flashembed] And here are some more (please don’t have a seizure!) Here’s the full source if you’re interested: [cc lang=”actionscript”] /* circlecube.com App to demonstrate the process of getting flashvars from embed code to actionscript (as3) Displays colors specified. looking for 4 flashvars specifically (in any order): colors:String – a comma delimited list of hex colors or simply a string “random” for randomly generated colors (the hex for black #000000 needs to be 0x000000) (default is random) loop:Boolean – wether or not to repeat these colors (default is true) delay:Number – the delay between colors (in seconds). (default is 1 second) random:Boolean – determines wether to cycle through colors in given order or randomize. selecting random overrides the loop to true. (default is false) */ //initialize vars var myflashvars:Object = new Object() var myColors:Array = new Array(“random”); var myLoop:Boolean = true; var myDelay:Number = 1; var randomOrder:Boolean = false; var allRandom:Boolean = false; //read flashvars in actionscript3 //if colors flashvars doesn’t exist use these defaults if (!this.loaderInfo.parameters.colors){ myflashvars = {colors: “random”, delay: 1}; } else{ myflashvars = this.loaderInfo.parameters; } //assign flashvars to variables within flash for (var item:String in myflashvars) { trace(item + “:\t” + myflashvars[item]); if (item == “colors”){ myColors = myflashvars[item].split(‘,’); } else if(item == “loop”){ myLoop = parseBoolean(myflashvars[item]); } else if(item == “delay”){ myDelay = myflashvars[item]; } else if(item == “random”){ randomOrder = parseBoolean(myflashvars[item]); } } //use my variables! if (myColors[0] == “random”){ allRandom = true; } var counter:Timer = new Timer(myDelay * 1000); counter.addEventListener(TimerEvent.TIMER, nextColor); trace (“color number: 0”, “color hex: “+myColors[0]); setColor(myBox, myColors[0]); counter.start(); stop(); function nextColor(e:Event):void{ //cycle through colors if (!allRandom && !randomOrder){ if (counter.currentCount+2 > myColors.length){ if (myLoop == true || myLoop == “true”){ counter.reset(); counter.start(); } else{ counter.stop(); } } trace (“color number: “+counter.currentCount, “color hex: “+myColors[counter.currentCount]); setColor(myBox, myColors[counter.currentCount – 1]); } //randomly select a color from the myColors array else if (!allRandom && randomOrder){ var randomColor = Math.floor(Math.random() * myColors.length); trace (“random number: “+randomColor, “color hex: “+myColors[randomColor]); setColor(myBox, myColors[randomColor]); } //randomly create colors else{ trace (“number: “+counter.currentCount, “color hex: “+myColors[0]); setColor(myBox, myColors[0]); } } function setColor(item:DisplayObject, col):void{ if (col == “random”){ setRandomColor(item); } else{ setHexColor(item, col); } } function setHexColor(item:DisplayObject, col:Number):void { var myColor:ColorTransform = item.transform.colorTransform; //check color bounds if (col > 16777215) col = 16777215; else if (col < 0) col = 0; myColor.color = col; item.transform.colorTransform = myColor; } function setRandomColor(item:DisplayObject):void{ setColor(item, (Math.floor(Math.random() * 16777215))); } function parseBoolean(str:String):Boolean { switch(str.toLowerCase()) { // Check for true values case “1”: case “true”: case “yes”: return true; // Check for false values case “0”: case “false”: case “no”: return false; // If all else fails cast string default: return Boolean(str); } } [/cc]

Tutorial to Create a Responsive Image Scroller in ActionScript 3.0

responsive-images-scroller-as3-thumb

I’ve written a tutorial which is published over at flash.tutsplus. This tutorial demonstrates how to create a horizontally scrolling image viewer and covers xml parsing, loading and resizing external images, and creating intuitive and responsive scrolling!

[kml_flashembed publishmethod=”dynamic” fversion=”9.0.0″ movie=”https://circlecube.com/circlecube/wp-content/uploads/sites/10/2009/07/image-scroller-example.swf” width=”550″ height=”137″ targetclass=”flashmovie”]

Get Adobe Flash player

[/kml_flashembed]

So check out the Tutorial to Create a Responsive Image Scroller in ActionScript 3.0 over at flash.tutsplus.com!

sourcedemomilestone

You’ll find full source code available for download as well as the demo files and step by step milestones all throughout the tutorial.

Forthcoming Actionscript Image Scroller Tutorial

image-scroller-thumbnail

Here is a preview of a file I’m writing a tutorial for. It’s nothing groundbreaking, but it deals with many normal tasks and will show my process a bit. This tutorial will show how to create a horizontally scrolling image viewer. It will cover xml loading & parsing, loading & resizing external images to fit into a scrollable container, and creating intuitive and responsive scrolling!

[kml_flashembed publishmethod=”dynamic” fversion=”9.0.0″ movie=”https://circlecube.com/circlecube/wp-content/uploads/sites/10/2009/07/image-scroller-example.swf” width=”550″ height=”137″ targetclass=”flashmovie”]

Get Adobe Flash player

[/kml_flashembed]

Let me know what you think, and if there’s anything you want specifically mentioned/explained in it I’ll do my best! Or if you have any ideas of how this could be improved.

Update: The article/tutorial has now been published follow the link to theTutorial to Create a Responsive Image Scroller in ActionScript 3.0

Flash Video Issue: loadbar (size) vs playbar (time) usability

This deals with some issues I’m having with the seekbar of a player. The seekbar is the area that displays the video time as a bar that shows your current position/percentage of the video, it can also display the loaded portion of the video among other things as well. Including the video players I’ve made, most player code seems to use bytesLoded / bytesTotal to calculate the amount loaded and display in the loadbar (or whatever you call it), this load bar relates to the filesize as it reads the bytes loaded out of the total. In this same scrub bar area, I like to display the current video time in the playbar as the currentTime / totalTime, notice that this relates to the time and not the file size.
seekbars
Since video is usually a variable bit rate, the loadbar (size) and the playbar (time) are not representing the same data of the video. Let’s consider an extreme example case video that consists of a first half containing live action with lots of colors and motion while the second half is a still image black and white slideshow. Understandably the first half of the video will be larger in file size than the second half, even though they each represent the same duration or half of a video… So the first half of the loadbar (size) would not correctly represent the first half of the playbar (time). So the user who watching the video load to the half point, and scrubbing to halfway through the video by clicking the load bar will see errors… The player will not be able to play the halfway (time) yet because that time is not yet loaded, even though the file is halfway loaded (size). So if we allow scrubbing through the video by clicking on the loadbar, there is a good chance that the user experience suffers because the loadbar (size) and playbar (time) are not interchangeable
Calculating display bar actionscript code:
[cc lang=”actionscript”]
//bar is display bar mc
//bar.bg.width is used as a constant to scale the percentage to the full bar width
bar.sizebar.width = (ns.bytesLoaded / ns.bytesTotal) * bar.bg.width;
bar.timebar.width = (ns.time / duration) * bar.bg.width;
[/cc]
Scrub on click actionscript code:
[cc lang=”actionscript”]
//calculate from percentage of bar width to time for seeking to
jumpSeekTo = (bar.mouseX / bar.bg.width) * duration;
ns.seek(jumpSeekTo);
[/cc]

A possible simple solution I’ve thought of is to just display a loading graphic if they click a time which has not yet loaded, but that seems counter intuitive and backwards, since the load bar would display that time as having being loaded.

I have not seen anything in documentation or anywhere online that suggests any other way to display the amount loaded which would represent the amount of TIME loaded rather than SIZE. Is there a way to know what time has loaded in the video and display that in the loadbar rather than display the percent of kb loaded?

Can anyone see something I am missing?

P.S. I already tried a couple forums to no avail: Actionscript.org forum post and gotoandlearn forum post.

How to use fullscreen in AS3 | Stage Display State Tutorial

fullscreen_tut png
One of the best features of the flash player if you’re doing video is the fullscreen functionality. It has been a question I’ve heard repeatedly. There are limits to what you can do in fullscreen. Such as minimal keyboard support while in fullscreen. But it is perfect for a video player! Who doesn’t want to see a video expanded to full screen mode?

There are a couple things to consider when coding fullscreen into your flash. Remember the hard coded “Press Esc to exit full screen mode.” that Adobe has placed into the flash player. This is untouchable by developers, and the function returns to normal stage display state. So we call the function to go fullscreen, but the exit fullscreen has already been written for us. This can pose a problem though, when we need the player to do something when we exit fullscreen, that is when we want it to do something more than the generic black box function adobe includes.

Steps

  1. specify stage properties
  2. full screen button and listeners
  3. stage fullscreenEvent listener
  4. (functions for each)
  5. allowfullscreen = true

Example

[kml_flashembed fversion=”9.0.28″ movie=”https://circlecube.com/circlecube/wp-content/uploads/sites/10/2009/03/fullscreen_tut.swf” targetclass=”flashmovie” publishmethod=”dynamic” width=”550″ height=”400″ allowfullscreen=”true”]Get Adobe Flash player

[/kml_flashembed]

1. Stage properties exist that allow us to specify what type of fullscreen we want.  We can have the swf scale to fit the fullscreen area (StageScaleMode.SHOW_ALL), not scale at all (StageScaleMode.NO_SCALE), skew to fit fullscreen (StageScaleMode.EXACT_FIT), and scale to fill fullscreen area (Stage.ScaleMode.NO_BORDER).  We may also edit the alignment of the stage in the fullscreen area; in this example I’m using TOP, but refer to documentation for more options

2. Adobe has placed restrictions on when a swf can enter fullscreen, and has deemed that it must result from a user interaction, a mouse click or keystroke. So create your buttons (or keyListeners). I prefer to have one button to enter fullscreen and another to exit, and have them both call the same function to toggle fullscreen. It gives a clearer communication to the user. I then control the visibility of these buttons depending on the current display state of the stage.

3. Another listener to watch the stage dispaly state. stage.addEventListener(FullScreenEvent.FULL_SCREEN, onFullscreenChange); This will fire every time the stage display state changes. We need this because as I mentioned earlier, when entering fullscreen we use our own function, but the ‘hit esc to exit fullscreen’ functionality is built into the flash player, we can’t update our stage layout or button visibility without watching to catch when the display state is changed. Using this method we can update our stage layout any and every time.

4. Of course flesh out the fullscreenToggle function to include anything else you need.

5. Lastly, for a SWF file embedded in an HTML page, the HTML code to embed Flash Player must include a ‘param’ tag and ’embed’ attribute with the name ‘allowFullScreen’ and value ‘true’, like this:

<object>
    ...
    <param name="allowFullScreen" value="true" />
    <embed ... allowfullscreen="true" />
</object>

The allowFullScreen tag enables full-screen mode in the player. If you do everything else right and don’t include this in your embed codes, fullscreen will not work. The default value is false if this attribute is omitted. Note the viewer must at least have Flash Player version 9,0,28,0 installed to use full-screen mode. Also note that  the simple (ctrl + enter) testing your movie in flash will not allow fullscreen either, you must use the debug tester (ctrl + shift + enter) … or go open the published swf in flash player.

Actionscript

[cc lang=”actionscript”]
stage.scaleMode = StageScaleMode.SHOW_ALL;
stage.align = StageAlign.TOP;

var stageDisplayAdjustCounter:uint = 0;

fsb.addEventListener(MouseEvent.CLICK, fullscreenToggle);
ssb.addEventListener(MouseEvent.CLICK, fullscreenToggle);
stage.addEventListener(FullScreenEvent.FULL_SCREEN, onFullscreenChange);

fsb.buttonMode = true;
ssb.buttonMode = true;

//fullscreen buttons need this to adjust the stage display state.
//pressing escape to exit fullscreen bypasses this function
function fullscreenToggle(e:MouseEvent = null):void {
status.appendText(stageDisplayAdjustCounter+”. fullscreenToggle from “+stage.displayState+”\n”);
//normal mode, enter fullscreen mode
if (stage.displayState == StageDisplayState.NORMAL){
//set stage display state
stage.displayState = StageDisplayState.FULL_SCREEN;
}
//fullscreen mode, enter normal mode
else if (stage.displayState == StageDisplayState.FULL_SCREEN){
//set stage display state
stage.displayState = StageDisplayState.NORMAL;
}
//here we subtract 1 from the counter because it has already incremented (in onFullscreenChange) when we set the display state above

status.appendText((stageDisplayAdjustCounter-1)+”. fullscreenToggle to “+stage.displayState+”\n”);
status.scrollV = status.maxScrollV;

}

//this function is called every and anytime the stage display state is adjusted
//either by pressing our buttons or
function onFullscreenChange(e:FullScreenEvent = null):void {
status.appendText(stageDisplayAdjustCounter+”. onFullscreenChange\n”);
status.scrollV = status.maxScrollV;
if (stage.displayState == StageDisplayState.FULL_SCREEN) {
fsb.visible = false;
ssb.visible = true;
}
else {
fsb.visible = true;
ssb.visible = false;
}

stageDisplayAdjustCounter++;
}

onFullscreenChange();

[/cc]

Source

Download fullscreen_tut.fla file