Showing posts with label web. Show all posts
Showing posts with label web. Show all posts

Wednesday, October 27, 2010

Adobe wakes up

THIS should have been Adobe's first public response to Apple dropping Flash support. It's an HTML5 animation editor (in the prototype stage) called "Edge".

If they had announced this when Apple publicly declared they were going to drop Flash support, instead of posting petulant rants about how Apple is doomed as a result, Adobe would have looked forward-thinking, professional, capable, and supportive of their users with whatever technology they choose to deliver to. It would have saved them a lot of bad press, and it wouldn't have fostered an Apple vs. Adobe mindset (or a "dang it, I'm going to have to choose or double my work, aren't I?" mindset) among its customers.

This is the first thing to come along in years that has given me hope for Adobe's product strategy. With the standout exception of the excellent Photoshop, Adobe has been nothing but disappointing with its product decisions of late. But this is smart; it's going where the web developers are going instead of trying to drop anchor and keep us where we are for as long as possible.

Gotta give kudos to Adobe on this one; I'm already a customer of this product, if they can deliver it before a compelling alternative emerges.

Monday, August 23, 2010

Okay, this is the geekiest thing I've ever done

I've done some geeky things in my day, but then there's today.

Today, in my sci-fi tabletop roleplaying game I'm refereeing, that I wrote the rules to myself, I let my players use their iPads or iPhones to connect to a web application I wrote which emulated the actual sci-fi personal data assistant their characters use in the game world.

Let me reiterate this so it sinks in. I wrote a web application for fictional people to use on fictional devices. For a sci-fi tabletop roleplaying game. I am geek.

Here's the thing, though - it was a hit! The campaign is about unraveling a mystery about a murdered friend in a dystopian future, and this allows the players to investigate, analyze, and explore on their own, in a way that evokes the setting. The web app tracks the leads that the characters can follow up on, provides background information about the game world, and gives them a way to "receive data files" from characters. For instance, I was able to drop in new leads on-the-fly using my own iPad as they appeared in the story. It worked really well; the players were using it practically the entire time.

In fact, they're requesting new features for their in-the-game-world PDA. I'm about to get even more geeky - I'm going to be a fictional software developer responding to in-game-world software update requests... Gah!

Thursday, July 22, 2010

ADDED_TO_STAGE doesn't always fire

Flash development geekery ahead. This is mainly so I can remember the solution to this problem in the future, but maybe this will help someone else, too...

I was struggling with a problem in Actionscript 3 for two hours trying to figure out why some ADDED_TO_STAGE events weren't firing on some MovieClips I had added to some MovieClip symbols I was instantiating.

I had four identical symbols, all the same class inherited from MovieClip, added to another MovieClip symbol in the library. Each would register for an ADDED_TO_STAGE event in itself in the constructor, but when the parent MovieClip was instantiated and added to the stage, only the first of the four MovieClip would actually fire.

The solution? Instead of registering for the ADDED_TO_STAGE event in themselves, I registered in "this.parent", i.e., I would watch for when the parent MovieClip gets added instead of the MovieClip itself. It works, but doesn't seem right. What if I need to make the parent MovieClip a sub-clip of another MovieClip? Will it break again? And how do I remove the listener if the parent changes?

I like the concept of Actionscript 3, but in practice, I'm finding lots of gotchas that make development seem harder than it should be.

Wednesday, July 07, 2010

Treadsylvania is live!

Finally, the ATV safety game we created for National 4-H is live and available for the general public to play. It's called Treadsylvania, and features some fun monster-fighting action! Check it out.

Monday, June 14, 2010

Easy Depth Sorting in Actionscript 3

I'm working on an ActionScript 3 project, and I needed a way to height-sort objects on the screen (so that elements further down the screen are drawn on top of elements further back). Thanks to a little web searching and my own hacking, here's an easy solution to the problem. It's called "DepthSort Space", and it's a movie clip that depth sorts all its children each frame. Currently, it uses bubble sort on the list, but if speed is of the essence, you could probably use some other sorting mechanism.


package {

import flash.display.*;
import flash.events.*;

public class DepthSortSpace extends MovieClip {

public function DepthSortSpace() {
super();
this.addEventListener( Event.ADDED_TO_STAGE, this.addedToStage, false, 0, true );
}

private function addedToStage( e:Event ) {
this.stage.addEventListener( Event.ENTER_FRAME, this.enterFrame, false, 0, true );
}

private function sortDisplayList():void {
var len:uint = numChildren;
var i,j;
for( i=0; i < len-1; i++ )
for (j=i+1; j < len; j++)
if ( getChildAt(i).y > getChildAt(j).y ) this.swapChildrenAt( i, j );
}

private function enterFrame(e:Event) {
this.sortDisplayList();
}

}
}


