Sunday, April 26, 2009

Cheap keyword-rich domain names for sale

Yes, I am actually going to try to sell some domain names through my blog. I registered these because my registrar offered a discount when you bought five or more domain names. They're unique domain names with plenty of keywords, but I simply can't use them all. Here's the list:

They're only one hundred dollars each, and they've got plenty of valuable keywords. Why not get one for your web design, programming, or software development business?

Monday, April 6, 2009

Google Trends: A powerful market analysis tool

It's not often that I find something to do that's both educational and incredibly addictive. However, Google Trends fits that description perfectly. I could spend hours scouring the data for market trends and checking the health of websites and industries. Essentially, this free web services gives anyone free access to the market data of the most widely used search engine in the world.

After spending only five minutes gazing at all the pretty graphs, I found an interesting trend. When I looked at the data for "nintendo wii", I noticed that the graph was on a general decreasing trend. I know that the Wii's popularity has steadily increased from its release, so I was puzzled by this result. However, a look at the graph for "wii" showed a more predictable upward trend. I believe that this incongruity between the search terms is caused by the public's increasing awareness of the Wii. As more and more people learn about the Wii, fewer and fewer use its full, formal name. Of course, this conclusion is strictly speculation, but it's an interesting theory, nonetheless.

Google Trends can turn anybody into a market analysis guru with access to possibly the largest consumer interest gauge in existence. You could use this service to pick which field of interest to study in, find the next big web service wave to ride, or pitch your web service to venture capitalists. However, one thing you won't find on Google Trends is this blog. It lives up to its name.

Sunday, April 5, 2009

Social networking for lazy bums

