Creating Sophisticated Animations with the Microsoft AJAX Library

The AnimationExtender control in the ASP.NET AJAX Control Toolkit makes it easy to add animated effects to Web pages. I especially like the fact that you can compose complex animations from simple animations and use <Parallel> and <Sequence> elements to control animation order.

Much of AnimationExtender’s magic is found in a file named Animations.js, which is derived from PreviewGlitz.js in the ASP.NET AJAX Futures January CTP. I was curious to find out how difficult it would be to implement complex animations using the low-level animation classes in PreviewGlitz.js, and found that there are virtually no samples out there demonstrating how to perform anything but the most trivial animations. So I cracked open the file and went spelunking. The result is my “Balloon Pop” demo (pictured below), which you can download here. When you click a balloon, the balloon pops. The pop is really a series of animations run in parallel to simultaneously fade the balloon out and scale its width and height from 1 to 8. Once the animations are complete, a bit of JavaScript code deletes the balloon by removing the balloon image from the browser DOM.

Balloon Pop Demo

For comparison, here’s how the animation would be implemented using the ASP.NET AJAX Control Toolkit’s AnimationExtender:

<asp:Image id=”Balloon1″ ImageUrl=”~/Images/balloon.gif” runat=”server”
style=”position: absolute; left: 320px; top: 260px; width: 74px; height: 110px” />
<ajaxToolkit:AnimationExtender ID=”AnimationExtender1″ TargetControlID=”Balloon1″ Runat=”server”>
<Animations>
<OnClick>
<Sequence>
<Parallel Duration=”0.2″ Fps=”40″>
<Scale ScaleFactor=”8″ Center=”true” />
<FadeOut />
</Parallel>

function removeBalloon(id)
{
var image = $get(id);
image.parentNode.removeChild(image);  // Remove the image
}

 

It’s more difficult using the animation classes in PreviewGlitz.js. There is no equivalent of AnimationExtender’s <Parallel> element, so you create a Sys.Preview.UI.Effects.CompositeAnimation object and encapsulate all the subanimations inside it. I used NumberAnimations to simultaneously animate the width, height, x-position, and y-position of the balloon, plus a FadeAnimation to fade it out. (Makes you appreciate AnimationExtender’s ScaleAnimation, doesn’t it?) Once the CompositeAnimation has run its course, a bit of JavaScript needs to be executed to remove the balloon image from the DOM. At first glance, it appears that you can register a handler for the end event that fires when the animation is complete. However, in what is probably an oversight in the January CTP, PreviewGlitz.js’s animation classes don’t fire end events. So I set up a timer to check the animation progress and remove the image from the DOM after the animation ends. Not pretty, but it works.

Here is the key source code:

<img id=”Balloon1″ src=”Images/balloon.gif” onclick=”popBalloon(‘Balloon1’);”
style=”position: absolute; left: 320px; top: 260px; width: 74px; height: 110px” />

var _scaleFactor = 8; // Modify this number to change the scale factor
var _image, _animation;