To use this, just make a new symbol, and set its class to DepthSortSpace (or subclass DepthSortSpace as your movie clip if you're already adding custom code for it). Then, add any objects you want to depth sort as children of this movie clip. It will handle it automatically.

Thursday, June 10, 2010

Safari 5's New Feature

While Safari 5's new extensions feature is getting a lot of buzz, I can already tell you what my favorite new feature is: Safari reader.

Basically, when you're presented with a site that has something interesting to read, but it's all crufted up with horrible layout, ads, navigation, banners, tiny type, etc., a button appears in the URL bar. Click it, and the page fades to black, and the article, presented with nice, clean CSS, slides up for easy reading.

Predictably, some people are up in arms over this feature because it hides their precious ads. These people should listen to Lukas Mathis, who argues that if you're upset about Safari reader, then you've only got yourself to blame for it - if your site was readable, people wouldn't need to click a button to make it so.

In particular, I don't feel the need to click the reader button on Lukas' site. It would be redundant, because his site is so readable. But I've used the feature already today on a different site.

Friday, June 04, 2010

Apple's HTML5 Gallery

Apple just released an HTML5 Showcase showing what's possible with the current generation of browsers (read: why the need for Flash is overstated).

I think what's clear is that Flash is still the way to go if you want to do vector-based interactive animations (i.e., games), but Flash is no longer necessary (or, at least, should be the fallback) for the things it's been used for in its most popular contexts, like video playback. That's a good thing, since video is a media type that browsers should understand, just like images, and it's in the spec. The sooner people are coding to the spec, the better.

But even the interactive animation context is under assault. With the canvas element, you can already create interactive animations using bitmap graphics and crude vector graphics. It won't be long before HTML5 games start showing up. If Adobe wants to make the case for Flash's long-term relevance, they need to stop putting all their chips in fighting against the video tag - they lost that one when YouTube jumped - and start focusing more on staying ahead of the canvas element. Adding "real" 3D support (ala Shockwave3D) to Flash would go a long way toward that.

Or, better yet, make a Flash-like IDE for HTML5/Canvas, and migrate Flash users to that, and become the de-facto IDE for developing next-generation interactive web content just like they dominated the last generation. Unfortunately, I don't have a lot of confidence that Adobe is that forward-thinking from their track record with products like Director. But maybe.

Tuesday, April 13, 2010

We are hiring!

We're hiring at NMSU Media Productions:

Web developer - Develop web applications for NMSU internal and external clientele using PHP, MySQL, XHTML, CSS, and Javascript. If you are good at coding the back end of a web site AND good at crafting excellent UI's, we want to talk to you.

Game developer - Develop educational games, mostly using the Flash platform, although we may also be moving to Unity and Objective C (iPhone OS). Artistic skill is not as important as capability to write games and game logic code, as you will be integrating art assets by our artists and animators.

NMSU Media Productions is a great place to work - talented and personable people, fun projects, supportive management, and work that has societal benefit rather than just being for generating revenue for investors. We're located in sunny Las Cruces, and the green chile is bountiful.

Thursday, June 11, 2009

Update to MVC Framework

I've released an update to the MVC framework for developing Shockwave3D applications in Director. Changes include:
  • Models now receive the act() message each frame.
  • Fixed bug that makes demo scene not work.
  • info() gives more information, and more complete information without parameters.
  • Fixed thumbnailer to include headings on member thumbnails.
  • Added floor() and ceil() math functions.
  • Added event() and replaceController() to the Controllers object. The Controllers object is now implemented a little differently, but the API should be the same.
  • Added centerImage() imaging lingo routine.

Thursday, May 28, 2009

Online Trick-Or-Treating

Doorless Chambers is a site that organizes online trick-or-treating for virtual Disney-themed goodies from October 25 through 31. Interesting concept. I might have to participate this year, if I can come up with something decent to share.

Wednesday, November 19, 2008

Spinebreakers

Spinebreakers is a site sponsored by Penguin Books which appears to be bringing print publishing up to Web 2.0 sensibilities. It's interesting because traditional print publishers need to keep up if they don't want to become irrelevant, and Penguin Books seems to be doing the right stuff. Between initiatives like Paper Cuts, a competition to get kids to write 100 word essays on what really matters to them and collecting the best ones into a printed volume, to fantastic cover design for classic reprints, they're doing the right stuff.

(And speaking of visual design for book jackets, be sure to check out the Penguin blog, which celebrates print design with articles like this one about designing the covers for a series of horror novel reprints. Good stuff.)

Thursday, October 18, 2007

Quickly view HTTP headers

Found this little gem today. Web-Sniffer.net allows you to enter a URL and it will display the HTTP request and response header.

Friday, October 05, 2007

Creating Accessible Flash Content

WebAIM has posted an article on making Flash content accessible. Widely it is asserted that Flash is accessible, but the reality is that it's not unless you make a Herculean effort to make it so. Thus, a how-to guide is good to have.

In addition, it has a good overview of general accessibility issues for any web content, not just Flash content:
  • Hearing disabilities
    • Provide synchronized captions for any audio that conveys content
  • Photo epilepsy
    • Remove strobing content that flashes between 2 and 55 times per second
  • Motor disabilities
    • Ensure the Flash content is keyboard accessible
    • Do not require fine motor skills
  • Cognitive disabilities
    • Give users control over time sensitive content
    • Provide easy to use controls and navigation schemes
    • Be consistent
    • Use the clearest, simplest language appropriate to the content
  • Low vision
    • Provide plenty of contrast
    • Allow the Flash content to scale to a larger size
  • Blindness
    • Ensure screen reader accessibility or provide an accessible alternative
    • Ensure keyboard accessibility
    • Do not interfere with screen reader audio or keyboard commands
    • Provide textual equivalents for all non-text elements that convey content or provide a function.
This list of accessibility items is always a good thing to look at when you are faced with a site that you need to update or design. Keeps you in check when you (or someone else) is looking to get funky with AJAX, general Javascript, or Flash on the web.

Tuesday, September 11, 2007

9 JavaScript Tips You May Not Know | Ayman Hourieh's Blog

Ayman Hourieh has provided a nice overview of 9 JavaScript Tips You May Not Know. I knew almost all of these, but there were a few nuggets in there I thought were clever, such as the way to model linked lists with arithmetic, and the static local variables trick.

Preloading Both Images AND Scripts in Javascript

We've lately begun developing content for the iPhone and other mobile devices, so I'm starting to get into Javascript programming more.

For an educational game I'm building, I wanted to show a loading screen while the device is downloading all the script information over the slow EDGE network. Unfortunately, while there is a lot of information on the web about preloading images for faster response time in Javascript applications, there's not much about preloading Javascript scripts. In fact, I saw several "it can't be done" type responses.

It turns out it can be done, and quite easily, by leveraging the power of Prototype's AJAX calls. Because Prototype will eval() any AJAX response that comes back with a Javascript MIME type, you can essentially use it to deliver your scripts, rather than using the typical <script> tag, and provide a pretty download bar as it goes.

Here's some code:

//   asset_loader.js
// This object handles all the assets for the page.

// First, the master list of application assets to preload.
// All images are considered to be optional unless required is set to 1.
// All scripts are considered to be required unless optional is set to 1.

var assets = {

// List images here.
// Each image is an associative array with:
// id: an identifier
// url: a url to load the image from (can be relative)
// required: (optional) if '1', calls failure callback
// if there is an error loading this image
// (Thus, all images default to being optional.)

images: [
{ id: 'an_image', url: 'images/an_image.png' },
{ id: 'another_image', url: 'images/another_image.png' },
{ id: 'required_image', url: 'images/important_image.png', required: 1 }
],

// List scripts here.
// Each script is an associative array with:
// id: an identifier
// url: a url to load the script from (can be relative)
// optional: (optional) if '1', does not call failure callback
// if there is an error loading this script
// (Thus, all scripts default to being required.)

scripts: [
{ id: 'required_javascript_thing', url: 'javascripts/important.js' },
{ id: 'optional_thing', url: 'javascripts/optional.js', optional: 1 }
]

};

// The preloader object.
// This object handles the job of preloading everything.
// Usage:
//
// preLoader.startLoading( preloadSuccess, preloadFailure, preloadStatus );
//
// Where:
// preloadSuccess: the function to call when preloading was successful
// preloadFailure: the function to call when preloading failed
// preloadStatus: the function to call to report status of preloading in progress
//
// Scripts grabbed in this manner are eval()'d by Prototype.

var preLoader = {
errors: { images: 0, scripts: 0 },
errortext: '',
progress: 0,
startLoading: function( completeCallback, errorCallback, statusCallback ) {
this.success = completeCallback;
this.failure = errorCallback;
this.status = statusCallback;
this.loadNextImage();
},
loadNextImage: function() {
if (this.progress >= assets.images.length) {
this.progress = 0;
this.loadNextScript();
return;
}
imageObject = new Image();
imageObject.onload = function() { preLoader.imageLoaded(); }
imageObject.onerror = function() { preLoader.imageError(); }
imageObject.src = assets.images[ this.progress ].url;
assets.images[ this.progress ].image = imageObject;
},
imageLoaded: function() {
var perc = Math.round((this.progress + 1) * 100 / assets.images.length);
assets.images[ this.progress ].success = 1;
this.preloaderMessage( perc, 'Loading Images', assets.images[ this.progress ].url );
this.progress++;
this.loadNextImage();
},
imageError: function() {
var perc = Math.round((this.progress + 1) * 100 / assets.images.length);
assets.images[ this.progress ].success = 0;
this.errors.images++;
this.errortext += '<div>Error loading ' + assets.images[ this.progress ].url + '</div>';
this.preloaderMessage( perc, 'Loading Images', assets.images[ this.progress ].url );
if (assets.images[ this.progress ].required == 1) return this.failure();
this.progress++;
this.loadNextImage();
},
loadNextScript: function() {
if (this.progress >= assets.scripts.length) {
this.progress = 0;
this.success();
return;
}
this.ajax = new Ajax.Request( assets.scripts[ this.progress ].url, {
method: 'get',
onSuccess: function(transport) {
preLoader.scriptLoaded();
},
onFailure: function(transport) {
preLoader.scriptError();
}
});
},
scriptLoaded: function() {
var perc = Math.round((this.progress + 1) * 100 / assets.scripts.length);
assets.scripts[ this.progress ].success = 1;
this.preloaderMessage( perc, 'Loading Scripts', assets.scripts[ this.progress ].url );
this.progress++;
this.loadNextScript();
},
scriptError: function() {
var perc = Math.round((this.progress + 1) * 100 / assets.scripts.length);
assets.scripts[ this.progress ].success = 0;
this.errors.scripts++;
this.errortext += '<div>Error loading ' + assets.scripts[ this.progress ].url + '</div>';
this.preloaderMessage( perc, 'Loading Scripts', assets.scripts[ this.progress ].url );
if (assets.scripts[ this.progress ].optional != 1) return this.failure();
this.progress++;
this.loadNextScript();
},
preloaderMessage: function( perc, header, msg ) {

this.status( perc, header, msg, this.errortext );

}

};


...and here's a sample usage which tries preloading the given elements, and displays a "Failure" or "Success" message depending on whether the items were successfully loaded. (In practice, you'd probably not burn out all that innerHTML each frame, but this works as a demo.)