Although I greatly enjoy software development, I don't enjoy researching of social bookmarking site interfaces just to let people share my blog's content. Luckily for me, I found AddThis, an incredibly easy-to-use social bookmark widget that's compatible with more services than I could possibly imagine. It's free to use, but you have to sign up for an account at AddThis.com before you can use it. Fortunately, that free account supposedly grants you access to analytics on who bookmarks your site and how (I haven't tried it out yet).

This free web service is an incredibly easy way to add social bookmarking to your site: I had it set up on my blog in about ten minutes. Now I've got more time to devote to real programming challenges!

Monday, March 23, 2009

DirSlideShow and MultiSlideShow

These two scripts conceal all server-side directory indexing through a JSON interface, allowing you to set the location of the target pictures through the instantiation of one of the slide shows. If you'd like to see how to use DirSlideShow and MultiSlideShow, please check out this no-jargon tutorial.

DirSlideShow

DirSlideShow takes four arguments, which are listed below.

  • newPictureDir:String — The URL of the directory containing the pictures to be displayed.
  • newslideShowID:String — The id of the HTML element to which the slide show (and possibly control buttons) will be appended.
  • newRotateDelay:Number — The time (in milliseconds) until the next picture is displayed automatically. If the user clicks on one of the control buttons, the slide show will stop progressing automatically.
  • newControlButtons:Boolean — A boolean that determines if two buttons are displayed to allow the user can control the progression of the slide show.

Below is DirSlideShow's function signature:


DirSlideShow = function(newPictureDir, newSlideShowID, newRotateDelay, newControlButtons) {

MultiSlideShow

MultiSlideShow takes two arguments:

  • newPictureDir:String — The URL of a directory which contains the picture directories.
  • newContainerID:String — The id of the HTML element to which the thumbnails will be appended.

Below is the function signature of MultiSlideShow:

MultiSlideShow = function(newPictureDir, newContainerID) {

Download

I am releasing the source code of DirSlideShow and MultiSlideShow under the Apache 2.0 license.

DirSlideShow and MultiSlideShow Source Code

Demonstrations

DirSlideShow Demo

MultiSlideShow Demo

Saturday, March 21, 2009

Two Convenient Javascript Slideshows

I've decided to share two of my most useful Javascript "classes": DirSlideShow and MultiSlideShow. These classes encapsulate the necessary server-side directory indexing so that you can use the slide shows through a pure javascript interface. In other words, they're easy to use. If you'd like to see demonstrations of DirSlideShow and MultiSlideShow or download them now to follow along, please visit their project page.

How about a demonstration?

Let's say that you have a bunch of pictures in the folder images/travelpics of your web server, and you'd like to show them off to your visitors. For this task, you should use DirSlideShow. First, you need to link the scripts to the page, like so:

<script type="text/javascript" language="Javascript" src="scripts/Loader.js"> 
</script> 
<script type="text/javascript" language="Javascript" src="scripts/DirSlideShow.js"> 
</script> 
<script type="text/javascript" language="Javascript" src="scripts/ArraySlideShow.js"> 
</script> 
<script type="text/javascript" language="Javascript" src="scripts/addevent.js"> 
</script>

Once you have access to the classes on your page, you need to create a the slide show by passing in the name of the directory that contains the pictures, the HTML element that will contain your slide show, the time between each change of picture, and whether you want the slide show to have controls. It sounds complex, but it's actually very simple:

<script type="text/javascript" language="Javascript"> 
addEvent(window, "load", init, false);
function init() {
var slideShow = new DirSlideShow("images/travelpics", "travelpicsdiv", 5000, true);
}
</script>

As long as you have an element with an id of travelpicsdiv, the script will find it and put a slide show in it containing the pictures of the directory images/travelpics. It's that simple.

What about the other one?

The other script, MultiSlideShow, is more specialized but probably more useful. For this demo, let's assume that you have taken three trips and put the photos in three separate directories: dubai, honolulu, and newyork. Then, you put all three directories into the directory images. Before you could create a MultiSlideShow, you would have to link to the scripts:

<script type="text/javascript" language="Javascript" src="scripts/Loader.js"> 
</script> 
<script type="text/javascript" language="Javascript" src="scripts/MultiSlideShow.js"> 
</script> 
<script type="text/javascript" language="Javascript" src="scripts/ArraySlideShow.js"> 
</script> 
<script type="text/javascript" language="Javascript" src="scripts/addevent.js"> 
</script>

You would now start a MultiSlideShow by passing only two arguments: the name of the enclosing directory, images, and the id of the div to be filled, travelpicsdiv.

<script type="text/javascript" language="Javascript"> 
addEvent(window, "load", init, false);
function init() {
var slideShow = new MultiSlideShow("images/multislideshow", "multislideshowdiv");
}
</script>

Voila! Your div, travelpicsdiv, will now be dynamically populated with the pictures in dubai, honolulu, and newyork. Once again, there's nothing left to do. Almost.

Configuration

The one assumption that these scripts make is the location of the directory-indexing script relative to the page on which the slide show resides. If your page is in the directory www and your scripts are in the directory www/scripts, the setup will work fine right out of the .zip file. However, if you put your html in a directory www/html and your scripts in a directory www/js, you'll need to do a little configuration. Don't worry; it won't hurt a bit.

There are only two variables in one file that need to be configured: dirIndexURL and htmlPageURL, which are both in scripts/Loader.js. dirIndexURL contains the URL of the script dirindex.php relative to the HTML page that contains the slideshow. htmlPageURL contains the URL of the HTML page relative to the script dirindex.php.

Let's go back to our previous example, in which the page resides in www/html and the script resides in www/js. To re-configure the script, you would replace these lines:

// URL of directory-indexing script relative to HTML page
var dirIndexURL = 'scripts/dirindex.php';
 
// URL of HTML page relative to directory-indexing script
var htmlPageURL = '../';
…with these:
// URL of directory-indexing script relative to HTML page
var dirIndexURL = '../js/dirindex.php';
 
// URL of HTML page relative to directory-indexing script
var htmlPageURL = '../html/';
Now, just reset the script tags properly:
<script type="text/javascript" language="Javascript" src="scripts/Loader.js"> 
</script> 
<script type="text/javascript" language="Javascript" src="scripts/DirSlideShow.js"> 
</script> 
<script type="text/javascript" language="Javascript" src="scripts/ArraySlideShow.js"> 
</script> 
<script type="text/javascript" language="Javascript" src="scripts/addevent.js"> 
</script>

…and set the position of the images relative to the HTML page:

<script type="text/javascript" language="Javascript"> 
addEvent(window, "load", init, false);
function init() {
var slideShow = new DirSlideShow("../images/travelpics", "travelpicsdiv", 5000, true);
}
</script>

And you're done!

I know that there are much flashier slide show scripts available for both Javascript and ActionScript with fancy transitions and flashy picture ribbons. Nevertheless, I'm almost certain that few of those scripts are as convenient, robust, and secure as this one. You can find a full description of these classes' features and usage instructions in their project page.

Thursday, March 12, 2009

I love Remember the Milk!

Remember the Milk is a free task-management web application. When you start it up, it presents you with a series of lists on which you can post tasks. You can organize your tasks with priority levels, due dates, and tags or throw 'em in a pile and use the search function to find what you're looking for. The entire service can be operated through the keyboard, which makes adding and managing tasks incredibly quick.

If you would like to have your tasks on all your calendars, you can thanks to RTM's stellar integration with Google Calendar, iGoogle, your Blackberry or Windows Mobile phone, Twitter, or even through a bookmarklet (you remember those, right?)

Probably the most surprising thing about RTM is its general applicability. I didn't think I had much use for a task manager, but now I use it constantly to keep track of my school assignments, my work projects, and whatever ideas I want to save for later. Soon, I plan to write a quick-and-dirty widget to display my list of ideas on this blog.

If you want to organize your life, or you just want to keep all your notes in one place, Remember the Milk is the web application for you. Find it at RememberTheMilk.com.

Thursday, February 5, 2009

WebPattern & ControlPanel

I've finally finished my first visually impressive AS3 project: the WebPattern class. It takes four arrays as arguments: branches, which represents the number of branches originating from each node; branchAngles, which determines the angle between the two farthest branches of a node; branchLengths, which determines the length of the branches originating at a node; and jointWidths, which governs the width of the branches where they connect at a node. If you don't understand my explanation, you can check out a demo.

Here are a couple of warnings before you start fiddling. First, this program is relatively processor intensive, because each new layer of branches dramatically increases processing time. If you want a pattern with five layers, you had better make sure that none of the nodes has more than five branches. This program will kill your computer if you aren't careful.

Second, all of the arrays you pass in as arguments have to be the same length. Otherwise, you'll get silent failure, unless you have the debug Flash plug-in. Also make sure that all of the nodes have at least two branches and none of the other arrays have a zero in them.

WebPattern may be a unique and incredibly fun-to-play-with class, but ControlPanel is a very useful class for demoing classes and apps. That box in the top-right corner that lets you create patterns is an instance of ControlPanel. Creating that panel took only six lines of code: one for instantiation, one for each input field, and one to add it to the stage. It seals away most of the painful interface construction and data management steps.

For example, for this implementation, I had to do only three things to implement the control panel and hook it up to my web pattern drawer. First, I had to construct it:


fields = ['Branches:', 'Branch Angles', 'Branch Lengths:', 'Joint Widths:'];
defaults = ['2, 5, 3','180, 180, 60','50, 50, 50','6, 6, 2']
controlPanel = new ControlPanel('Arial');
for (var i:uint = 0, j:int = fields.length; i < j; i++) {
 controlPanel.addTextInput(fields[i], defaults[i]);
}
addChild(controlPanel);

I only used the arrays to abstract the naming of the fields; you can call it manually if you would like. Next, I added some event listeners:


controlPanel.addEventListener(ControlPanel.SUBMIT, submitListener, false, 0, true);
controlPanel.addEventListener(ControlPanel.CLOSE, closeListener, false, 0, true);

Finally, I created some listening functions. Notice how the submitListener() function only has to retrieve the data from controlPanel with data and access it through the input field names:


private function submitListener(evt:Event):void {
 destroyWebPattern();
 var arguments:Array = [];
 var rawData:Object = controlPanel.data;
 try {
  for (var i:uint = 0, j:int = fields.length; i < j; i++) {
   var fieldData:String = rawData[fields[i]];
   fieldData.replace(' ', '');
   arguments[i] = fieldData.split(',');
  }
  createWebPattern(arguments[0], arguments[1], arguments[2], arguments[3]);
 } catch (e:Error) {
  trace(e);
 }
}
  
private function closeListener(evt:Event):void {
 removeChild(controlPanel);
}

Even if you don't want to analyze that code, the lack of TextField, embedFonts, and defaultFormat should be apparent. Just remember that the ControlPanel relies on embedded fonts; make sure to embed whatever font you'd like it to use and export it for ActionScript.

Check out the demo and the source. I hope you'll have fun with my new toy and new tool.