function popBalloon(id)
{
if (_animation != null)
return; // Prevent overlapping animations
_image = $get(id);
var width = parseFloat(_image.style.width);
var height = parseFloat(_image.style.height);
var x = parseFloat(_image.style.left);
var y = parseFloat(_image.style.top);
//
// Use a CompositeAnimation object to “explode” the image by
// simultaneously scaling, moving, and fading it.
//
var a1 = new Sys.Preview.UI.Effects.NumberAnimation();
a1.set_target(_image);
a1.set_property(‘style’);
a1.set_propertyKey(‘width’);
a1.set_startValue(width);
a1.set_endValue(width * _scaleFactor);
var a2 = new Sys.Preview.UI.Effects.NumberAnimation();
a2.set_target(_image);
a2.set_property(‘style’);
a2.set_propertyKey(‘height’);
a2.set_startValue(height);
a2.set_endValue(height * _scaleFactor);
var a3 = new Sys.Preview.UI.Effects.NumberAnimation();
a3.set_target(_image);
a3.set_property(‘style’);
a3.set_propertyKey(‘left’);
a3.set_startValue(x);
a3.set_endValue(x – (width * (_scaleFactor – 1)) / 2);
var a4 = new Sys.Preview.UI.Effects.NumberAnimation();
a4.set_target(_image);
a4.set_property(‘style’);
a4.set_propertyKey(‘top’);
a4.set_startValue(y);
a4.set_endValue(y – (height * (_scaleFactor – 1)) / 2);
var a5 = new Sys.Preview.UI.Effects.FadeAnimation();
a5.set_target(new Sys.Preview.UI.Image(_image));
a5.set_effect (Sys.Preview.UI.Effects.FadeEffect.FadeOut);
_animation = new Sys.Preview.UI.Effects.CompositeAnimation();
_animation.get_animations().add(a1);
_animation.get_animations().add(a2);
_animation.get_animations().add(a3);
_animation.get_animations().add(a4);
_animation.get_animations().add(a5);
_animation.set_duration(0.2);
_animation.set_fps(40);
_animation.play();
//
// Because the animation classes in PreviewScript.js do NOT fire end
// events (even though you can register end handlers), manually set a
// timer to fire after 0.4 seconds so we can remove the image from the
// DOM once the animation is complete.
//
var timer = new Sys.Preview.Timer();
timer.initialize();
timer.set_enabled(true);
timer.set_interval(400);
timer.add_tick(removeBalloon);
}
function removeBalloon(sender)
{
if (!_animation.get_isPlaying())
{
sender.set_enabled(false);              // Disable the timer
_image.parentNode.removeChild(_image);  // Remove the image
_animation = null;
}
}

 

Understanding how to do animations with PreviewGlitz.js is more than academic. If you want to use ASP.NET AJAX to do animations on non-ASP.NET platforms such as PHP and ColdFusion, you can’t use the ASP.NET AJAX Control Toolkit because it’s ASP.NET-specific. But you can use PreviewGlitz.js. And now there’s an example to go by.

As we mentioned in our Myths post (click to read), there’s a lot of hype as well as genuine concerns about using a public cloud to power mission-critical applications, especially those with high InfoSec or compliance requirements.

Data Breaches on Our Minds

It seems everyone is paying attention to security – especially on how to prevent data breaches. From developers – who, according to a recent Veracode survey, cite preventing data breaches and cyberattacks as their #1 concern – to service providers like Verizon who recently reported that web application attacks are the #1 source of data breaches – as IT professionals, we all have such concerns on our minds.

And it’s no wonder, according to IBM and Ponemon Institute (registration required to view) typical data breaches (under 100,000 records breached) cost US-based businesses:

  • An average of $7.01 million per data breach
  • An average of $221.00 per lost or stolen record

For Atmosera, Security is our Priority

We put security in the forefront of everything we do. Our methodology – whether on public, hybrid or private cloud services – from design through deployment focuses on delivering InfoSec and Compliance solutions that are realistically implementable.

Our services span the entire computing stack, from connectivity to applications, with stringent physical and logical security controls. We employ security professionals who uphold HIPAA/HITECH + HITRUST + PCI-DSS + IRS-1075 compliance thresholds, and our technology is secured end-to-end, while being actively monitored 24x7 every day of the year.

Secure Delete Application for Azure

We also actively develop applications when there’s an opportunity for something better in the market. We recently introduced the first secure delete app for Azure storage. The application was developed in response to the growing need to deliver better assurances that data is permanently deleted from cloud deployments. It uses the US Department of Defense (DoD) 5220.22-M data sanitization method.

Since there is no way to get to the physical drive, our secure delete application targets the logical sectors of the drives and stripes all data. This is an extreme measure, but ensures your data is deleted and not recoverable.

Successfully leveraging applications in a public cloud such as Azure requires careful planning, consideration and expertise to ensure it is properly setup with InfoSec in mind.

We welcome the opportunity to connect with you and talk through your needs.

[gravityform id="2" title="false" description="false"]

We deliver solutions that accelerate the value of Azure.

Ready to experience the full power of Microsoft Azure?

Start Today

Blog Home

Stay Connected

Upcoming Events

All Events