Monday, February 17, 2014

Crash Course for DIY Websites

It's hard to watch TV these days without seeing commercials for DIY website builders.  One commercial that sticks out in my mind proclaims something along the lines of "You always thought you could build a website yourself, and in fact, you can, and it's really easy with our service."

As a web designer, this is similar to saying "Rothko paintings are just squares on canvas, I can do that." or "Rappers just have computers make the music; I could do that."

The truth is, you can't.  At least, not with a lot of practice.

For evidence of this truth, look around at some of the DIY built websites.  The fact that you can intrinsically tell which ones I'm talking about already means there is a gap between professional designers and non professionals, but even still, you don't have to look far to find some neon colors, all caps text, and an over abundance of center aligned paragraphs.

Even still, using a DIY site or CMS can be beneficial for individuals or businesses that update their content frequently; it is best for the developer and business if they do not have to constantly bug a designer to add text or change photos.

This post serves as a "crash course to web design" for anyone using these services, or any WYSIWYG editor.

Information Architecture

Information architecture is the skill of organizing information so it is easy to find for your end users.
  • Navigation should be coherent and efficient.  Keep main links to a minimum, and be aware of broad vs. narrow navigation patterns.
  • Conduct adequate user research to know what are the most frequently requested content items; make them as easy as possible to access.
  • Be organized with your information.  Is the information on each page relevant to each other?  Can it be split or combined to make more sense?
  • Keep your goals in mind.  What is the sites purpose?  How can information be presented to more effectively accomplish its goals?

Resources:

Color Theory

Color theory is the selection of colors that is pleasing to the eye and psychologically appealing.
  • Stick to a limited color palette, of 3 to 4 colors.  Use an online tool to help you pick your colors.
  • Use good contrast between backgrounds and text.  This has improved dramatically in recent years, but still causes problems.  Black on white is still the best. This is bad.
  • Avoid ultra bright extremes, and opposite colors on the color wheel.
  • Remember your warm and cool colors and their effects on psychology and even physiology. 

Resources:

Content Design

Content design is designing your content to be readable on the web.
  • Use bullets; users typically scan web pages and rarely read them top to bottom.
  • Stick to left alignment.  Left-to-right language users can read more efficiently when the left margin is aligned; that way our eyes know where to return after a line.
  • Make links meaningful, and keep content relevant.  This will help improve your listing on search engines.
  • Use minimal bold our underlined text.  The less it is used, the better effect it will have.

Resources:

Overall

  • Brevity is key for the web; use only the most important information.
  • Take a minimalist approach to web design.
  • Keep your site updated.  Out of date websites scare potential customers.
  • Remember to keep your website accessible to all users of different abilities.
  • Stay educated.  Remember sites you like, and study them.  Read blogs and follow web designers on Twitter.  There is tons of information out there.

Conclusion

Hopefully this will serve as a starting place for those DIYers out there.  Don't hesitate to ask a professional developer for help; we're happy to give tips and critique for those willing to listen and improve.  

Wednesday, February 5, 2014

Connect Kentucky Award

It's been a long time since a post, but I wanted to pop in and talk about some work I've been doing.

I've been developing tour websites alongside of two historians. We're basically taking walking tours and putting them online, so you can take them with your smartphone. We've completed one site for Augusta, Kentucky. It's located at http://www.battleofaugusta.com. One is currently in the works for the City of Fort Thomas, Kentucky, and should be finished this spring.

For our work, my colleagues and I were awarded the Connect Kentucky Small Business and Technology award. The press release is located here: http://www.connectkentucky.org/_documents/CKY_TechDay2013.pdf

Thanks for reading!

Wednesday, July 10, 2013

My New Telephone

Introduction








After reading the Design of Everyday Things for the second time, I decided to go on eBay and find a Bell Systems touch tone telephone.  I won an auction for a phone, and it ended up costing $24 including shipping.  Friends and family said that it was a waste of money, but I bought it because, like Donald Norman, the author of DOET, I believe it is the embodiment of great design.  So here it is sitting on my desk, inspiring and encouraging me to strive for great design in my software development.  I wanted to share with everyone why it inspires me and what it can teach us about developing well designed software.

According to DOET


