Your Favorite Games

Loading...

Floating Button Click Text

About this tutorial

Category: Javascript
Difficulty: Intermediate
Floating Button Click Text.zip

Results

A huge button that rewards the player with resources is a genre staple, but it can be a little boring to watch for hours on end. This tutorial will give you the basics that you need to create a cross-browser responsive solution to this problem: Floating text.

Each time the player clicks on the button, they will be rewarded, but why not give them a visual cue as well? We can create a series of functions that will give the player a piece of text randomly placed around the button to tell them how much they have been rewarded with each click. This is a pretty simple concept, but can be a little tricky to implement.

First off, we'll explain what we're about to do.

We will need to create an array for our floating text objects. This array will contain how much time they have left on screen, their unique identifying number, and the level of opacity that the object currently has. We'll also need to keep a few variables for global information, such as how long our refresh time should be, how many times our floating text will refresh (to be used in conjunction with fading), and so on.

With each second that passes, we'll need to determine whether an object has passed its lifecycle onscreen and remove it. With each new object created, we will need to find a unique identifier to give to this object so that we can interact with it later. We'll be using a few advanced array techniques here, but you should be able to catch on pretty quickly.

First things first, lets create our list of variables:

  1. function Float() { //The basic structure for our floating text display
  2. this.id = 0;
  3. this.timer = FloatTimer;
  4. this.opacity = 100;
  5. }
  6. //Timer Related Variables
  7. var FloatTimer = 3; //The time floats will stay on screen in seconds
  8. var RefreshSpeed = 10; //The number of milliseconds between refreshes
  9. var FloatIncrement = (1000 / RefreshSpeed) * FloatTimer; //The number of resfreshes per float
  10. var FadeSpeed = 350 / FloatIncrement; //The percentage at which floats fade per refresh
  11. //Float Related Variables
  12. var FloatText = "+1 Click!"; //The text for floats
  13. var Floats = []; //This array will hold all our floating text information
  14. //Timers
  15. var Timer = window.setInterval(function(){Tick()}, 1000); //A per second timer
  16. var Timer2 = window.setInterval(function(){Refresh()},RefreshSpeed); //A faster timer for display updates

Wow, that's a lot for a seemingly small function. Read the comments on each to find out what they all do. They're all pretty basic, so you shouldn't have too much trouble. Just something to note: The 350 on FadeSpeed can be adjust to change how quickly/slowly the text will fade later on. The higher the number, the faster it fades.

Next, we'll add the function to create the new object. This is a little more complex and may require a bit more digging to understand:

  1. function CreateFloat() { //Create a new floating text div
  2. //Find the lowest float ID. We start with 0 to keep with array standards. Since we will splice in later, we can simply look for
  3. //a location that has a higher ID than its array location.
  4. for (var i=0;i<Floats.length;i++) {
  5. if (Floats[i].id > i) {break;}
  6. }
  7. //Note that if the array has a length of 0, i will return as 0
  8. //Create the new float class structure and assign the ID
  9. var NewFloat = new Float();
  10. NewFloat.id = i;
  11. Floats.splice(i,0,NewFloat); //Add the new element into its appropriate place in the array
  12. //Create the new div
  13. var NewDiv = document.createElement("div");
  14. NewDiv.innerHTML = FloatText;
  15. NewDiv.className = "FloatingText";
  16. NewDiv.id = "Float" + i;
  17. //Get the max left and top as the width and height of the Clickables container
  18. //Note the 50 and 20 are the width and height of the floating divs as set in the CSS file
  19. var MaxLeft = document.getElementById("Clickables").offsetWidth - 50;
  20. var MaxHeight = document.getElementById("Clickables").offsetHeight - 20;
  21. //Randomly create a left and top value for the new div
  22. var Left = Math.round(Math.random() * MaxLeft);
  23. var Top = Math.round(Math.random() * MaxHeight);
  24. //Readjust for the maximum left and top positions
  25. if (Left > MaxLeft) {Left = MaxLeft;}
  26. if (Top > MaxHeight) {Top = MaxHeight;}
  27. //Apply the left and top figures
  28. NewDiv.style.left = Left + "px";
  29. NewDiv.style.top = Top + "px";
  30. document.getElementById("Clickables").appendChild(NewDiv);
  31. }

