Friday, December 13, 2013

Rotating Polymorphic Interface (RPI)

This is just an experiment. Just some fun. I doubt the practicality of such an interface, but then again, I felt compelled to create it. Its CPU intensive and won't look good if you have an older machine (IE 7 looked ok for me on my 1GB/pentium 4), but not great. Other browsers worked wonderfully. If you view it as text, of course it speeds up.

I made it a mooTools 1.2 set of classes and you can have multiple polyhedra on one page in different styles, although for simplicity I am showing one. It starts off life as a base polyhedra class, then can become a cube, a pyramid, or whatever you want! I have made a cube, a pyramid and a diamond shape, but there is no limit as long as you know the coordinates.
The buttons show how you can not only switch between text and images, but also you can morph the classes from one to another.
Aside from the core logic for making the polyhedron, here is what I added/changed:

  • Object itself or a handle can turn the cube. (its not great if you use the object itself as the handle and I have no example of this). The handle I added was the touchpad. You make it turn by clicking and dragging on the touchpad. The yellow spotlight indicates where you left off (it maps to the polyhedra).
  • If you use the ctrl key and move up or down, you can scale the entire shape.
  • Can take images as shown, or plain old text, as it was.
  • I added opacity for a more real effect for the images. (although at the moment in IE there is a small bug where opacity is not working for text).
  • You can mouseover an image for a closer view with some moo fx.
  • Click on an image to see a "details" view that I did not flesh out, its just a wireframe. I would imagine some sort of ajax request here for details. Click the image again to return it.
  • I added a scatter and a reconstruction effect.
  • Different browsers scale the images differently. Looks awesome in firefox, but not great in ie 7. Not sure what to do there.

The following options for the container are:
  • left, top: the usual, corresponds to the cube.
  • handle: the thing to manipulate.
  • polyType : a class that describes the shape.
The following options for the polyhedra are:
  • counterSpin: moves like a pilot joytick or moves naturally.
  • rotateSpeed: correlates a mousemove with a cube turn. Really its supposed to make it faster or slower, but this is so CPU intensive that its hard to notice at low numbers
  • opacity: the starting opacity.
  • spacing: space between the faces.
  • hideCenter : hides the center object if you want.
  • contents : img or text (if not images, you automatically get spans)
  • scale: Creates an arrangement of the polyFaces to the polySize overall. When you change this, you should change the default picture size, if there. Leave it at the default if your not sure
  • height, width: The usual, corresponds to each polyFace.
  • root: where to grab the images. If your showing text, use "".
  • notFound: the image or text to show if a slot is empty (I left a few).
  • data: an array of image names or text. Anything you want.

About other shapes:
This is not limited to regular shapes. Again, provided you know where to place the points, you can show and rotate any shape.

To do: make text color configurable, add example of non-regular shapes, show multiple.

The algorithm for the cube in 3 dimensions was inspired by: Thiemo M├Ąttig. The "text" version is an emulation of his work, but in this new code. This uses very little of the original code, which serves as more of an inspiration, but that core logic does drive this.

Thanks to my colleague Sualeh for his help on extending the OOP concept.

Wednesday, December 15, 2010

Why I Do it

Why I do it (by TheUiGuy)
I have an innate curiosity about the workings of the universe, and much of my time learning various subjects including science, technology, mythology, religion and recently, civics. I'm the type to complain about the design of a parking lot and ask "what was the developer thinking?" and then spend the next 20 minutes redesigning the thing.

This is why I am a User Interface Engineer for software. Because of all of man's endeavors, we are only beginning to crack the surface of true usability of this nightmarish thing called computers. My goal is to prove that usability enhancements not only improve the software and the brand-loyalty, but also contribute to user's general well-being/health and the company's bottom line.

I don't get holistic about it. I just know what its like to be on the end of a door whose designer decided to leave out all visual cues as to which way the door opens... only to push on the wrong side and have to pretend that I meant to do it, so I don't look foolish. And nobody thinks to themselves "Wow, that door designer really should have applied a visual cue to the door so that people don't make asses out of themselves"... nope, its always your fault, right?