"Consider the telephone.  The early telephone evolved slowly, over several generations. It once was a most awkward devices, with handset and microphone, one held in each hand. You had to turn a crank to generate a signal that would ring the bell at the other end of the line.  Voice transmission was poor.  Over the years, improvements were slowly made in size and shape, reliability, and features that simplified its use.  The instrument was heavy and robust: drop it on the floor, and not only did it still work but you seldom lost the telephone connection.  The layout of the dial or push buttons resulted from careful experimentation in the laboratory.  The size and spacing of the keys were carefully selected to work for a wide variety of the population, including the very young and the very old.  The sounds of the telephone were also carefully designed to provide feedback.  Push a button and you heard a tone in the earphone.  Speak into the microphone, and a carefully determined percentage of your own  voice was fed back into the earphone, the better to help you regulate how loudly you were talking. The clicks, buzzes, and other noises you heard while a connection was being established provided useful indications of progress."

I love the notion he presents as good design being an evolutionary process.  It comforts me to know that every wonderfully designed website or application didn't just appear out of nothingness; we as designers are all part of a process and contribute bits and pieces to the overall advancement of  design.  There is no burden of creating the next design poster child, because responsive design, iPads, and even seemingly commonplace constructs, like the number layout on my phone, all were the result of years of slow progress.

Besides the things Norman presents, I've noticed some other design features of my phone once I got it in my hands.

Design Elements of my Phone


One Function per Control


Looking at the phone, I notice that there are 14 controls on the phone; 12 number buttons, a hang up button, and a dial on the bottom for ring volume. The phone is fairly unique in the sense that, for a fairly complex device (i.e. more complex than a potato peeler), every control maps to a single function. Each number button corresponds to entering one symbol.  The hang up button controls if the phone is active or not.  The dial controls the ring volume.  There are no secrets to the functionality of this phone, and that partly contributes to the fact that when you look at this phone, you instantly know how it is used.

I want to strive for this in my websites and applications.  When you have many functions and too few controls, you end up with ambiguous elements with mysterious functionality.  On the opposite side, you end up with many redundant controls and an unclear path for the user to accomplish their goal.  The constant balance between ambiguity and clutter is a major problem for a lot of websites and web apps;  look at the clutter of godaddy.com and the ambiguity of the fluxbox desktop environment.
 
 

Button Arrangement

 
Norman mentions this in the excerpt I provided, but I couldn't help but embellish on this point.  This is a perfect example of design that goes completely unnoticed, because it is so subtle that many people take it for granted. For a moment, consider the alternative. Try typing your phone number on a number pad 5 times as fast as you can.  Now try it on the horizontal keys on top of your keyboard.  Much slower right?  I also found that I was more error prone on a horizontal keyboard.
 
So if design elements are so subtle and taken for granted, does it really matter?  It matters a lot, because when software applications mess this particular one up, it drives me crazy.  The most obvious offender of this is the Search page on Netflix on the XBOX 360.  Here is a link to what it looks like: (image) .  Remember how bad you were at typing on a horizontal bar with your fingers?  Try it with a joy stick.  To make matters worse, Netflix searches while you are entering terms, but its slow, causing hiccups in the letter selection process.  It is horrendous.  I remember earlier versions were not like this; I can't imagine how the change ever made it past testing.

I'm not advocating strictly adhering to convention because that would be detrimental to progress.  Instead, rather than take common constructs for granted, gain a full understanding for why they are the way they are.  Chances are, there is good design at work that goes unnoticed.  This phone reminds me to notice the little things, analyze why they work or why they don't, and find creative solutions to the smallest of problems.  In the end, that is what is contributing to the evolution of design.

Requires Little Precision or Accuracy


The usage of this phone requires little physical dexterity to use.  The buttons are spaced far enough away from each other, require adequate amount of force to push (preventing accidental presses), and have a low minimum speed required for subsequent presses to be considered a string of numbers.  The handset can be easily dropped into place from a good six to eight inches above the prongs; the prongs act like funnels and guide the handset in.  This is great design because it affects an action used every time the device is used, and it is done unknowingly to the user.

Being tolerant of low precision users encompasses both those with disabilities and the elderly, who are constantly being left out in regards to technological inclusion.  Windows 8, for example, requires the user to bring the mouse to the top corner of the screen, where it is out of view, to pop up the Charm bar, where common functions are kept.  This requires a decent amount of mouse dexterity,  which is no problem for us used to website pull down menus, but what about the others?
 

Back Handle





