patternjavascriptMinor
Spritesheet cut to individual frames
Viewed 0 times
framescutspritesheetindividual
Problem
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:
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 im
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:
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 im
Solution
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
Refactor the code into a general function that handles the styling
Use named constants
This will make things easier when you want to change the values.
Put everything together
If there is more common behavior, you can abstract that into a function.
Good luck!
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:
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!
Code Snippets
<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>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";
};var TIMEOUT = 300;
var INTERVAL = 600;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);Context
StackExchange Code Review Q#84839, answer score: 2
Revisions (0)
No revisions yet.