So, my philosophy is that 9 times out of 10 if a user fails a task in the physical or software world it is because the designer failed to communicate clearly. I hope to help alleviate this during my work even if it means failing once in a while.

But beyond all that, there is a massive evolution of software due - one of those "peak events" that redefine current categories of thought. It will be on the heels of a hardware evolution of the same ilk. It's difficult to say what it is, but in the next 10 years you probably will be interacting with software in a very different way, and I hope to help define the tenants of the interaction.

Sunday, March 22, 2009

Latest Freelance Website

(Unfortunately, the site is down - as of 2014. But this is the article and I will attach a screenshot once i find one)

The latest site,, is for a family friend who wanted to start a t-shirt business. I put up the first generation of the site. My goal was to have only javascript with a ratio of 10:3:1, which is beginning to be my new idea. In this case, I wanted no screen refreshes - so it required some intelligent image loading because I am relying 100% on PNG transparencies. Thus, it does not work in ie6, but that was an executive decision. I no longer support ie6.

The ratio is for every 1,000 lines of javascript (including comments and whitespace), there are about 250-300 lines of css, or less if you use more advanced selectors. Let's say 300 in case you have to be more verbose in the css. And 100 lines of html.

I know, it sounds crazy to have only 100 lines of html, but in this website, almost everything s a div. If you subtract the very basic page tags that every website has, there are only 59 lines of html.

I used to get the pngs as small as possible, the W3c validator to ensure xhtml compatibility, and i threw in google tracking, which of course ruins the validation, but i wanted it.

I also make heavy use of smart object loading, by adding the css in the head, the javascript in the bottom of the page (in a way that defers, and does not allow blocking).

I even created "shams" or what I call the scenario where you load in a lower resolution graphic for the main page (say 40k), and while the page is loading you load the higher res.

There is still too much waiting in my mind for non-cache users. Most of the waiting is for the images to load. I still have some logic to do in order to make this faster and smarter, but the difference here is in the style of loading. Like i said this website has no screen refreshes. I have to load everything at once... well, kind of. I have to load only what I need at first, then intelligently load the rest.

The actual code ratio in this case was 1,000 :: 380 :: 73

It is superfast in Chrome 1.0 and Safari 4, fast in Opera 9.6, Safari 3, IE 8, and moderately fast in firefox 3, IE7

I do not support ie6, and I did not test it in Firefox 2.0, Opera 9.5, Chrome 2.0 or other browsers yet.
The worst offender as usual was ie7. It created nasty artifacts using mooTools 1.2 effects to change opacity. It also is very slow anywhere opacity or transition effects are invoked. It also has a slower load perception since it has a different rendering scheme than firefox or safari.

The site was built using PHP on apache (very little php), javascript using JSON style, object dot notation, one global variable with closures. It uses mooTools 1.2 as a framework, and is xhtml compatible.

Friday, February 20, 2009

Select Box Factory 2.2j (improvements)

Note: the latest version is 2.2.1j, which allows for images and text in the dropdown at the same time, and allows images to appear in the toggle.

The improvements to 2.2j (also included in 2.2.1j) are explained below.

I've been tinkering with SelectBoxFactory (Help Guide) mainly because I have been getting
some feedback and want to provide some real world use cases. The tool did not come out of the box with any hooks to accept onChange events, and many people asked how they could "retrieve" the values of the dropdown.

The result is SelectBoxFactory 2.2... (or 2.2j, same thing for now - from now on always in jQuery unless someone needs it in mooTools). Its a modest improvement, but one that I think will enable more people to use it, and to me thats a more important change.

So what can you do? Based on code that is now in the internal.js file, the following examples are now available...

With selectBoxItemHook(), you can now write any code you want to run as soon as someone or some code selects an item in the select box. This applies to dropdowns and single-select items. Its very simple, but entirely critical, since this interface is not exposed to the external world. Now it is.

With gatherAllChoices() I show how you can use the method _gatherChoices(type) to collect values from a particular dropdown. Because you may have various data requirements, the type argument can be any delimiter, or "array" as text, or "json" as text. The output of selections will come in that format. The purpose of gatherAllChoices() is to show that you can create one place where all dropdowns on the screen are collected (say, as part of a form).