This is one of my favorite features of the phone.  There is a little handle under the prongs to pick the phone up.  I've seen this in movies, so I tried it myself, and I realized how great this design is.  First, it acts as a forcing function when the handset is on the prongs.  When you pick up the phone like this, the handset becomes part of the handle; it cannot fall off the prongs while in transit.  The design forces this functionality.  Similarly, when the handset is off and you are presumably in a call, the prongs block the fingers from accidentally hanging up the phone.  The handle is just a little indention, so it can only be picked up one way; with the hand over the handset or prongs.

Furthermore, The handle is placed right in the center of gravity, so it pivots nicely on your fingers and is easy to pick up. Also, it is neatly hidden as not to distract from the aesthetics of the phone.  Norman seems to thing there is no possible reconciliation of good design and good aesthetics, but I believe his own example proves him wrong.

Design fundamentals like forcing functions and affordances can be implemented in software applications.  Don't let users close the application if there is unsaved work.  Blank out unavailable dates in an airline booking program.  Guide them into the desired functionality with good design.
 

Built To Last


One thing I was surprised about when I got my phone was how heavy it was.  These phones were made with high quality, metal parts so they can be dropped, slammed, and rolled.  As Norman stated, the phone is fault tolerant; if it falls off a table, the prongs protect it from hanging up on itself.  And even after all of these years, the phone still carries out its designed task flawlessly.

The implications to software are obvious.  Use quality libraries and components.  Design fault tolerance and test extensively.  Build for the future and maintain the functionality of your application.
 

Curvature of Handset


The handset is curved and designed to fit a face.  It is comfortable and can be propped up to my ear with my shoulder.  It seems to naturally fit my face, which is something most smartphones can't say.  It is easy to grip, and is obvious by its shape where I am intended to hold it.  The cord comes out the side of the phone, not the back or front, indicating a specific orientation that the handset is supposed to reside on the prongs.  All small design features, but all very important.

I'm not sure about this next point, but it seems to make sense to me.  I noticed that the speaker is concave, while the microphone is convex.  I'm sure part of this is for comfort; holding the convex side to my ear is not nearly as comfortable.  My other theory is that the concave side is meant to form a sort of seal around your ear, trapping in the sound from the speaker.  The convex side on the microphone is to reflect outside noise and pick up more direct sound from the person talking.  Again, I have no proof of this, but because of all the little details, I wouldn't be surprised if this were the case.

To me, the handset is a lesson in user centered design.  Make the app conform or "fit" your users just like the handset fits my head.  It should be easy to use and comfortable for them both mentally and physically.  Time spent  hammering out small details, although possibly unnoticed to the users, is time well spent, considering the alternative.

Conclusion


I know that was a lot to read, but there are a lot of lessons to be learned from a small, common place object like my phone.  No matter what anybody says, I see it as a good investment, as it inspires and encourages good design in everything I do.  It sits next to my monitor, always in the corner of my eye, constantly reminding that good design is timeless.
   

Monday, February 25, 2013

Web Services Using Axis2 Tutorial

SOAP Web Services with Apache Axis2

Introduction

I wrote this tutorial because there are not very many resources for teaching absolute beginners how to use a SOAP web service.  While Axis2 is a great framework, the documentation, which full of examples and sample code, is a little sparse on the explanation of simple web service functionality.  This tutorial is intended to be very descriptive, and the sample code I provide is well commented.

SOAP is a protocol that uses a standardized XML format to transfer information via web services.  Web services, in the context of this tutorial, are nothing more than a set of Java methods on an external server that can be accessed from a remote program.  SOAP was created to standardize the format of the data, making it easily accessed by many platforms and programming languages.

This tutorial was written for a Windows machine, but Axis2 is cross platform.

Writing the Service


First we will be writing the service that resides on the server. 

1.  Download and extract Axis2. 
Go to the Apache Axis2 download page and download the Binary distribution.  Extract the file to a directory.  This will be the AXIS2_HOME directory.  I extracted mine to c:\axis2-1.6.2\.  Next, you'll need to set an environment variable on your system, so add a variable called AXIS2_HOME with a value of the directory you extracted Axis2.


2.  Write the Web Service java file, compile
Now we'll want to write the web service itself.  Make a new working directory anywhere on your computer.  We will be making a Hello World example, so the service is fairly simple.  The code should look like this:

public class HelloWorldService {
    public String sayHello() {
        return "Hello World!";
    }
}


