0

I am new to JavaScript. I am really intrigued to figure out an easy technique for changing the opacity of an image that is laying on top of another image to reveal that bottom image gradually. I want to do this by fading out. In other words subtracting from the style.opacity property gradually after each second passes with time.

I came up with the following but it doesn't seem to work for me.

The current state of my code changes the opacity suddenly goes from 1 to the negatives (-0.1, -0.2, -0.3, etc). Which basically does a transition from the top image immediately to revealing the bottom one.

I want to gradually go from opacity of 1 to (0.9, 0.8, 0.7, etc) as each second passes.

I want to accomplish this in pure JavaScript. I found something similar in CSS but I don't want to use that approach.

I assume that (var currentOp = document.getElementById('guitar2').style.opacity;) treats the currentOp variable as a string. Because of this I tried a combination of parsing to float, making the subtraction and changing back to string, setting the opacity gradually over time to not avail.

<!DOCTYPE>
<html>
<head>
    <style>
    #guitar1
    {
        position: relative;
        top: 0;
        left: 0;
    }

    #guitar2
    {
        position: absolute;
        top: 0px;
        left: 0px;
        opacity: 1;
    }
    </style>
</head>
<body onload="runTime()">
    <script>

        var timer;

        function reduceOpacity()
        {
            var op = document.getElementById('guitar2');
            var currentOp = document.getElementById('guitar2').style.opacity;
            //currentOp = (parseFloat(currentOp) -  0.1).toString();
            currentOp -= 0.1;
            op.style.opacity = currentOp;
        }

        function runTime() 
        {
            timer = setInterval(reduceOpacity, 1000);
        }

    </script>
    <h4 id="header">Gibson Les Paul</h4>
    <div style="position: relative; left: 0; top: 0;">
        <img src="gibson1.png" id="guitar1" width="500" />
        <img src="gibson2.png" id="guitar2" width="500" />
    </div>
    <button type="button" onclick='document.getElementById("header").innerHTML = "yea"'>Click Me!</button>
</body>
</html>
halfer
  • 19,824
  • 17
  • 99
  • 186
MisterTams
  • 95
  • 2
  • 9
  • 1
    You could always use pure CSS: https://stackoverflow.com/a/11681331/3684265 – imvain2 Jan 22 '19 at 19:10
  • 1
    You should check out the link posted by @imvain2. Here is another similar approach that I think is even easier to follow: [CSS3 Transition - Fade out effect](https://stackoverflow.com/questions/15907079/css3-transition-fade-out-effect#20910008) – benvc Jan 22 '19 at 19:15

2 Answers2

0

Use getComputedStyle and getPropertyValue to retrieve an accurate representation of the element's styling on load.

style.property has a habit of not being up to date, will sometimes pull default values inexplicably, and many values aren't able to be grabbed until they are set. If you console.log(op.style.opacity) in your original example you'll see that it pulls an empty string and then counts down from there after transposing it to 0.

You then use clearInterval to stop the function from continuously running after that point.

    //get the style value with getComputedStyle, which is an accurate representation of 
    //all element styling on load.
    var currentOp = getComputedStyle(op).getPropertyValue("opacity");
    // clear the interval if opacity is less than or equal to 0
    if(currentOp <= 0) clearInterval(timer);

    console.log(currentOp);

<!DOCTYPE>
<html>
<head>
    <style>
    #guitar1
    {
        position: relative;
        top: 0;
        left: 0;
    }

    #guitar2
    {
        position: absolute;
        top: 0px;
        left: 0px;
        opacity: 1;
    }
    </style>
</head>
<body onload="runTime()">
    <script>

        var timer;

        function reduceOpacity()
        {
            var op = document.getElementById('guitar2');
            
            //get the style value with getComputedStyle, which is an accurate representation of 
            //all element styling on load.
            var currentOp = getComputedStyle(op).getPropertyValue("opacity");
            // clear the interval if opacity is less than or equal to 0
            if(currentOp <= 0) clearInterval(timer);
            
            console.log(currentOp);
            //currentOp = (parseFloat(currentOp) -  0.1).toString();
            currentOp -= 0.1;
            op.style.opacity = currentOp;
        }

        function runTime() 
        {
            timer = setInterval(reduceOpacity, 1000);
        }

    </script>
    <h4 id="header">Gibson Les Paul</h4>
    <div style="position: relative; left: 0; top: 0;">
        <img src="gibson1.png" id="guitar1" width="500" />
        <img src="data:image/png;base64,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" id="guitar2" width="500" />
    </div>
    <button type="button" onclick='document.getElementById("header").innerHTML = "yea"'>Click Me!</button>
</body>
</html>

Note: I had to replace your image since it's a local file.

zfrisch
  • 8,474
  • 1
  • 22
  • 34
  • 1
    Excellent help! I made a few changes as you suggested and it absolutely worked! Thanks! – MisterTams Jan 22 '19 at 20:49
  • @MisterTams no problem. That's what the site's here for. If you're feeling good about it, throw it an upvote or click that semi-transparent check mark next to the answer and accept it as gospel. Happy Coding, mate – zfrisch Jan 22 '19 at 21:44
0


I have an alternative if your heart isn't set on JavaScript. Animate.css is an incredible stylesheet that will do the same thing in a much easier fashion. (Plus it's pure CSS so much better and more uniform support)

Import this in the head

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.0/animate.min.css" />

Then here is your according code:

   <div style="position: relative; left: 0; top: 0;">
    <img src="gibson1.png" id="guitar1"  width="500" />
    <img src="gibson2.png" id="guitar2" class="animated fadeOut delay-5s" style="animation-duration: 3s;" width="500" />
</div>

May not be quite the answer you're looking for but it is so much easier to do then JS + JQ animations.

All the best!

  • Looks very cool and I will try this out as well! But I guess my heart is set on JavaScript for this particular problem. Great input! – MisterTams Jan 22 '19 at 20:49