Hello Animation!

By Opera Software

24th April 2012: Please note

Starting with Opera 12, Opera Widgets will be turned off for new users and completely removed in a later release. If you're interested in building addons for Opera, we recommend going with our extensions platform — check out our extensions documentation to get started.

In our previous tutorial, we completed a minimal version of the Hello World! widget. While the widget works, as is, it may seem a little dull to users, since it simply displays two sides, none of which have any other interaction than the "flip" button.

We will proceed by adding a little sparkle to the widget, by creating some simple animations, using the Opera Animation library. Please note that this is just a brief introduction to the library - there is a separate document describing all the advanced features of the animation library.

This tutorial assumes that you completed the "Hello World!" tutorial. If you did not save your work, you must download the original widget, and unpack it.

Using the library

The first thing you will need to do, if you want to create nice animations in your widget, is to include the file animation.js in their project. A zip of the library is available for download.

First, begin by copying the animation.js file to your widget's root folder. Next, you will have to include this file in your project, by placing the appropriate script element into your Hello World!-widget's index.html file.

In the widget we created in the Hello World! tutorial, the head section of our widget looked like this:

<head>
  <title>Hello World!</title>
  <link rel="stylesheet" type="text/css" href="helloworld.css">
  <script type="text/javascript" src="helloworld.js"></script>
</head>

We will now change it to include the Opera Animation library:

<head>
  <title>Hello World!</title>
  <link rel="stylesheet" type="text/css" href="helloworld.css">
  <script type="text/javascript" src="animation.js"></script>
  <script type="text/javascript" src="helloworld.js"></script>
</head>

Please note that the order in which you include scripts is significant. Since we now will proceed to change the helloworld.js script from our previous incarnation of the Hello World! widget, to add the animation, it is important that the functions in already available to our animations.

The flip button

This tutorial will cover animation of the "flip" button. Where the flip button in the past simply appeared when we moused over the widget, and disappeared when we moved the mouse off our widget, we will now add some smooth fading:

  1. First, we will let the flip button fade in when you mouse over it.
  2. We will then fade the flip button to become more visible when you hover the button itself.

Changing styles

Proceed by opening the helloworld.css file from the original Hello World! tutorial. Some of the rules from that stylesheet will be unneccesary (and even conflict) with our nice JavaScript animations. Locate and delete the two following style rules, and then save the file:

body:hover .flipbutton {
	opacity: 0.3;
}

body .flipbutton:hover {
	opacity: 1.0;
}

When you have deleted these two style rules, save and close the file, and open helloworld.js instead, so we can add the behavior instead.

Preparing the widget for animation

Before we can start animating objects (elements of the markup), we will have to add the animations to the elements themselves. This is done by calling the createAnimation() method on them. For our widget, this affects the flip buttons, and they are added, by adding the following to the start of the load event for the widget.