Here we've made a simple class called HelloWorldService, which is the name of the web service.  It has one method, sayHello, which will be our endpoint that our client application will access.  It takes no parameters, and simply returns "Hello World!" to the client.  Compile this file using the command:

javac -g HelloWorldService.java

You should now have a class file in your working directory alongside the source file.


3.  Use the java2wsdl script to convert it to a web service descriptor language

A Web Service Descriptor Language (WSDL) file describes how a client will interact with a web service.  You'll usually want to provide these files with your web service.  Axis2 comes with a script that converts java class files into a WSDL file.  In your working directory, run:

%AXIS2_HOME%\bin\java2wsdl -cp . -cn HelloWorldService -of HelloWorldService.wsdl


This takes the class name (HelloWorldService) and generates an output file (HelloWorldService.wsdl).


4.  Make services.xml

Services.xml is a file that describes the web service at a higher level.  Ours will look like this:

<service name="HelloWorldService" scope="application">
    <description>
        Says Hello World to you.
    </description>
    <messageReceivers>
        <messageReceiver
            mep="http://www.w3.org/2004/08/wsdl/in-only"
    class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>
        <messageReceiver
            mep="http://www.w3.org/2004/08/wsdl/in-out"
    class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
    </messageReceivers>
    <parameter name="ServiceClass">
        HelloWorldService
    </parameter>
</service>


Items to note are the name parameter in the service tag, the description tag, and the parameter ServiceClass tag.  The message receivers are java classes than handle the message sent to the server; these were the default ones, and will work fine for our simple example.

5.  Organize in directory structure, compress to jar
Now that we have all of the components for our web service, we need to organize them in a file hierarchy that Axis2 can understand and compress it into a jar.  You'll need to organize your directory like so:

- top leve working Directory (not included in jar)
    -META-INF
        -services.xml
        -HelloWorldService.wsdl
    -HelloWorldService.class

Now compress the directory into a jar.  I used the command:

jar cf HelloWorldService.aar META-INF HelloWorldService.class

Note the .aar file extension, which is what Axis2 will recognize.  This took both files in META-INF and the class file and compressed it into an jar archive. 
   
6.  Place in repository, test.

Take the .aar file you just made and drop it into AXIS2_HOME\repository\services.  Inside that directory, there should be a file called services.list.  Edit that file and add HelloWorldService.aar to the list.

Now, start the Axis2 server by running AXIS2_HOME\bin\axis2server.bat.  Assuming there are no errors, you should be able to navigate to http://localhost:8080/ and see a splash screen, showing the HelloWorldService and its one action, sayHello.  Navigating to http://localhost:8080/axis2/services/HelloWorldService?wsdl will bring up the WSDL file, and finally, navigating to http://localhost:8080/axis2/services/HelloWorldService/sayHello should bring up some XML, with Hello World! clearly visible.


If all of this works, then your simple HelloWorldService is complete!


Writing the Client


Now we will want to access this service from a Java program, so we'll need to write a client.  Axis2 provides many ways of auto generating clients using the WSDL file, but for our simple task we'll just write one from scratch using the Axis2 API.

1. Write the client code.
First, make a new directory anywhere on your computer and add this file in it.  It is our GreetMe.java client, and here is the code.

//this is a Request-Response, Blocking Client
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;

import org.apache.axiom.om.OMElement;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;

public class GreetMe {
    private static EndpointReference targetEPR = new EndpointReference("http://localhost:8080/axis2/services/HelloWorldService"); //this is the url of our endpoint.  These endpoints are listed in the wsdl:service tag.

    public static void main(String[] args) {
        try {
            OMElement payload = getsayHelloOMElement();  // get the payload, or SOAP XML request to send to server
            Options options = new Options();
            options.setTo(targetEPR); //set the end point address of the options
            options.setAction("urn:sayHello"); //tell it the action to use is sayHello

            //Blocking invocation
            ServiceClient sender = new ServiceClient(); //the ServiceClient object is provided by the Axis2 API and sends and receives the SOAP message
            sender.setOptions(options);
            OMElement result = sender.sendReceive(payload);  //send request, get the result of the payload request as a OMElement

            System.out.println(result);

        } catch (AxisFault axisFault) {
            axisFault.printStackTrace();
        }
    }
   