Again, wow, it's pretty big. The hardest part to understand, though, will be at the beginning. We start by searching our array and looking for any floating objects that have a HIGHER ID than the array location its in. This will mean that older entries have been removed from under it and that there are free IDs between it and the array location. We take the actual array location and use that as our new ID.

To maintain the structure of the array, however, we need to slot the new element into the array in the location we just found. The Splice() function will handle this for us. In this instance, it takes the array location, the number of array locations that need to be removed, and the data that we're entering in. For example, if we are using the value 7, it will move to that spot, move everything from 7 on down one spot (to 8 on) and insert our new data into 7.

After that, we create the new div, adjust a few variables for positioning (we're taking the width and height of the parent div, in this case the clickables container, and randomising), then add it to the screen. In our example, the clickables container MUST have a position of relative and our floating divs a position of absolute. Using this combination, the top, left, bottom, and right values will be based on the container rather than the screen.

The last thing we have to do is timer related. We'll first make sure that the objects are removed after 3 seconds. Remember that this value can be changed at any point by adjusting the FloatTimer variable at the top of the page.

  1. function Tick() {
  2. for (var i=0;i<Floats.length;i++) {
  3. Floats[i].timer--;
  4. //Get the element and store it in a variable for ease of use later
  5. var element = document.getElementById("Float" + Floats[i].id);
  6. if (Floats[i].timer <= 0) {
  7. //Remove the element from the display
  8. element.parentNode.removeChild(element);
  9. //Remove the item from the array. Since we're shifting a number down, we need to decrement i to cycle this particular number again.
  10. Floats.splice(i,1);
  11. i--;
  12. }
  13. }
  14. }

This is the first of two timers. It runs every second (1,000 milliseconds) and decrements the float values each time. Once the 3 seconds are up (as recorded by the timer variable in the Float class) it removes the element from the screen. We then use the Splice function again, but this time to REMOVE an item from the array. By passing the array locator and the number 1, we're telling the browser that we want to go to array location i (let's use 7 again for this example), then move 1 places INCLUSIVE towards the end of the array and remove them.

Note that we use i-- afterwards? This is because our array length is suddenly one entry shorter. We need to adjust for that, otherwise we may end up trying to call an array location that doesn't exist. If, for example, we have 1 entry at position 0, our length is 1. When we remove it, our length is now 0, but our i variable has incremented to 1, a location that doesn't exist. This may not be an issue, but lets increase our length to 2. When we remove the first, our length is down to 1, but our i variable will be incremented to 2 before we check that location. By decrementing it, we ensure that we're not missing any data.

Finally, our last function is purely cosmetic:

  1. function Refresh() {
  2. for (var i=0;i<Floats.length;i++) {
  3. //Get the element and store it in a variable for ease of use later
  4. var element = document.getElementById("Float" + Floats[i].id);
  5. //Modify the display of the float by lifting it up slightly
  6. element.style.top = (element.offsetTop - 1) + "px";
  7. //Calculate the new opacity value
  8. Floats[i].opacity -= FadeSpeed;
  9. //Apply the new opacity
  10. element.style.opacity = Math.floor(Floats[i].opacity) / 100;
  11. element.style.filter = "alpha(opacity=" + Math.floor(Floats[i].opacity) + ")";
  12. }
  13. }

This function can be called as often as you like, and is used to refresh the screen. In our case, we're using it to animate the floating text. As usual, we cycle through the existing float divs, but now we're going to modify them slightly. We still get the element into a variable to simplify things though.

By using the top style of the element, we can move it up slightly. In this case, we're moving it up by 1 px per refresh. This is updated on the screen as soon as we change the element variable. The second change is a little more complex. Remember the FadeSpeed variable from above? Well we're using it here. One could argue that we could use a simple integer value, but by calculating it, we can change the duration of the slide but keep the fade roughly the same.

We do, however, need to keep track of the opacity in a variable. This is simply to make calculating it a little easier at run time, and since we need to make 2 separate calculations to ensure cross-browser compatability. The first adjustment is to the opacity style, which is passed as a fractional number (0.9 eg). The second is the filter style, and is to allow older versions of IE to render the fading. Here, the figure must be a number out of 100 (87 eg).

So there you have it. I suggest downloading the attached file to ensure that the interface works correctly with the code before stripping it down for your own use. Note, however, that this code could be applied to all sorts of situations, and it not just limited to text. A variation of this, for example, could be to strip out the visual interface and use it to monitor trades in a civilisation game, or to randomly display clickable rewards to active users.