window.addEventListener('load',function(ev){
// ... other code

// create animations for the front and back flip buttons
var frontFlipAnimation = document.getElementById('flipfront').createAnimation();
var backFlipAnimation = document.getElementById('flipback').createAnimation();
// set the speed for the animations
frontFlipAnimation.speed=10;
backFlipAnimation.speed=10;

In addition to adding the animations, we also set the speed of the animations, so they are a bit faster, by setting the .speed property of the animations we just created.

Mousing over the widget

According to the "Opera Widgets Style Guide", the flip button should be invisible when the mouse is not over the widget, and at 0.3 opacity when the mouse is over the widget. We will now add the animation to do that:

Again, inside the onload event handler, we add code for the animations themselves:

// a handler to fade in the flip button on hover over the widget
document.body.addEventListener('mouseover',function(){
  clearTimeout(buttonTimeout);
  if (parseFloat(frontFlipAnimation.style.opacity) == 0){
    // create the animation, and add an opacity fade and run it
    frontFlipAnimation.addAnimation('opacity',0,0.3).run();
    // similarily for the back side
    backFlipAnimation.addAnimation('opacity',0,0.3).run();
  }
},false);

// create an animation for whenever we move the mouse away from the widget
document.body.addEventListener('mouseout',function(){
  // create the animation, and add an opacity fade and run it
  buttonTimeout = setTimeout(fadeOut,50);
},false);

This example might seem a bit complicated, but relax. This really is quite simple:

First, we are adding event handlers to the document, so that when we mouse over, or out of the widget, we start fading in and out. Inside these event handlers we add the actual code for animating. Let's examine one line of the code in the `mouseover' handler:

frontFlipAnimation.addAnimation('opacity',0,0.3).run();

We are doing two things here:

  1. We add an animation on the CSS property opacity, and we are animating the value from 0.0 (fully transparent) to 0.3 (somewhat transparent). This is done by the addAnimation() method
  2. Then we simply run the animation, by calling run()

Delayed triggering

In our example, we are delaying the animation with 50ms, as shown on this line:

buttonTimeout = setTimeout(fadeOut,50);

We will now need to declare the buttonTimeout somewhere in our global scope. Add the following as the first line of your script:

var buttonTimeout;

Next, when we want to animate, we are calling the fadeOut function, and thus, we'll need to declare this function. Let's add it, somewhere inside our `load' event handler. This function will be called whenever you move the mouse away from the widget:

function fadeOut(){
    frontFlipAnimation.addAnimation('opacity',0.3,0).run();
    backFlipAnimation.addAnimation('opacity',0.3,0).run();
}

Voila! When you now start the widget, and mouse over the widget, the flip icon will gradually fade into view, and when you move your mouse away, it will gradually disappear.

Mousing over the flip button

The next thing we'll have to fix, is to make the flip button fully visible when we move the mouse over it, e.g. without transparency. This is done by adding event handlers to the button itself. Again, we add these inside the load event handler:

frontFlipAnimation.element.addEventListener('mouseover',function(){
  if (parseFloat(frontFlipAnimation.style.opacity) != 1){
    frontFlipAnimation.addAnimation('opacity',0.3,1.0).run();
  }
},false);

frontFlipAnimation.element.addEventListener('mouseout',function(){
  frontFlipAnimation.addAnimation('opacity',1.0,0.3).run();
},false);

backFlipAnimation.element.addEventListener('mouseover',function(){
  if (parseFloat(backFlipAnimation.style.opacity) != 1){
    backFlipAnimation.addAnimation('opacity',0.3,1.0).run();
  }
},false);

backFlipAnimation.element.addEventListener('mouseout',function(){
  backFlipAnimation.addAnimation('opacity',1.0,0.3).run();
},false);

Note that we are adding four event handlers here: One for mousing over the flip button in the main view, and one for the config view. Similarily, we add animations for moving the mouse away on both views.

Another thing worth noting is that we don't trigger animation when the opacity is already at 1 (full opacity). This is something we will need to do to prevent an unwanted extra fade when we actually click on the widget. This is signified by the if statement:

if (parseFloat(backFlipAnimation.style.opacity) != 1)

Adding flipping

The final thing we actually need to do, is to change the flip button image when we click the it. We covered this in the original tutorial, but we need to make two tiny modifications. Our previous code contained the following:

document.getElementById('flipback').addEventListener('click',function(ev){
  flipWidget("front");
}, false);

document.getElementById('frontlabel').addEventListener('change',function(ev){
  document.getElementById('hellotext').textContent = this.value;
},false);

This should be changed to:

document.getElementById('flipfront').addEventListener('click',function(ev){
  backFlipAnimation.style.opacity = 1;
  flipWidget("back");
}, false);

document.getElementById('flipback').addEventListener('click',function(ev){
  frontFlipAnimation.style.opacity = 1;
  flipWidget("front");
}, false);

What we are doing here is setting the opacity for the opposite flip button directly to 1 (full opacity), so that the flip button will appear the same after you have flipped as before. So, when we click the flip button in the main view, backFlipAnimation.style.opacity = 1; changes the opacity of the configuration view's flip button, and frontFlipAnimation.style.opacity = 1; changes the flip button on the main view when we click the config view's flip button.

Our Hello Animation! widget should now be complete with animations. You can now add your own fancy ones, or you can download the complete widget if you want to see the reference code.

This article is licensed under a Creative Commons Attribution, Non Commercial - Share Alike 2.5 license.

Comments

The forum archive of this article is still available on My Opera.

No new comments accepted.