    public static OMElement getsayHelloOMElement() {
        OMFactory fac = OMAbstractFactory.getOMFactory();
        OMNamespace omNs = fac.createOMNamespace(
                " http://ws.apache.org/axis2", "example1"); //the xml namespace of the service.  found in the the first arg is found in the wsdl file in the wsdl:definitions tag, in the xmlns:ns parameter.  The second is the prefix, which can be pretty much anything, as its purpose is simply to prevent naming conflicts.
        OMElement method = fac.createOMElement("sayHello", omNs); //the name of the method, using the namespace.  If you didn’t write the service and don’t know the method name, it is in the WSDL file as one of the xs:element tags.
        OMElement value = fac.createOMElement("Text", omNs);
        value.addChild(fac.createOMText(value, "Axis2 Echo String ")); //here we are adding a description to the request.  We are adding a Text xml element, and adding it as a child to the method xml element.
        method.addChild(value);

        return method;
    }
}


2.  Make an ANT file
Rather than building from command line, I chose to make an Ant script to handle the classpaths and jvm options:

<project name="custom client" default="compile">
    <property name="mainDir" value="c:\axis2-1.6.2\" />  <!--The AXIS2_HOME directory -->
    <path id="axis.classpath">
        <fileset dir="${mainDir}/lib">    <!--include the jars in the AXIS2_HOME/lib directory -->
            <include name="*.jar"/>
        </fileset>
        <pathelement location="."/>        <!--also include the working directory -->
    </path>

    <target name="compile"> <!-- our compile target -->
        <delete file="GreetMe.class" />
        <javac srcdir="." destdir=".">
            <classpath refid="axis.classpath" />
        </javac>
    </target>
       
    <target name="run" depends="compile"> <!-- the run target, which first calls compile -->
        <java classname="GreetMe" classpathref="axis.classpath" fork="true"> <!-- our client class -->
            <jvmarg value="-Daxis2.repo=${mainDir}/repository"/>
            <jvmarg value="-Daxis2.xml=conf/axis2.xml"/>
            <!-- the above arguments tell the class where the repository is, which holds the configuration files.  By default, it will look for axis2.xml there, but you can also specify exactly where axis2.xml is, as seen in the second arg.  See references for details.
        </java>
    </target>
   
</project>


3.  Run the file

Make sure the Axis2 server (AXIS2_HOME/bin/axis2server.bat) is running, then use the command:

ant run

To compile and run the client.  It should output the XML seen in the browser when testing the service.  This is my output:

<ns:sayHelloResponse xmlns:ns="http://ws.apache.org/axis2"><ns:return>Hello World!</ns:return></ns:sayHelloResponse>



References:
Web Service, deploy as POJO: http://axis.apache.org/axis2/java/core/docs/userguide-buildingservices.html#deploypojo
Blocking client:  http://axis.apache.org/axis2/java/core/docs/dii.html
Repository: http://wso2.org/library/tutorials/axis2-repository

Sunday, January 27, 2013

Planes Trains and Automobiles: 3 Mobile Travel Sites

Introduction

 

A lot of websites don't need a separate mobile site, and can get by with a responsive layout and some media queries.  Travel sites, however, require a separate and usable mobile site, as many people need to check flights, bus stops, and train schedules while on the go

Before a recent trip from Cincinnati to St. Louis, I found myself browsing travel sites on my phone.  As it turns out, there is no convenient and direct means of mass transit between the two cities, but in my search, I got to survey three mobile travel sites.  Each has relatively the same functionality, so I thought it would be interesting to do a small compare and contrast.  The three sites I looked at were Southwest Airlines, Megabus, and Amtrak.  I accessed these sites via my web browser and on my Blackberry Pearl 9100 with a Wifi Connection, using the Opera Mini browser.

 What they all do well

 

All three of these avoid the most common pitfalls of most mobile sites.  First and foremost, they all load quickly, in under 1 second.  This is easily the most important to prevent bounce rates on your mobile site, and these sites accomplished this by limiting the use of images and videos.  Second, they all automatically switch to the mobile site when trying to access the main website, but allow you to switch to the full site if you choose.  This is really important, because as screen resolutions and mobile browsers improve, more people will be accessing the desktop page from their phones. 

Megabus

http://mobile.usablenet.com/mt/us.megabus.com/default.aspx?

 The Good

 