When you call externalClick, a new event on the dropdown, it will cause the dropdown to make a selection for you but it won't cause the dropdown to open and close, which it would do, thinking that a user was touching it. Its actually an important addition if you think about it. This way you can make programmatic calls using selectBoxItemChooser(), another demo. selectBoxItemChooser is an example of code you might write that will select items for you based on another component. (The example here is a month button on a calendar that when pressed, triggers selects the next month in the dropdown for the user).

This is just the start of the use cases, and it is small, but the changes i made to the codebase are powerful and should enable you to really take these to the next step. See the updated sections in the (Help Guide) for more information.

Friday, October 3, 2008

Huge performance boost during iterations

I've improved my code to the point during this latest round of optimizations, that I can get Safari 3.1 to load 4,356 divs (each with a few attached events, and 5 attributes, including styling) - to load in 657 milliseconds (.15 ms per item)

The status of my system at the time was a 50% memory allocation (of 1 GB), iTunes running, a text editor running, and the one browser. No heavy background services were running (polling).

Give it a try below and help me test! Please send me your results... :) To be fair, try closing down your apps and let ONE browser test at a time, with ONE tab. Don't let other processes get in the way. This will be the cleanest number.

If you get different results than me, or if the documentFragment results are slower, then don't freak out. Although its unlikely that this would happen, remember there is an entire world of variables to consider that make this kind of testing tough to streamline. Thats why I am exposing this and want your help.

FYI: The mouseover event does exist in both tests, and is being allocated, even if the addOption test doesn't mouseover with any visual changes. These samples are both in their own iframes, to ensure no preference.

  • You can perform two kinds of tests with both these boxes.
  1. The first is to put a large number into the box and run each. Then jot the results and refresh. (The first test simulates how a user would feel when a page loads and they have to wait for contents to render.)
  2. The second test is one where you load the boxes with a reasonable number, (say 100), then keep loading over and over again without refreshing. (The second test simulates an interface where a user is tasked with "adding elements" throughout their session. How does the box respond?)

Safari is by far the fastest rendering engine (all rendering engines are not the same! Google Chrome has added elements to their rendering engine, alongside webkit, that make it just slightly slower than Safari in the current 0.2. At least in my tests).