<html>
<head>
<title>Javascript Preloading Demo</title>
<meta name="viewport" content="width=320, user-scalable=no" />
<link rel="stylesheet" href="css/main.css" type="text/css" media="screen, tv" />
<script src="javascripts/prototype.js" type="text/javascript"></script>
<script src="javascripts/game_loader.js" type="text/javascript"></script>
<script>
// <![CDATA[
// Sample preloading code.

function initialize() {
preLoader.startLoading( preloadSuccess, preloadFailure, preloadStatus );
}

function preloadStatus( perc, header, msg, errors ) {
$('preloader-message').innerHTML = '\
<div style="text-align: center; font-weight: bold; color: #999; margin-top: 80px;">' + header + '</div> \
<div style="margin: 0px 20px; border: 2px solid #00f; position: relative; height: 16px;"> \
<div style="position: absolute; left: 0px; top: 0px; width: ' + perc + '%; height: 16px; \
background-color: #008;"></div> \
<div style="position: relative; text-align: center; color: #999;">' + msg + '</div> \
</div>';
$('preloader-error').innerHTML = errors;
}

function preloadFailure() {
$('preloader').innerHTML = '<div style="text-align: center;"><h1>Failed to Load!</h1></div>';
}

function preloadSuccess() {
$('preloader').innerHTML = '<div style="text-align: center;"><h1>Success!</h1></div>';
}
// ]]>
</script>
</head>
<body onLoad="initialize();" style="border: 1px solid #666;">
<div id="preloader">
<div id="preloader-message"></div>
<div id="preloader-error"></div>
</div>
</body>
</html>


