Create Your Own Ajax effects

许都 502 0

The basic and prebuilt effects in script.aculo.us are nice, but if you really want to build something great why not investigate doing your own, homegrown, do-it-yourself effects. We’re going to show you how to take basic effects and build on them to create your own. So let’s get going.

First, download and include Prototype and script.aculo.us on your page asjavascript described in the installation instructions.

You’re ready to use the visual effects engine now! Give this short line a try:

<div onclick="Effect.Fade(this)">Fade me already!</div>

To tweak the effect, try something like this:

<div onclick="Effect.Fade(this,{duration:3})">Fade me slower!</div>

The cash register effect

You’re now ready to start building your own effects. All the pre-built effects in script.aculo.us really are about changing the style of elements, but there’s nothing to stop you from actually manipulating the contents of elements too. For our homegrown effect, we’ll do exactly that.

Say you have an online shop that uses AJAX for adding and removing products from a shopping basket. Of course, you may display a total for all the products in the basket, that gets automatically updated each time something changes. We want to give the user a clue that this total is correctly updated and reflects the current contents of the basket. You could use the Yellow Fade Technique, but we want to bring our own style in here and use something more snazzy.

So, we want to emulate the look and feel of an old cash register, and display the change in the total with a completely new homegrown effect, that dynamically adjusts the value from the old total to the new.

Have a plan

To make use of the facilities the effects engine provides, you should sit down and think about what your effect really does. The important thing is to come up with a method that renders exactly one specific frame as the effect engine will ask your method to do that.

For our cash register effect that means that for the duration of the effect, on each rendering of a frame, it should display the result of the expression start_price + (price_delta * position), where price_delta = end_price - start_priceand position refers to how far the effect is completed in a 0 to 1 range.

Example: Assume that the total currently displayed is $100.00 and we want to change that to $150.00. The value to display on position 0.5 (halfway through the effect) would be $125.00 or $100.00 + ($50.00 * 0.5) with price_delta = $150.00 - $100.00 = $50.00.

First frame (position 0):       <span id="total">$100.00</span>
Halfway-through (position 0.5): <span id="total">$125.00</span>
Last frame (position 1):        <span id="total">$150.00</span>

Effect skeleton

The visual effects engine provides a base class to build your own effects.

Effect.Base is used like this:

Effect.CashRegister = Class.create();
Object.extend(Object.extend(Effect.CashRegister.prototype,
  Effect.Base.prototype), {
    // we’ll fill this up later
});

Next, we need to tell our new effect what to do.

The initialize() method

As dicussed earlier we want to have a transition from one price to another, and

need to find out the delta before we start the effect. For convinience, we also just

want to take the value that’s displayed in the element as a starting point, so we

won’t have to remember the “old” price:

initialize: function(element, price) {
  // optional third argument “options”
  var options = arguments[2] || {};

  // $ is a shortcut for document.getElementById in Prototype
  this.element = $(element);

  // find current price and parse it without the dollar sign
  this.startPrice = parseFloat(this.element.innerHTML.substring(1));

  // set finishPrice and precalculate delta
  this.finishPrice = price;
  this.delta = (this.finishPrice-this.startPrice);

  // the start method is provided by the effects engine
  // it should be the last line in your initialize() method
  this.start(options);
},

A short note on using the innerHTML property of a DOM element here: It’s neither good nor evil, it’s just there, in all browsers. So, do use it. It’s much faster than any XML sit-ups with the DOM anyway.

The update() method

For the heavy lifting in our effect, we need to define the update() method. This method is called repeatedly by the visual effects engine for each frame to render. It get’s the position parameter which is in the range of 0 to 1.

update: function(position) {
  // calculate value and convert to dollar/cent array
  var value = (this.startPrice + (this.delta*position)).toString().split(’.');

  // ensure two digits after the comma
  var cent  = value.length==1 ? ‘00′ : (
    value[1].length == 1 ? value[1]+”0″ : value[1].substring(0,2));

  // Element.update from Prototype sets the innerHTML of an element
  Element.update(this.element, ‘$’ + value[0] + ‘.’ + cent);
}

And that’s it. Your effect is ready. To actually use it, call it by using (for example):

new Effect.CashRegister('total',150);

If you want to have a little bit of that “slow motion awe” (where you’ll notice that easing in and out is automatically applied), try:

new Effect.CashRegister('total',150,{duration:10}); 

Here’s the complete code with the comments removed.

Effect.CashRegister = Class.create();
Object.extend(Object.extend(Effect.CashRegister.prototype,
Effect.Base.prototype), {
  initialize: function(element, price) {
    var options = arguments[2] || {};
    this.element = $(element);
    this.startPrice = parseFloat(this.element.innerHTML.substring(1));
    this.finishPrice = price;
    this.delta = (this.finishPrice-this.startPrice);
    this.start(options);
  },
  update: function(position) {
    var value = (this.startPrice + (this.delta*position)).toString().split(’.');
    var cent  = value.length==1 ? ‘00′ : (
      value[1].length == 1 ? value[1]+”0″ : value[1].substring(0,2));
    Element.update(this.element, ‘$’ + value[0] + ‘.’ + cent);
  }
});

More things to explore

Of course, we’ve only scratched the surface here, so here’s a quick look at various other things waiting for discovery inside the visual effects engine:

Callbacks

At all stages while your effect runs, various callbacks can be used to do further processing. For example, if you want to issue an other effect after your effect has completed, you can use the afterFinish callback:

new Effect.CashRegister('total', 150, {
 afterFinish:function(effect){ new Effect.Highlight(effect.element) }
});

Transitions

Transitions control the easing-in and out of effects, plus can be used for some more advanced control over how an effect should render itself. See the script.aculo.us wiki for more information

Queues

Effect queues are a tool to build powerful, time-line based animation. Here’s a great tutorial.

So what are you waiting for? Get out there and start creating your own wonderful world of visual effects.

About Scriptaculous

Among other things, script.aculo.us includes a fully-featured JavaScript effects engine that provides easy-to-use visual effects on the web. The primary goal is to enable AJAX-powered sites that give visual feedback to users, who otherwise might have no clue that page updates happen behind the scenes. The second use is to make in-page interactivity smoother (for example when a hidden panel opens, it can slide out smoothly instead of just popping up).

The visual effects engine first came to life as a part of Ruby on Rails and particularily the Prototype JavaScript framework, at a time when AJAX was very fresh and the Yellow Fade Technique had a revival. For the launch of script.aculo.us in June 2005, the engine was completely rewritten to provide a solid animation framework that’s easily expandable.

If you never heard about it, have a look at the demo page in the script.aculo.us documentation wiki. For a nice use of rich in-page interactivity visit Apple’s Aperture product web site, and try the “Key Features of Aperture” box at the right of the screen (scroll down a bit to see it), and the wollzelle homepage (try the references in the portfolio section).

For usage in an web application, you might want to check out the fluxiom teaser video (most stuff in the effects engine came out of the development of fluxiom).

What you don’t have to worry about

script.aculo.us’ time-based animation framework takes

care of all the tedious background processing and advanced functionality,

so you never have to worry about things like the rendering speed of the client/browser,

easying in and out and queueing up stuff in timelines.

You’ll automatically get all sorts of tweaking options and callback functionality

to really tune the effects to your liking (of course the provided effects come with

sane defaults, so you can just drop a line of JavaScript code in and you’re all set).

Also, anything is meant to work (and does!) on Internet Explorer 6, Firefox 1.0 and later, plus Safari.

发表评论 取消回复
表情 图片 链接 代码

分享