With this test I am creating divs that emulate a select box set of options. The top is my current performance, and the bottom is simply using addOption() to append native options to a select box in the DOM (I've tested this a dozen times in all, 10 times each browser (120 tests), ask me for the complete results and I will send.):

504 items:

Firefox 3 (me) : 198 ms (.4 ms per item avg)
Firefox 3 (native addOption) : 358 ms (.7 ms per item avg)

Opera 9.5 (me) : 177 ms (.4 ms per div)
Opera 9.5 (native addOption) : 136 ms (.3 ms per div avg)

Safari 3.1 (me) : 78 ms (.2 ms per item)
Safari 3.1 (native addOption) : 50 ms (.1 ms per item avg)

Chrome .2 (me) : 203 ms (.4 ms per item)
Chrome .2 (native addOption) : 416 ms (.8 ms per item avg)

Ie7 (me) : 359 ms (.7 ms per item)
Ie7 (native addOption) : 382 ms (.8 ms per item avg)

The key to all of this is when and where. If you write your methods correctly, you can massage where code is invoked, and when to push your performance over the edge.

1. When it comes to large scale iterations, don't use the toolkit DOM methods to create and insert the bulk of your objects.
  • I know, it's crazy. But hear me out. There are pain points somewhere in your application where things slow down when using a toolkit. What I am saying here is that during the page load, or when returning an ajax response of 150 divs (e.g.) - don't use the toolkit to wrap these up just to get special features.
  • You can use the toolkit to iterate, but during that iteration, separate out the methods to help minimize the dirtiness. Inside those methods, get dirty and write plain old javascript for a huge performance boost* (see below to see more of what I mean here).
  • Meaning, don't use the append, create or addevent (bind) methods (see more detail below), but use everything else (createElement, onmouseover = function, setAttribute). You can certainly use these for most of your operations, sure, and that's the point of a toolkit. But not for these heavy iterations!
  • Create your own internal "shadow" array in memory of these objects with its base styling and base events, then, when the DOM has rendered, and for the rest of your application, wrap jQuery (or new Elements $) around your items and proceed as normal to style and add effects - or wait for just the right time to invoke these styles and events.
2. Use a documentFragment when creating elements.
  • documentFragment is your #1 friend. Instead of appending to the DOM at the end of every iteration, append to a documentFragment Element, then lastly, append the documentFragment element to the DOM.
  • This works 3x faster because it is all kept in memory - not in the DOM, where rendering is slow. It is added to the DOM later and without any effort on your part, the documentFragment melts away.
  • This has been around for years and supported by all browsers.
3. Use very short custom attribute names.
  • Except for id, className and title, make your custom attribute names be 2 characters or less. This will shave many milliseconds off your rendering time.
4. Bind Events within Events
  • Did you know that if you really plan, that you only have to bind one event to an object? Yes, the mouseover event! Inside that event, bind the rest of your events conditionally. Why pay that price over and over again during iterations?
5. Add classes and styling carefully. (IE can choke)
  • Here is where things get hairy in IE, but if you must make ie run faster, then do this: Set the className (or "class" in non-ie browsers) by hand using setAttribute. Faster than any toolkits "addclass". Don't even use the item.className = class. Just use setAttribute.
6. For ie, use innerText, not createTextNode
  • to inject text. I saved 30-80 ms per item doing this
7. Use Native events like onmouseover = function()
  • ...not toolkit addEvents or bind. Except for the little trick I mentioned above, don't bind or addEvent() during heavy iterations.
*What I mean by dirty: I mean writing plain old javascript. And by "inside these methods" I assume that you are using some kind of OOP-like style and have separated your methods too keep them small and to make sure they do one thing well. That being the case, I assume that during an iteration, you have one method for just attaching events. Its in here that you "get dirty" and write plain old javascript.

  • Aside from the two types of tests, you need to test both types of boxes. One uses documentFragment technique, and one uses addOption by comparison.
  • Note: if you get the "browser / script is running too error" let me know. The documentFragment test works differently in different browsers, but the addOption test can't handle large numbers! Another testament to using documentFragment.
  • Note: if you want to see how I did the tests, please grab the js file in the source. If you want an explanation of what I did, please comment and I will give much more detail (probably not necessary for this).
If you want to see examples I will definitely share!

Tuesday, September 23, 2008

Select Box Factory 2.1 (with graph)

I guess I can't leave well enough alone, but once i saw the css graphs on this page, I had to figure out a way to use them. Have a look by clicking the graph icon, then mouse over the bars and labels. Then, starting loading in different colors and watch the graph grow. (removal is shown in help guide).

The thing to realize is that this is by no means a static graph. It is always accurate to the states and numbers of items in the select box (even if you add or remove items).

Granted, it took some time even beyond that demo to get the css to work. I had to deal with max-height, and list-style-type, and it took some time to wire the logic into this chart, but the results are enjoyable. The demo here is relatively positioned, but you can tell this graph and even the dropdown (or a mix) to be absolute, and it will coast over the text instead of pushing it aside. I have it relative for the demo.

The way I have this written, and with the options I added, you can use any labels and build up to 5 states, which hopefully is plenty. You can use any colors too, but the css demo uses background-position for the colors, so you will need to update a very small image. I will be building a skinning set so you can simply choose your color theme and away you go -that is not there yet.

The graphs are the default css colors and image from the site, but they are configurable, and the labels are no longer built into the image.

help guide

Sunday, September 21, 2008

Select Box Factory 2.0 for jQuery

Note: Interested in show a bar chart? Try Select Box Factory 2.1 for jQuery (Help Guide & Download)

Otherwise, see 2.0 below:

Welp, i'm finally done transforming the code to be usable as a tool if you have jQuery 1.2.6+. I've spent many a week trying to perfect this in various browsers, and compiling a help guide.

Please see this link for everything you need to know.:

Select Box Factory 2.0 for jQuery (Help Guide & Download)

(give it a second to load, i've added a ton of dropdowns and code for examples in an accordion widget).