If you're not using Prototype, this same principle could be applied using a standard XMLHttpRequest.

Update

Some notes on the usage of the above code. As is typical with eval()'ed code, objects that you create in the global namespace using the above method will not persist. Depending on how you've architected your code, you may not be able to just "drop in" your Javascript and have it work.

However, this is easily remedied. All you need to do is create an object that will persist, and then attach your objects and methods to that. (This is generally a good idea anyway, rather than cluttering up the global namespace.)

For instance, you might add, to the loading script code above, a global object called "app". Then, if you wanted to add a "mainMenu" object, do "app.mainMenu = { whatever };" Since app persists, so too would app.mainMenu.



Update#2

See Andrew's comment below for an alternate method for preloading scripts. (Thanks, Andrew!)

Tuesday, July 24, 2007

There is no Fold

I have recently been called to account, in two separate occasions, for a link on a web page being "below the fold."

"Below the fold" means roughly "below the visible part of the page when it first renders." Or, "stuff you have to scroll down to see." There is an urban myth going around that you shouldn't put anything of any remote importance "below the fold," because, apparently, the web is rife with drooling morons who haven't been able to get the scroll bar to work.

The problem is that a lot of non-web-designers have somehow got it into their head that this is the ultimate litmus test on whether you have a good page design: are there any links they like "below the fold" as it is rendered on their personal computer? If so, well, why don't you go back and redo that page?

