1

I apologize in advance if this is a simple question, but I am a novice and am having an extremely difficult time resolving a glitch that occurs when triggering a CSS transition on mouseover.

I am using JS to trigger an inversion of color and background images based on the position of the mouse on the screen. If a user moves their mouse to the bottom 50% of the screen, the JS adds the class 'white' to the tag.

This changes the color of all text on the page and loads a different background image.

I think that I am facing two issues:

  1. After the initial page load, the transition flickers once. I believe this may be because the image isn't pre-loaded. I am not sure how I can easily do this in my current situation.

  2. When mousing between the bottom and top half of the screen quickly I notice the same type of flickering behavior. However, when I allow the transition to complete, I can move between both states smoothly without flickering. I cannot understand what is causing this inconsistent behavior.

Live page | Fiddle demo

<style>
#home {
  background-color: #191919;
  background: url(../img/Profile1.jpg) no-repeat center center fixed;
  background-size: cover;
  transition:         all 900ms cubic-bezier(0.455, 0.03, 0.515, 0.955);
}

#home.white{
  background-color: white;
  background: url(../img/Profile2.jpg) no-repeat center center fixed;
  background-size: cover;
}
</style>

<div id="split-container">
  <div class="split-top">
    <div class="container-s">
      <div class="row">
        <div class="col-12">
          <h1 class="center offwhite">A UI/UX designer dedicated to creating thoughtful digital experiences.</h1>
        </div>
      </div>
    </div>
  </div>    
  <div class="split-bottom invert-trigger">
    <div class="container-s">
      <div class="row">
        <div class="col-12">
          <h1 class="center offblack">An avid traveller seeking new perspectives and meaningful connections.</h1>
        </div>
      </div>
    </div>
  </div>
</div>  

<script>
   winWidth=$(window).width();
      if (winWidth >=752) {

      $('.invert-trigger').hover(function(){
        $('body').addClass('white');
      }, function(){
        $('body').removeClass('white');
      });
      $('.invert-trigger').hover(function(){
        $('.invert').addClass('black');
      }, function(){
        $('.invert').removeClass('black');
      });
    }         
  });
</script>

Thank you for any help you can provide to resolve these challenges!

isherwood
  • 58,414
  • 16
  • 114
  • 157
mitchepa
  • 21
  • 1

3 Answers3

0

"Quickly" in this case is when you move the mouse before a transition has completed. There are many ways to deal with this.

One example is to toggle a parameter indicating whether or not the animation is ready. You can then toggle the parameter to ready = false when you start the animation and use setTimeout() to toggle it back. This way the animation will always be completed before you can trigger it again.

Jensei
  • 450
  • 1
  • 4
  • 17
  • This makes sense, but I suppose it would also make the page feel slow as it will need to complete the entire transition before rolling back to the previous state. Ideally, if I am 50% through the transition, I would like to be able to reverse the transition smoothly without waiting for the first transition to complete. Perhaps this is not possible though? – mitchepa Mar 20 '19 at 19:54
  • I agree. animejs is a great library for doing exactly that! Although, then you are looking at animations rather than transitions. – Jensei Mar 20 '19 at 19:57
0

I'd be inclined to use a :before pseudo-element on your body tag with the alternative color and background image already applied to it and with an opacity of zero, and toggle opacity in your hover handlers. It'll lay behind your other content. Then the image would (hopefully, depending on size and network speed) load before the initial transition.

isherwood
  • 58,414
  • 16
  • 114
  • 157
  • Thanks, I am not familiar with this, but would love to learn and would be happy to work up a demo when I get home this evening. Thanks for all of your help! – mitchepa Mar 20 '19 at 19:48
  • I had a chance to go through the code and pull the relevant content into JSFiddle as requested. I haven't used this service before and can't seem to get the actual js to run (probably some simple mistake). Thanks for any help you can provide with this.. The link can be viewed here: https://jsfiddle.net/L2s0jdck/ – mitchepa Mar 21 '19 at 15:08
  • Seems like it's working fine. Thanks. I'll try to find some time. – isherwood Mar 21 '19 at 16:11
0

I have changed your script a little bit. I hope it's still readable for you.

$(document).ready(function() {
    if($(window).width() >= 752) {
        $('.invert-trigger').on('mouseover', function() { // One .mouseover() event
            $('body').addClass('white');
            $('.invert').addClass('black');
        }).on('mouseout', function() {  // One .mouseout() event
            $('body').removeClass('white');
            $('.invert').removeClass('black');
        });
    }
});

The flickering of the image, comes from the fact the image is not loaded in the DOM yet. This can be solved by pre-loading the image.

var img = new Image();
img.src = 'your_image_url.jpg';

I hope this helps you on your way.

Peter Bode
  • 222
  • 1
  • 9
  • 1
    See this thread for more info: https://stackoverflow.com/questions/3646036/javascript-preloading-images – Steven Kuipers Mar 20 '19 at 19:34
  • I'm very new to jquery, but will take a look at the code you have reworked carefully and figure out how to load the image into the DOM as you suggest. – mitchepa Mar 20 '19 at 19:51