最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to make an image fade transition? - Stack Overflow

programmeradmin1浏览0评论

I have a script which generates a random number so that when setImg(); is called a randomly selected image appears:

<img src="" id="imgRand" alt="">


      function setImg(){
          var numRand = Math.floor(Math.random()*(6 - 1 + 1)) + 1;
          document.getElementById("imgRand").src = "images/"+numRand+".jpg";

      }

This all works fine, but when the image changes, it just 'appears'. I was wondering if there was any way to get it to fade from one to the other? Everything I've found online talks about setting styles on each individual image, but as Im using this random number script to source my images, I cant think of a way to adapt any of those solutions.

Any help is much appreciated, thanks!

I have a script which generates a random number so that when setImg(); is called a randomly selected image appears:

<img src="" id="imgRand" alt="">


      function setImg(){
          var numRand = Math.floor(Math.random()*(6 - 1 + 1)) + 1;
          document.getElementById("imgRand").src = "images/"+numRand+".jpg";

      }

This all works fine, but when the image changes, it just 'appears'. I was wondering if there was any way to get it to fade from one to the other? Everything I've found online talks about setting styles on each individual image, but as Im using this random number script to source my images, I cant think of a way to adapt any of those solutions.

Any help is much appreciated, thanks!

Share Improve this question edited Jan 5, 2013 at 0:46 Alexander 23.5k11 gold badges64 silver badges74 bronze badges asked Jan 4, 2013 at 23:36 MeechoMeecho 451 silver badge5 bronze badges 4
  • 5 Unrelated but - 1 + 1 is 0 – Alexander Commented Jan 4, 2013 at 23:36
  • Webkit allows for image transitions for backgrounds in CSS. Or, you could manage two image objects and fade one in while fading the other out, but this (this being a cross-fade) isn't possible through setting a single image source. You could fade the image out, then fade it in onload. – Shmiddty Commented Jan 4, 2013 at 23:48
  • Is this a fade effect between only two images or is this a transform effect using more than two images, if it's a transformation then random is inappropriate here, instead you have to show one after another maintaining the order of the images you set for the transform using an interval. – The Alpha Commented Jan 4, 2013 at 23:53
  • yea sorry about the 1+1 thing...I was using a formula I found for the minimum and maximum image numbers (so my min is 1 and max is 6) and didn't want to simplify it until I had settled on the amount of images I was going to use. – Meecho Commented Jan 5, 2013 at 11:37
Add a ment  | 

3 Answers 3

Reset to default 3

I will provide you with an example using CSS3 transitions. You can adapt and improve it for your specific case.

My specific example works only with Webkit as it is written since the implementation of the transcription end callback is vendor dependent. You can fix this by using the correct vendor event handler names.

/* Fades an element to given opacity */
var fade = function(opacity, fn) {
    this.addEventListener("webkitTransitionEnd", function end() {
        this.removeEventListener("webkitTransitionEnd", end);
        fn && fn.call(this);
    }, false);
    this.style.opacity = opacity;
};

/* Preloads an image */
var load = function(src, fn) {
    var self = this, $img = new Image();
    $img.onload = function() {
        fn && fn.call(self);
    };
    $img.src = src;
};

/* Steps:
 *   1. Fades out current image.
 *   2. Preloads next image.
 *   3. When loading of next image is plete, sets next image.
 *   4. Fades in.
 */
var $img = document.getElementById("imgRand");
/* Fades out */
fade.call($img, 0, function() {
    /* Get random dimensions */
    var height = Math.ceil(Math.random() * 100) + 100;
    var width = Math.ceil(Math.random() * 200) + 100;
    var src = "http://placehold.it/" + width + "x" + height;
    /* Preloading */
    load.call(this, src, function() {
        $img.setAttribute("src", src);
        /* Fades in */
        fade.call($img, 1);
    });
});

You can see it here.

The img element has -webkit-transition-duration style property set to 1s.

The most plicated and overlooked part of this is image preloading. Because, unless you preload all images that you want to use, the animation won't be smooth. But at the same time the detection of when an image has been loaded is not an easy task and the method that I'm using is a naive one that most probably will fail for images in the browser's cache. I won't go into details about that, you can search SO for it.

Disclaimer: It is too freaking late. So, I will just dump the code here and e to it later. If there's doubts.

This can be done most easily using a library such as jQuery but here is a jsFiddle example. I use absolute positioning to have two images placed over the top of each other and give one of them an opacity of 0. Then I just toggle between the two and fade one in and one out using helper functions.

The html looks something like this:

<div id="imageHolder">
    <img id="imgRand0" src="http://placehold.it/100x100" />
    <img id="imgRand1" src="http://placehold.it/100x100" style="opacity:0;alpha(opacity:0);"/>
</div>

<button onclick="setImg()">New Image</button>​

The CSS:

img {
    position:absolute;
    top:0;
    left:0;
}
#imageHolder {
    position:relative;
    height:100px;
}

And the javascript (I use additional functions from this tutorial):

var counter = 0;
function setImg(){
    var numRand = Math.floor(Math.random()*6) + 1;
    //document.getElementById("imgRand").src = "images/"+numRand+".jpg";

    counter = (counter + 1) % 2;

    document.getElementById("imgRand" + counter).src = "http://placehold.it/100&text=" + numRand;
    fade('imgRand0');
    fade('imgRand1');
}

This was too long to put into a ment, but hopefully it will guide you in the right direction.

So, because you're replacing the src of imgRand with each call to setImg, the two images you're trying to cross-fade will not be present in the DOM at the same time. You will probably need to have two separate image tags that are stacked on top of each other with CSS.

Then you will need to set the src on the top image (the one you want to fade in) and hide this image with CSS or your image will just 'appear' as soon as you set the src.

Then you will want to fade the top image in incrementally by setting the opacity of the image until it's 100...

Sorry for such a crazy description, but it's probably far easier if you have jQuery available. I will go and hunt down an example and update this.

Update: If you have jQuery, this is a rudimentary example of what your script might look like: http://jsfiddle/tracyfu/W9wMh/ Some of the other solutions here might be better if you're confined to straight JS.

发布评论

评论列表(0)

  1. 暂无评论