The problem with this is that there is nothing you can say to this without sounding defensive or uncooperative. If you say, "well, it's not below the fold on my computer," you're being flip. If you say, "if your content is good, they'll scroll," you're just saying that to avoid doing work (as if moving a link up the page is some Herculean task).

That's why I was glad to see this article about the myth of the fold line.

It actually goes over the research that examines the validity of the "below the fold" argument, and the research is pretty damning. Not only has research shown that scrolling been pretty much universally understood since the late nineties, but there is also evidence that the vast majority of users actually do scroll down web pages.

One juicy tidbit is that there is no fold. When you make the argument that it's dumb to base design decisions on the fold since there are so many factors that influence its position (browser, OS, browser features, browser settings, device, screen resolution, default font size, etc.), you get the argument "yeah, there will be a few pages that don't, but you can take the fold location that most users have." However, research shows that this percentage of users is about 10%. In other words, if you plan your page layout for a specific fold line, only 10% of users maximally will see that optimal design. Even if you lump in fold lines that are close together, you only account for 26%. There is no such thing as a fold line for "most" users.

But the best part of the article, actually, was in what one of the commenters on the post said. She pointed out that every novice user she's introduced to the web intuitively began scrolling without any problem, but she always sees them "back right out from a visual overload without thinking to seek lower." That's the real point here. By embracing this "fold line" nonsense, we may actually be driving people away because bad, cramped design does more to deter users than having to scroll to get to information.

Now, how do I get these armchair web designers to read this article?

Sunday, June 24, 2007

Interesting Site Statistics

