Login or create a free accountShare your thoughts!
Billwoo Photo
Billwoo (Site Newb) wrote 9 weeks ago
I'd like to say thanks to Andrew for this excellent tutorial.

A few comments follow on what I had to do in IE8 (Win Vista) to achieve a "smooth cycling" effect (fade in, pause, fade out) between two 24 bit .png files saved from PhotoShop with transparency. The graphic content of the .png files contain a central shape (a pyramid) and anti-aliased edges.

The two graphic elements are identical in size: what varies in the content is only the color information, and some trivial variations on anti-alisasing. Only one of the elements is being faded in or out, the other is always visible. Yes: the first image could have been part of a page background, but I wanted to work with it as a separate element.

In the CSS : I found it would only work if the CSS declaration of the .png being faded used : display:hidden

In the HTML : as in Andrew's examples, I declared the div element containing the picture to be faded as id = "fade1"

In the JavaScript :

1. both pictures pre-loaded using the standard technique from the late Paleolithic.

2. in OnWindowLoad :

a. call the first fade-in :

fade('fade1', 0, 100, 8000);

b. trigger the "cycle" function to occur nine seconds later :

theWindowInterval = window.setInterval("pyramidCycle()", 9000);

c. the "cycle" function :

function pyramidCycle()
{
// fade out
fade('fade1', 100, 0, 4000);

// call fade in after four seconds
setTimeout("fade('fade1', 0, 100, 4000)", 4000);
}

Hope this is useful information.

To do ? :

1. in Andrew's code the lookup of the element style is being done with every call to 'setOpacity which is being called in every iteration of the for loop in the function 'fade : set the element's style once in a variable in OnWindowLoad and eliminate multiple look-ups ?

2. improve the "cycle" function : add a parameter for "pause after completion" of each fade-in or out ?

best, BillWoo
Andrew Photo
Andrew Johnson (ITNewb Guru) wrote 9 weeks ago
@Billwoo

My pleasure, glad it has been of some help to you. As you've seen the code doesn't do anything except provide an example (albeit not a great one) of how fading works. IE does react the worst to the code in this article, but with a few controls built in the issues you're facing can be corrected.

One issue to determine is whether or not the image you're fading in after fading out the currently visible image has already been preloaded. If it hasn't, there will be a pause while it's downloaded and then likely a jerk because the fadeIn function started before the element finished downloading.

I have some "rough" code that I used a while back that I'll message you in a few minutes. It should be enough to point you in the right direction. The reason I don't want to post it here in the comments is because it's not very clean code. There are a few articles on the site that I need to edit and improve such as this one and the intro to ajax I wrote but I've been swamped working on version 2 of this site.
Billwoo Photo
Billwoo (Site Newb) wrote 9 weeks ago
Hi Andrew,

Many thanks for this well done article. I am playing with fading between two images in IE 8, and seem to have trouble getting a smooth cycle repeating: fade in, pause, fade out.

I've tried using setTimeInterval, etc. Seems like the fade in will occur smoothly, but the fade out seems to "snap" visually and not take as long as the fade in, no matter how I set the time intervals.

Perhaps an IE related thing ?

thanks, Billwoo
Safi Photo
Safi Nassar (Site Newb) wrote 9 weeks ago
Got it, thanks again.
Andrew Photo
Andrew Johnson (ITNewb Guru) wrote 9 weeks ago
Hey Safi, thanks. Well, there are no getElementByClass, getElementByClassName or getElementsByClass. There is, however, a native getElementsByClassName() which is what jQuery for example uses when you use a selector such as $('.classname')..

This article is primarily intended to take a look at how a fade works, but it really doesn't even do a good job of that. I need to rewrite the actual fade functions so they're a bit more sophisticated and cpu friendly.

If you want to do fades and other neat things I recommend you run with a light weight version of jQuery. For the longest time I wrote all my JS from scratch and just recently I moved over to jQuery. In the upcoming ITNewb v2 I have less JS code which means smaller files to send clients and I have saved a tremendous amount of time working with JS compared to before.

I do think it is very important for us to understand JS and be able to write these things from scratch but once we're decent JS programmers using a framework is a really good idea.

If you really want to use this code or your own customized version of it, you'll have to use getElementsByClassName and then loop through the returned results appropriately just as jQuery would do.

Hope this helps :)
Safi Photo
Safi Nassar (Site Newb) wrote 9 weeks ago
Thanks, that's very helpful.