Overall, the Megabus site is a solid mobile website.  There aren't too many problems with it, but there's nothing that really stands out about it.  It uses standard HTML form controls for its interactive pages, which is good because higher end phones like the iPhone interact with them in a way most efficient for the phone, and lower end phones like mine have browsers that can handle just basic HTML.  Probably the best aspect of the mobile site is that is strips down the functionality of the site.  It only focuses on the most important actions for a person on the go:  buy a ticket, check the schedule, and check reservations.  A good rule of thumb is that a mobile site should have roughly 20% of the functionality of the main website.

The Bad

 

The bad parts about the Megabus site are largely aesthetic.  The logo takes up way too much space and serves no real purpose, especially the animated bus image.  In an environment where scrolling is annoying, its important to reserve space only functional elements.  Also, the colors just awful in general.  While blue and yellow are opposites on an HSV color wheel, on most color wheels they aren't even complementary colors.  Blue and yellow offer good contrast, which is important on smaller low resolution screens, but so do black and white, which would definitely be an improvement.  A mobile site should be usable, not promote brand identity.

Amtrak

http://m.amtrak.com/mt/www.amtrak.com/home?un_jtt_redirect

The Good

 

When going from Megabus to Amtrak, the first thing you'll notice is how much "cleaner" the site feels.  This is because the Amtrak site has a very conservative approach to space usage.  You'll notice that there isn't a lot of padding around elements, instead, they opt to use borders.  Even on my small device, the entire page fits on the screen without scrolling.  The logo is small and not intrusive, and serves the purpose of identifying the page and being the home link.  As a user, I'm able to see all of my options at once and make a decision more quickly.   Another good aspect  of the site is how they chose to deal with the large amount of Amtrak stations.  Megabus comparatively has few station, so they can lob them all into a select tag.  Amtrak opted to do a separate page, with a select box for the letter and then a list of stations.   This saves a lot of scrolling from the user, especially on a phone like mine that has no special handing of HTML forms.  While navigating separate pages can disrupt the user's attention, this seems justified to me, and it allows some additional processing without the use of Ajax.

The Bad

 

The overall usability of the Amtrak site is good, although I don't like the One Way Trip and Round Trip buttons when booking a trip.  From looking at it, can you tell which one is selected?  It may have been better to fake a tab metaphor, or use an underline or green border to indicate a selection.  While the usability is good, it fails a lot of functional requirements.  When selecting a From location, it takes you to the separate page to select stations, which is good, but upon returning, does not weed out all the invalid times, dates, and To locations.  As stated above, the separate page is an opportunity to do some additional processing.  Instead, I'm taken to an error page and have to do it all over again.  Another functional flaw is the Contact page, which is an enormous web form to send an email.  We're accessing this page from a phone; why is there no phone number?  Why do I have to type my address on my tiny phone keyboard or touchscreen?  I did check, and Amtrak does have a phone number, which is listed only their desktop page for some reason.

Southwest Airlines

https://mobile.southwest.com/p

The Good

 

The Southwest page was probably my favorite website of those surveyed.  Unlike the Amtrak page, they were more liberal with their space, and opted for a cleaner, minimalistic look at the expense of user scrolling.  To counter balance this, the Southwest page uses a very narrow and deep.  The tasks are well organized and intuitively partitioned, which keeps the page size small.   Note this could also be considered a negative aspect of the page because traversing 6 pages to get where you need to go on a slower 3g connection is pretty annoying.  Another thing I like about this site is the form organization, which gives it a very clean feel.  Unlike the other sites, they used floating elements to position labels and inputs side by side, conserving vertical space.  This can be risky, as some mobile browsers do not display floating elements correctly and the horizontal space can be limited on devices.  That being said, if it works for my Blackberry Pearl, chances are they are safe with higher end smartphones.  The forms are nicely padded and have subtle horizontal dividers to denote sections.

The Bad

 

While I do like this site, it certainly isn't perfect (no website really is, after all).  One of the biggest annoyances I had using the site is that the logo is not a link to the homepage.  By now, your logo being the home link is convention, and both of the other sites use this technique.  Southwest has a home link on the bottom of nearly every page, but not all.  Relying on the back button is bad usability.  Another qualm I have is while they have many airports, they choose to lob them all into a single select box.  A scheme like Amtrak would be far more appropriate.

Conclusion

 

