Introduction
The introduction of iPhone has given wings for the mobile phone's user interfaces to take off to new peaks. Multi-touch (Pinch), finger based operation, sliding, etc. have undoubtedly created a new era in the human-computer interaction. It is a revolutionary thought and many are inspired by these magical ideas. After Apple introduced these techniques to the public at a mass level, every phone maker is trying to 'imitate' many of these techniques in their products too. So I thought 'Why not the web user interface too grab the iPhone ideas?'. That's the enthusiasm that led me to write this project. Though it is a simple and stupid idea, it is really worth considering as it allows the user to control the way a web page is displayed.
What Can We Do With This
There are numerous things that can be done with this idea. But following are just a few tips:
- Selling Products: A site like eBay or Amazon can provide such functionality for their customers to put their product in a showcase and let the user arrange the order in which they are displayed.
- Portal Sites: Portal sites such as iGoogle or Netvibes can arrange their widgets like the icons in iPhone.
What's the Magic
Recently I came across the wonderful tools by developers at Yahoo and I fell in love with those tools after spending just a few minutes with them. They are so amazing and extremely powerful where I found that they have immense potential within. Above all they are completely free and 100% open source. Just visit http://developer.yahoo.com/ for further details and downloads. If you can devote a few minutes with these amazing YUI tools, I am sure every GUI fantasies in an iPhone can be reproduced in Web without a fuzz. It is truly astonishing. So here we go.
Working with YUI is simple. There are tons of sample code and millions of documentation. To start with, we need to first link the YUI script files in our HTML. We can either download the *.js files to our local store or we can link to Yahoo store itself. In this project, I am linking the *.js files directly from Yahoo's store.
<script type="text/javascript"
src="http://yui.yahooapis.com/2.7.0/build/yuiloader/yuiloader-min.js"/>
<script type="text/javascript"
src="http://yui.yahooapis.com/2.7.0/build/dom/dom-min.js" />
<script type="text/javascript"
src="http://yui.yahooapis.com/2.7.0/build/event/event-min.js" />
<script type="text/javascript"
src="http://yui.yahooapis.com/2.7.0/build/dragdrop/dragdrop-min.js" />
<script type="text/javascript"
src="http://yui.yahooapis.com/2.7.0/build/animation/animation-min.js" />
<script type="text/javascript"
src="http://yui.yahooapis.com/2.7.0/build/element/element-min.js" />
<script type="text/javascript"
src="http://yui.yahooapis.com/2.7.0/build/button/button-min.js" />
Then I've created 24 draggable objects as follows:
<div id="ProductItem-1" class="ProductItem">
<span class="ItemTitle">Yahoo Widgets</span><br />
<img style="float: right" src="imgs/Yahoo Widgets.png" />
<span class="ItemDesc">Yahoo Widgets.png</span>
</div>
...
<div id="ProductItem-24" class="ProductItem">
<span class="ItemTitle">Ad Aware</span><br />
<img style="float: right" src="imgs/Ad Aware.png" />
<span class="ItemDesc">Ad Aware.png</span>
</div>
And the 24 place-holders where these draggable items can dock in:
<div id="ItemBase-1" class="ItemBase"></div>
...
<div id="ItemBase-24" class="ItemBase"></div>
Note: The id
of the dragable object and id
of the placeholders. The suffix of the id
is a sequential number which I have identify which DD is in which DDTarget
.
Having the basic thing ready, now I can write the code to do the animation when the user drags an item.
When the window is loaded (i.e. on window.onload
event), the place-holders are arranged in a tabular manner which is done by the great CSS. Then the dragable items are docked in the place-holders according to the sequential order of the id
suffix.
Now the interesting part begins. Each of the place-holders is registered as the 'Drop-Target' (YAHOO.util.DDTarget
) and each product-item is registered as 'DragDrop-Item' (YAHOO.util.DD
).
new YAHOO.util.DDTarget(document.getElementById('ItemBase-X'));
new YAHOO.util.DD(document.getElementById('ProductItem-X'));
Now it's time to handle the events. When a DD item enters (event: onDragEnter
) into a DDTarget
items boundary, move the existing DD item inside the DDTarget
to the adjacent DDTarget
and move DD into adjacent repeatedly until the current DD item's original DDTarget
is reached. I know it might sound bit tricky. But it's very simple.
if(startIndex < tIndex)
{
for(var i=startIndex+1;i <= tIndex;i++)
{
setPosition(m_Store[i], i-1);
}
}
else
{
for(var i=startIndex-1;i >= tIndex;i--)
{
setPosition(m_Store[i], i+1);
}
}
...
function setPosition(el, index)
{
var Dom=YAHOO.util.Dom;
m_Store[index]=el;
var pos = Dom.getXY('ItemBase-' + (index+1).toString());
new YAHOO.util.Motion(
el.id, {
points: {
to: pos
}
},
0.3,
YAHOO.util.Easing.easeOut
).animate();
}
Note the Motion
class - an animation library by YUI. There a number of interesting animation effects.
backBoth
, backIn
, backOut
: Backtracks slightly, then reverses direction, overshoots end, then reverses and comes back to end. bounceBoth
, bounceIn
, bounceOut
: Bounces off start and end. easeBoth
, easeIn
, easeOut
: Begins slowly and decelerates towards end. elasticBoth
, elasticIn
, elasticOut
: Snap in/out elastic effect.
Similarly, I've written the code to animate when the Item is dropped into a DDTarget
(event:onDragDrop
) and when it is dropped outside a valid DDTarget
(event:onInvalidDrop
). In fact the coding is so simple and anyone can understand. Thanks to the YUI tools making life easy by giving us such nice libraries.
Points of Interest
Well this is just a static web page with some hardcoded items in it. But I am currently developing a web site which will be marketed to many financial advisors where they can customize and arrange their financial products on their home page. The customers or the end-users of their web site can further make arrangements according to their priorities. I presume, it would be a ground breaking web site and would attract many funky web lovers. Once the site goes live, I will put the URL here, so watch this space.
How to Re-use this Code
Re-using this code is easy, but I am afraid I cannot take any responsibility for any outcome of this code. The following needs to be considered in order to make it work for your circumstances.
- Any dragable item should have the class name set to
ProductItem
- There must be an empty place-holder defined for each dragable object with the class name set to
ItemBase
- The dragable object IDs should be set to '
ProductItem-X
', where 'X
' is the sequence number - Each
ItemBase
defined should have the ID in the former 'ItemBase-X
' where 'X
' is the sequence number
That's it. You are now in your fantasy island.
History
- V 1 - 08/Jul/2009 11:59 - First submission without much Technical Details
- V 2 - 08/Jul/2009 16:20 - Added more Technical Details