I've been tracking my site statistics using Google Analytics and StatCounter for quite a while now, and I sat down tonight to really look at some of the data. It's quite interesting. Here are some fun facts about the traffic my site receives:
  • Microsoft ain't doing so well. Internet Explorer browsers only make up half of my pageviews, which is quite a bit lower market share than I had been led to believe. The other half is made up of Firefox at around 40%, and Safari taking the lion's share of the remainder.
  • Moreover, MSN search yields the merest pittance of page referrals compared to Google and Yahoo. MSN referred about 1% of pages that came in via search engines. Google referred 80%, and Yahoo about 18%. Also, MSN appears to be the least able to connect people with relevant content, because MSN yielded the lowest pages viewed per referral out of all the major search engines. (For example, AltaVista, which referred about the same number of visitors to my site, generated over five page views per visitor on average, while MSN generated barely over one. In other words, AltaVista connected me to people who were actually interested in my content, while MSN connected me with people who immediately left.)
  • If browser hits are to be believed, Mac is gaining market share. According to the browser agents, at least 12% of my traffic is coming from Macs. Granted, Mac types may be more attracted to the creative stuff featured on my site, but none of the listed incoming traffic keywords have anything to do with OS platform stuff except for searches that either list my domain (people typing my URL) or looking for software (Magic Mirror for Mac).
  • Only 20% of my traffic comes from search engines, which means that the remaining 80% of traffic comes from direct links - either people actively bookmarking my site or clicking on a link on a web page somewhere. In fact, 25% of my site visitors have no referring link, which I am guessing means bookmarked locations or referred to from other sources, like an email client.
  • My "depth of visit" statistics are odd. The graph looks like your typical falloff chart with a lot of one-page visitors, less two-page visitors, even less three-page visitors, etc. But I get a spike at the end of the chart with a lot of visitors visiting 20+ pages. Now, that's probably the effect of the "long tail" talking, but I also get a spike around 9 pages, and another spike around 16 pages. Somewhere on my site, there's about nine pages of content of interest to a group of people somewhere, and another set of sixteen pages of interest to another group of people. My guess offhand is that my ImaginEERIEing site is the sixteen, and my Shockwave3D Developer's Guide is the nine. (My home haunt page has about 30 subpages, half of which is tours of previous years and the other half being how-to's, and my Shockwave3D site has eight subpages.) I think that means that when someone finds my site who is interested in the content I offer, they consume all of it, but maybe that's reading too much into the data.
  • However, the above assumption is supported by the fact that almost 6% of my visitors spend more than an hour reading my site when they come. That's good - it means that trying to have a detailed, content-rich site is worth the effort, because people are reading it.
  • Finally, I have a pretty international audience. Only 70% of my traffic comes from the U.S. That surprised me, since I have a lot of content that is not only solely available in English, but also concerns a largely American holiday: Halloween. Still, I get a lot of hits from Asia on my Shockwave3D stuff, and I get hits from Europe on my Arkham Investigations stuff. (This latter content actually includes some localized content, thanks to the efforts of some fellow Arkham Horror fans.)
Anyway, hope you found some of these statistics interesting. I think other people who have their own web sites should share stuff like this. Do you have any interesting tidbits in your server logs to share?

Monday, May 07, 2007

IE 8 to require web designers to "opt in" to standards compliance

Microsoft is saying that IE 8 will have better standards compliance, but will require web developers to "opt in" to standards compliant page rendering.

First of all, why the #%@!? is Microsoft still planning on making a browser that intentionally renders HTML wrong?

Second, why the #%@!? is Microsoft going to make it not default to rendering pages correctly?

And finally, why the #%@!? is Microsoft going to make web developers add even more cruft to their web pages to support their design flaws?

Damn!

Don't get me wrong, I'm glad to hear that we will be able to flip a switch that says, "Oh, and tell Internet Explorer to not suck (as bad)." That is much better than having to deal with guillotines and peekaboos for hours and hours.

But really, when are they going to grow up and not assume that all web developers have the time, patience, and willingness to treat their browser as a special case? Suck it up, Microsoft! Admit your software was crap, and fix it. Don't let it continue to sit there broken, and don't force us to learn even more ways in which we have to treat IE as a special case when making a web page.

If some web developers opted to write broken pages to look nice in IE but which totally break when rendered in standards compliant browsers, then it's their own damn fault for betting on the wrong horse. Let them take on the burden of opting in to the broken renderer of IE 8.

Fix the software, Microsoft. Make it work correctly by default. Don't give us an endless stream of Backward Com-crap-ibility.

Friday, April 27, 2007

Advanced Lingo For Games released for free

Gary Rosenzweig, a skilled Director developer and active online community member, wrote a book called Advanced Lingo for Games back in 2000. The book is now out of print, and the copyright has reverted to him, so he put Advanced Lingo for Games up on the web to read for free.

The title is a bit of a misnomer, I believe, since it seems to bring newbie Director game developers up to an advanced level, but it has a lot of examples with full source code, and includes downloadable projects for your own use. Some of the content is no longer applicable to current Director development, but it looks like it will give a hobbyist who is just starting out a step up.

Kudos to Gary for being so generous with his book!

Wednesday, April 25, 2007

Clever Javascript techniques

Seven Javascript Techniques You Should Be Using Today is an interesting little article where I picked up some clever tricks I didn't know before, such as this clever little gem for using a double-bang to read and store a flag so you don't have to keep checking for DOM capability:

var w3 = !!(document.getElementById && document.createElement);

The article contains clever little blips like that and also some more design-patternsy stuff to help you constrain scope and write more efficient code. A good read.