Everybody knows how important page load times are to mobile sites, but there are so many other aspects of mobile website design that are often ignored, even by big corporations.  These three sites overall are very high quality, and I admit I am being a little picky on some issues, but it just goes to show that there is so much more to mobile design than load times and 100% widths.  It's important to keep in mind these questions:
  1. Am I efficiently using the limited space I have?  Are my elements organized and spaced properly?  How will this affect the vertical length of my page?
  2. Are the UI controls appropriate for their use?  Do they adequately suggest their state and value?  What differences will there be from device to device?
  3. How will average users navigate my site?  What is the information hierarchy?  Do I have too many functions on my site?
So concludes my survey of three travel sites.  Regardless of their usability, functionality, and style, none could offer me a cheap and convenient route to St. Louis, so I ended up driving.  







Sunday, December 2, 2012

New Approach to Particle Systems

As a combination web and game developer, the HTML5 canvas is something that really interests me. I had dabbled a little in programming for the canvas with Javascript, but it wasn't until I read a fantastic article about common optimizations for the canvas that I really felt inspired to write a small framework for HTML5 games. The engine has some cool features, including a tile-based collisions/physics, animation sprites, input handling, and timing. Future functionality includes sound, resource management, and possibly a AJAX server/client interaction wrapper. This is all implemented using a message based architecture. The engine is a WIP, and the feature I'd like to talk about today is the particle system. I set out to get away from the classic model of particle systems and try something new.

The Classic Model 

Generally, a particle system consists of three parts:

Particle Collection Collection
This contains a list of emitters to be drawn or updated. Also may have any adding/removing emitter logic. Sometimes this component is non existant, like in a highly object oriented architecture, where each object would control its own emitter. Even so, if an object had multiple emitters, it would have to control a list of them like this.

Particle Emitter
This spawns and controls a list of particles.  The emitter has a specified position and time to live. Because it is in charge of spawning particles, it must store the initial state of particles. The emitter must also have the constraints on particle speed, direction, and generation rate.

Particle
This is the final, smallest part of the particle system. It renders itself and also has a time to live. Updating the particle means doing any physics calculations on its position.

The Problems 

The problems with this system is that there is a lot of information passing from component to component that is largely the same. Particles themselves have a lot of data associated with them: position, velocity, acceleration, fade boolean, fade rate, gravity boolean, lifespan, image/animation. The emitter must generate all of this from: range of angle to spawn direction, jitter, and most of the elements listed above. What this usually results in is large constructor and function calls with about 10 parameters each. There are solutions to the classic model, such as using a convention over configuration approach or storing particle information in script files. These are perfectly valid solutions, and I've used the CoC solution in other projects.

My Solution

What I did was eliminate the emitter component. The particles are stored directly in a list, contain their own initial state, constraints, and data. In addition, they have a maxGeneration number and a unique ID. Every time a particle is copied, the new particle's generation is one more than the particle that spawned it, and its ID is the same as the particle that spawned it. If its generation is maxGeneration, it does not copy itself. Essentially, to start a new emitter, you just add a particle configuration object to the list. The particle collection does the rest using a queue and set. Here is some pseudo code:
for each particle in list:
    add (particle.id,particle.initial_params) to set
    update particle
    draw particle
    
for each tuple in set:
    if(tuple.params.generation < tuple.params.maxGeneration)
        make new particle(tuple.id,tuple.params,tuple.params.id+1)
    
A particle object is basically a Javascript object that specifies the behavior of the particle. It relies on resonable defaults, so it can be as big or small as you like: 
var particle1 = { 
  initialState : {x:134,y:575,v:.2,a:0}, 
  ttl : 25, 
  maxGen : 10, 
  image : "particle_red_img", 
  gravity : 0, 
  copy_per_frame : 15, 
  fade:1, 
}


Conclusion 

I think in a Javascript environment, my scheme eliminates a lot of redundant code, which is good for reducing loading times and keeping with JS coding convention. For a language like C with no built in support for sets and variable sized arrays, it is probably best to stick with the classic model. A negative to my new system is that there is some added logic in copying particles and using the set. Like anything else, it all comes down to what makes you a more efficient programmer and what is the best fit for your project.

I would love to hear other solutions or comments about how you handle particle systems.

Thursday, November 8, 2012

In The News

My recent work with the city of Augusta, www.battleofaugusta.com, was featured in an article that appeared on the Northern Kentucky University home page.  You can read the article here.