In the function getElm(eID), you used the ID attribute to make the effect work but I am trying to use the class attribute instead. So here is what i did:

I changed "getElementByID" to "getElementByClass"
(It's not necessary to change the "eID" too)
  1.  
  2. function getElm(eID) {
  3.     return document.getElementByClass(eID);
  4. }
  5.  


Here is the html code:
  1.  
  2. // img1
  3. <img class="image" src="img1" width="181" height="113"
  4. onmouseover="fade('image', 25, 100, 300)" onmouseout="fade('image', 100, 25, 300)"/>
  5. // img2
  6. <img class="image" src="img2" width="181" height="113"
  7. onmouseover="fade('image', 25, 100, 300)" onmouseout="fade('image', 100, 25, 300)"/>
  8.  


And the class used to set the default opacity value (50%) is located in a separate style sheet file.

When I try it out in one of the browsers, it shows the too images with the default opacity but the fading effect doesn't work at all.
For some reason it's not working.
Andrew Photo
Andrew Johnson (ITNewb Guru) wrote Dec 7, 2009
The problem is really just a mediocre approach on my part. There are too many iterations, running a bit too fast. As you've seen FF, Opera, Safari and so on pull it off, but IE wigs out. Nevertheless, if you watch your CPU level during a fade it will spike, which is a dead giveaway the approach has flaws.

Regarding opacity itself, this article was done well, but the fade technique needs to be improved. When I wrote a function to perform "smooth scrolls" it used step sizes, where it might jump 50px at a time. This fade technique is moving only a single percent each time the opacity changes, which is really silly on my part. Sure, it works tolerably, but I should have put more thought into it. At any rate, what the function really needs to do is have fewer executions, and each execution should change the opacity by probably 5%. I'm virtually certain IE would play nice with such a technique as well.

So I guess what I've really done is only offered "half help" regarding the fade thus far. Currently I'm on break (until Jan 1st), but once I get back to it I will rewrite the fades code and do it the way I should have done it to begin with.

Hopefully you can figure out how to write one yourself in the mean time. You may find the basic logic of the smooth scroll helpful to that end, at least as far as steps are concerned. I should also rename speed to interval so it's more clear what it does.

Cheers!
Steve Photo
Steve (Site Newb) wrote Dec 6, 2009
Many thanks for the input and advice Andrew.
The speeded up transition seems an improvement but the opacity in IE is really flakey isn't it !
I seem to be reaching the conclusion that IE and its failings are just something we have to live with...is that so?
As regards hiding the overlapped pages at the start, you seem to be right about just setting the opacity in the class without needing the onload setting.
Once again, thanks for the help.
Steve
Andrew Photo
Andrew Johnson (ITNewb Guru) wrote Dec 4, 2009
My pleasure, Steve.

You're right, the fade is a bit "laggy" in IE. For some reason, we can give FF and IE the same code and IE tends to be slow, and IE also has the issue of fuzzy text when we apply CSS opacity to certain elements.

Personally, I just avoid doing fades with IE, although I understand not everyone can go that route necessarily. The quickest bit of advice I can give you is to change the "1000" in the following line to say "300". You should get a decent result in both FF and IE this way.

  1. var speed = Math.round(1000 / 100); // what you have
  2. var speed = Math.round(300 / 100); // try this instead


Also, if your fade function doesn't have a duration parameter, you might as well just do:

  1. var speed = 3; // which is, update opacity every 3 milliseconds


Regarding duration, here is what my fade function looked like:

  1. function fade(eID, startOpacity, stopOpacity, duration) {
  2.     var speed = Math.round(duration / 100);
  3.     // rest of the code
  4. }


Regarding hiding the overlay divs with onload, what's coming to mind would be simply setting those classes with a display:none by default. You can adjust the display when needed to perform fades in the appropriate way. For what you're doing in that web page, I usually use the fadeIn and fadeOut functions because they also handle the display attribute for the target elements.

Hope this helps, and welcome to ITNewb :)
Steve Photo
Steve (Site Newb) wrote Dec 4, 2009
Hi Andrew
Just want to say a big THANKYOU. It's cause of guys like you that guys like me can learn things !!
Have been studying the issue of crossbrowser opacity fades, which is very relevant to a web site I'm working on
i.e. www.sdz.freevar.com (Please note the content is borrowed for now just til we insert the real text )
The opacity is great in FF but if you compare you'll see it's much weaker in IE.
Firstly, just wondered if it not much hassle for you to take a look and see if maybe I'm not using the right opacity stying for IE.
I have used a combination of copied fade script and my own (as seen in an earlier posting here) which includes a crossbrowser fix.
Secondly I find that that my atempted onload function (to get all the overlayed divs to hide as the page loads) doesnt work in FF ...any possible input on that would be greatly appreciated.
Many thanks for any help you could throw my way.
Web page can be seen at http://sdz.freevar.com/
and here's the js file it calls up
  1. //SET INVISIBLE PAGES on startup -required for Mozilla bug ---IE seems okay with its version of HTML style settings
  2. window.onload= function firstview(){
  3. document.getElementById('home').style.opacity=100;
  4. document.getElementById('bio').style.opacity=0;
  5. document.getElementById('philos').style.opacity=0;
  6. }
  7.  
  8. //FADE OPERATION
  9. function opacity(id, opacStart, opacEnd) {
  10.     //speed for each frame
  11.     var speed = Math.round(1000 / 100);
  12.     var timer = 0;
  13.  
  14.     //determine the direction for the blending, if start and end are the same nothing happens
  15.     if(opacStart > opacEnd) {
  16.         for(i = opacStart; i >= opacEnd; i--) {
  17.             setTimeout("changeOpac(" + i + ",'" + id + "')",(timer * speed));
  18.             timer++;
  19.         }
  20.     } else if(opacStart < opacEnd) {
  21.         for(i = opacStart; i <= opacEnd; i++)
  22.             {
  23.             setTimeout("changeOpac(" + i + ",'" + id + "')",(timer * speed));
  24.             timer++;
  25.         }
  26.     }
  27. }
  28. //BROWSER CROSSING
  29. function changeOpac(opacity, id) {
  30.     var object = document.getElementById(id).style;
  31.  /* firefox, opera, safari, chrome */ object.opacity = (opacity / 100);
  32.                          /*Mozilla*/ object.MozOpacity = (opacity / 100);
  33.                                         object.KhtmlOpacity = (opacity / 100);
  34.                 /* IE 4.0 -8.0 */ object.filter = "alpha(opacity=" + opacity + ")";
  35. }
  36. //MY CODE
  37. function showHome(){
  38.     var id=document.getElementById('home');
  39.     if(id.style.opacity == 0) {
  40.         opacity('home', 0, 100);
  41.     } else {
  42.         opacity('home', 100, 100);
  43.     }
  44.         var bb=document.getElementById('bio');         
  45.             if(bb.style.opacity == 0) {
  46.             opacity('bio', 0, 0);
  47.         }   else {
  48.             opacity('bio', 100, 0);
  49.         }  
  50.             var pp=document.getElementById('philos');          
  51.                 if(pp.style.opacity == 0) {
  52.                 opacity('philos', 0, 0);
  53.             }   else {
  54.                 opacity('philos', 100, 0);
  55.             }          
  56. }/*closes showHome function*/
  57.  
  58. function showBio(){
  59.     var id=document.getElementById('bio');
  60.     if(id.style.opacity == 0) {
  61.         opacity('bio', 0, 100);
  62.     } else {
  63.         opacity('bio', 100, 100);
  64.     }
  65.         var hh=document.getElementById('home');        
  66.             if(hh.style.opacity == 0) {
  67.             opacity('home', 0, 0);
  68.         }   else {
  69.             opacity('home', 100, 0);
  70.         }  
  71.             var pp=document.getElementById('philos');          
  72.                 if(pp.style.opacity == 0) {
  73.                 opacity('philos', 0, 0);
  74.             }   else {
  75.                 opacity('philos', 100, 0);
  76.             }          
  77. }/*closes showBio function*/
  78.  
  79. function showPhil(){
  80.     var id=document.getElementById('philos');
  81.     if(id.style.opacity == 0) {
  82.         opacity('philos', 0, 100);
  83.     } else {
  84.         opacity('philos', 100, 100);
  85.     }
  86.         var hh=document.getElementById('home');        
  87.             if(hh.style.opacity == 0) {
  88.             opacity('home', 0, 0);
  89.         }   else {
  90.             opacity('home', 100, 0);
  91.         }  
  92.             var bb=document.getElementById('bio');         
  93.                 if(bb.style.opacity == 0) {
  94.                 opacity('bio', 0, 0);
  95.             }   else {
  96.                 opacity('bio', 100, 0);
  97.             }          
  98. }/*closes showPhil function*/

Requirements

Nickname
  Remember me.
Login
Close