0

I'll start by saying that I'm fairly new to css so pardon me if the answer to my question is obvious. I'm looking to apply an effect to the element(s) that are most centered in the screen. I want the user to scroll down and have photos saturate from gray scale.

Here is the page which I'd like the effect to occur on:

http://evanscottpierce.com/portfolio/

The current desktop behavior is to saturate on hover but obviously this doesn't work for mobile, so I'd like saturation to be triggered by scrolling instead. As you can see below, I just applied the gray scale effect to desktop only until I can get the desired behavior for mobile.

Here is the code I have so far:

@media only screen and (min-width:768px){
    .gray-scale-img .rl-gallery {
      overflow: hidden;
      -webkit-backface-visibility: hidden;
    }
    .gray-scale-img .rl-gallery .rl-gallery-link {
      -webkit-filter: grayscale(100%);
              filter: grayscale(100%);
      -webkit-transition: .3s ease-in-out;
              transition: .3s ease-in-out;
      will-change: filter;
    }
    .gray-scale-img .rl-gallery .rl-gallery-link:hover {
      -webkit-filter: grayscale(0);
              filter: grayscale(0);
    }
}

Thank you in advance!

  • Evan, I'd do this with jQuery's .is(':visible') as the method of detecting whether an element is visible. Basically, check all of your target elements when the window.on( 'scroll' event is triggered and toggle the effect class based on that visibility check. I'm working up a sample answer that implements this idea but you should also take a stab at it. – JasonB Nov 25 '18 at 03:57
  • Check that - .is(':visible') didnt do the trick - see answer below using helper method from https://stackoverflow.com/questions/487073/check-if-element-is-visible-after-scrolling – JasonB Nov 25 '18 at 04:13

2 Answers2

0

Using a helper method to select whether or not the css should be applied and then applying that css with class is pretty clean.

// loop to add sample images
let imageCount = 0;
while (imageCount++ < 10) {
  $('body').append('<p><img src="https://picsum.photos/200/100?image=' + imageCount + '" alt="sample image" class="gray-scale-img" ></p>');
}

// helper function to check for vertical centering
function isScrolledIntoCenter(elem)
{
    var docViewCenter = $(window).scrollTop() + $(window).height() / 2;

    var elemTop = $(elem).offset().top;
    var elemBottom = elemTop + $(elem).height();

    return ((elemBottom >= docViewCenter) && (elemTop <= docViewCenter));
}

// function to toggle .in-color based on visibility
function toggleInColor() {
  const images = $('img.gray-scale-img');

  images.each(function() {
    $(this).toggleClass('in-color',isScrolledIntoCenter(this));
  });
}

toggleInColor();

$(window).on('scroll', toggleInColor);
.gray-scale-img {
  -webkit-backface-visibility: hidden;
  -webkit-filter: grayscale(100%);
  filter: grayscale(100%);
  -webkit-transition: .3s ease-in-out;
  transition: .3s ease-in-out;
  will-change: filter;
}

.gray-scale-img.in-color {
  -webkit-filter: grayscale(0);
  filter: grayscale(0);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
JasonB
  • 5,747
  • 2
  • 13
  • 25
  • Hey Jason! Thanks for the speedy reply. This script looks like it almost accomplishes what I want save for a few discrepancies. I want to saturate the center image, not any image in view. Would the following change to "isScrolledIntoView" fix that? `var docViewCenter = docViewTop + ($(window).height()/2); return ((elemBottom >= docViewCenter) && (elemTop <= docViewCenter));` I'm pretty inexperienced with javascript and need a little bit of clarification. How would I pass gallery elements to "toggleInColor"? Sorry for the confusion! – Evan Pierce Nov 25 '18 at 05:01
  • Glad we're on the right track. The toggleInColor function in this example will filter through all of the images and add or remove the .in-color class based on the value the helper function returns - I'll rewrite it with my version of scrolled into center instead of scrolled into view and we'll see how we're doing – JasonB Nov 25 '18 at 05:09
  • Changed the helper function to ensure that only an image that straddles a horizontal line at the vertical center of the window will be colored. – JasonB Nov 25 '18 at 05:14
  • Perfect! Its working exactly as intended with the test images. However I'm unable to get gallery images working with the function "toggleInColor". It seems "const images = $('img.gray-scale-img');" is not registering images in the gallery. Is there another way I can create an array of images on the page to pass to the function? http://evanscottpierce.com/portfolio-test/ – Evan Pierce Nov 25 '18 at 05:57
  • Sure, looks like $( '.rl-gallery-link' ) or $( '.rl-gallery-item' ) should do the trick. – JasonB Nov 25 '18 at 07:55
  • Still no luck.. Could it be an issue that I'm using Beaver Builder to apply javascript and css to a page? And if so what is the best practice for applying javascript and css to an individual wordpress page? – Evan Pierce Nov 25 '18 at 08:07
  • Looks like you're getting an error related to jQuery. Try wrapping all of the code you are adding in jQuery(document).ready(function($){ ... }); where ... is your code. Otherwise look up help for using jQuery with Beaver Builder. There is other jQuery code executing in that javascript file. – JasonB Nov 25 '18 at 08:26
  • I think I realized my issue: I'm not sure where to add the script. I just tried installing the Header and Footer Scripts plugin but when I add the script to the header the entire gallery's format breaks. I also tried adding it with an HTML widget but the same issue arose. What is the correct way to add the script? Sorry that I need so much help with this! I really appreciate your help. http://evanscottpierce.com/portfolio-test/ – Evan Pierce Nov 26 '18 at 05:04
  • Take a look at https://premium.wpmudev.org/blog/adding-jquery-scripts-wordpress/ and if you're still having trouble tomorrow add a comment and I can connect with you on a chat or video stream and help you out. – JasonB Nov 26 '18 at 05:09
  • Awesome, I'll go ahead and do that now! – Evan Pierce Nov 26 '18 at 05:10
  • Hey! I finally figured it out, I had to change `$( '.rl-gallery-link' )` to `$( 'a.rl-gallery-link' )`. Thank you so much for your help! – Evan Pierce Nov 26 '18 at 08:30
0

The simplest way is usages css3 flexbox:

<div class="flex-container">
   <div>One</div>
   <div>Two</div>
   <div>Three</div>
   <div>Four</div>
   <div>Five</div>
   <div>Six</div>
   <div>Seven</div>
   <div>Eight</div>
   <div>Nine</div>
</div>

<style type="text/css">
.flex-container {
   display:flex;
   height: 200px;
   align-items: center;
}
</style>