4
\$\begingroup\$

I need a hoverable transparent animation for a website, so that it glows when the mouse is over it. I could use two gifs or svgs one on top of another, but (as far as I know) there's no control of the current frame so I tried spritesheets with JavaScript and an if/else inside of every image in order to show the hovered, glowing version or the non-glowing depending on the users's mouse position.

However, there is yet another thing I tried: instead of a single spritesheet, why not cut it and put it all in the same position within a container div? They all start in display:none and they appear at the rate JavaScript tells them to. It works quite nicely. Here is my HTML:

    <div id="animation">
        <img src="frame1.png">
        <img src="frame1glow.png">
        <img src="frame2.png">
        <img src="frame2glow.png">
    </div>

There are many more frames, of course. This is the JavaScript controller (for two frames):

var animation_hovered = false;

animation.onmouseover = function(){animation_hovered = true;}
animation.onmouseout = function(){animation_hovered = false;}

window.setInterval(function(){
  if(animation_hovered == false){
  document.querySelector('#animation img:nth-child(1)').style.display = "initial";
  document.querySelector('#animation img:nth-child(4)').style.display = "none";
  document.querySelector('#animation img:nth-child(3)').style.display = "none";
  }
else{
  document.querySelector('#animation img:nth-child(2)').style.display = "initial";
  document.querySelector('#animation img:nth-child(4)').style.display = "none";
  document.querySelector('#animation img:nth-child(3)').style.display = "none";
  }
window.setTimeout(function(){
  if(animation_hovered == false){
    document.querySelector('#animation img:nth-child(3)').style.display = "initial";
    document.querySelector('#animation img:nth-child(1)').style.display = "none";
    document.querySelector('#animation img:nth-child(2)').style.display = "none";
    }
  else{
    document.querySelector('#animation img:nth-child(4)').style.display = "initial";
    document.querySelector('#animation img:nth-child(1)').style.display = "none";
    document.querySelector('#animation img:nth-child(2)').style.display = "none";        
   }
  }, 300);
}, 600);

It seems bulky, but this approach gives you absolute control over your frames and it works nicely. Also, by not using a spritesheet, you can keep your layout pretty simple (or at least a big spritesheet seems to me a bit difficult to hide in my web interface; cut it seems simpler).

Does anyone think I am doing something wrong or could be enhanced in any way?

\$\endgroup\$
1
  • \$\begingroup\$ Welcome to Code Review, I hope you get some great answers! \$\endgroup\$
    – Phrancis
    Mar 23, 2015 at 20:45

1 Answer 1

2
\$\begingroup\$

First of all, this kind of manipulation is done using CSS. E.g. http://blog.teamtreehouse.com/css-sprite-sheet-animations-steps

Nevertheless, let's see what can be improved:

Instead of nth-child selectors, use classes instead

It provides some meaning to the images, and you can replace the src easily afterwards:

<div id='animation'>
    <img class='first-frame' src='...'>
    <img class='first-frame-glow' src='...'>
    <img class='second-frame' src='...'>
    <img class='second-frame-glow' src='...'>     
</div>

Refactor the code into a general function that handles the styling

var style_switcher = function(first, second, third) {
    document.querySelector(first).style.display = "initial";
    document.querySelector(second).style.display = "none";
    document.querySelector(third).style.display = "none";
};

Use named constants

var TIMEOUT = 300;
var INTERVAL = 600;

This will make things easier when you want to change the values.

Put everything together

window.setInterval(function(){
    if(animation_hovered == false){
        style_switcher('.first-frame', '.second-frame-glow', '.second-frame');
    }else{
        style_switcher('.first-frame-glow', '.second-frame-glow', '.second-frame');
    }
    window.setTimeout(function(){
        if(animation_hovered == false){
            style_switcher('.second-frame', '.first-frame', '.first-frame-glow');
        }else{
            style_switcher('.second-frame-glow', '.first-frame', '.first-frame-glow');
        }
    }, TIMEOUT);
}, INTERVAL);

If there is more common behavior, you can abstract that into a function.

Good luck!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ To add more context to your post, instead of just saying what you should do, say why you should do it. \$\endgroup\$
    – SirPython
    Mar 23, 2015 at 22:13
  • \$\begingroup\$ Actually I can do it with pure CSS, I just realized. Anyway, I learned a lot. Thank you all! \$\endgroup\$ Mar 30, 2015 at 17:58

This site is temporarily in read-only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .