skip to Main Content

Is there a way to add a class when the element that I want to apply the class to comes into the viewport? Or when the bottom of the screen is a certain distance past the top of the element?

Right now I have the effect that I want using something like this:

if ($(document).scrollTop() > 100) {
                    $(".graph-line.two").addClass("graph-75");

The problem with this is that it’s relative to the document height, so when I shrink the page (or view on mobile) and the elements stack on top of each other, the page becomes taller and the class (animations) don’t start when the element comes into view.

I’ve seen other people asking similar questions and I tried to implement the answers they got but I couldn’t get anything working so any help would be greatly appreciated.

This is what I have:

$(document).ready(function() {
  $(".graph-line.one").addClass("graph-75");
  $(".graph-line-2.one").addClass("opacity");
  $(window).scroll(function() {

    if ($(document).scrollTop() > 100) {
      $(".graph-line.two").addClass("graph-75");
      $(".graph-line-2.two").addClass("opacity");
    }

    if ($(document).scrollTop() > 450) {
      $(".graph-line.three").addClass("graph-75");
      $(".graph-line-2.three").addClass("opacity");
    }

    if ($(document).scrollTop() > 800) {
      $(".graph-line.four").addClass("graph-75");
      $(".graph-line-2.four").addClass("opacity");
    }

    if ($(document).scrollTop() > 1150) {
      $(".graph-line.five").addClass("graph-75");
      $(".graph-line-2.five").addClass("opacity");
    }

    if ($(document).scrollTop() > 1500) {
      $(".graph-line.six").addClass("graph-75");
      $(".graph-line-2.six").addClass("opacity");
    }
  });
});
.graph {
  display: block;
  margin: 100px auto;
  transform: rotate(-90deg);
  will-change: transform;
}
.graph-line {
  stroke-dasharray: 628px;
  stroke-dashoffset: -628px;
  transform-origin: center;
}
.graph-75 {
  animation: graph-75 1200ms ease forwards;
}
@keyframes graph-75 {
  0% {
    stroke-dashoffset: 0;
    transform: rotate(360deg);
  }
  100% {
    stroke-dashoffset: 471;
    transform: rotate(0deg);
  }
}
.graph-line-2 {
  transition: opacity 700ms;
  opacity: 0.1;
}
.opacity {
  opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>

<h1>Scroll Down</h2>

<svg width="250" height="250" class="graph photoshop">
						<circle class="graph-line-2 one" cx="50%" cy="50%" r="100" stroke-width="20" fill="none" stroke="#2ECBE4" />
						<circle class="graph-line one" cx="50%" cy="50%" r="100" stroke-width="22" fill="none" stroke="#fff" opacity="0.92" />
						<text class="graph-text" text-anchor="middle" x="50%" y="-46%" fill="#fff">Photoshop</text>
					</svg>



<svg width="250" height="250" class="graph photoshop">
						<circle class="graph-line-2 two" cx="50%" cy="50%" r="100" stroke-width="20" fill="none" stroke="#2ECBE4" />
						<circle class="graph-line two" cx="50%" cy="50%" r="100" stroke-width="22" fill="none" stroke="#fff" opacity="0.92" />
						<text class="graph-text" text-anchor="middle" x="50%" y="-46%" fill="#fff">Photoshop</text>
					</svg>



<svg width="250" height="250" class="graph photoshop">
						<circle class="graph-line-2 three" cx="50%" cy="50%" r="100" stroke-width="20" fill="none" stroke="#2ECBE4" />
						<circle class="graph-line three" cx="50%" cy="50%" r="100" stroke-width="22" fill="none" stroke="#fff" opacity="0.92" />
						<text class="graph-text" text-anchor="middle" x="50%" y="-46%" fill="#fff">Photoshop</text>
					</svg>



<svg width="250" height="250" class="graph photoshop">
						<circle class="graph-line-2 four" cx="50%" cy="50%" r="100" stroke-width="20" fill="none" stroke="#2ECBE4" />
						<circle class="graph-line four" cx="50%" cy="50%" r="100" stroke-width="22" fill="none" stroke="#fff" opacity="0.92" />
						<text class="graph-text" text-anchor="middle" x="50%" y="-46%" fill="#fff">Photoshop</text>
					</svg>



<svg width="250" height="250" class="graph photoshop">
						<circle class="graph-line-2 five" cx="50%" cy="50%" r="100" stroke-width="20" fill="none" stroke="#2ECBE4" />
						<circle class="graph-line five" cx="50%" cy="50%" r="100" stroke-width="22" fill="none" stroke="#fff" opacity="0.92" />
						<text class="graph-text" text-anchor="middle" x="50%" y="-46%" fill="#fff">Photoshop</text>
					</svg>



<svg width="250" height="250" class="graph photoshop">
						<circle class="graph-line-2 six" cx="50%" cy="50%" r="100" stroke-width="20" fill="none" stroke="#2ECBE4" />
						<circle class="graph-line six" cx="50%" cy="50%" r="100" stroke-width="22" fill="none" stroke="#fff" opacity="0.92" />
						<text class="graph-text" text-anchor="middle" x="50%" y="-46%" fill="#fff">Photoshop</text>
					</svg>

Here’s the codepen if you prefer

2

Answers


  1. You’re on the right track, I think if you use the scroll event with a function such as the answer to this similar question:

    Check if element is visible after scrolling

    Hope that helps 🙂

    Login or Signup to reply.
  2. You could do something like this: (See CodePen for implementation)

    Function taken from here: Check if element is visible after scrolling

    CodePen

    $(window).on('scroll', function() {
      $(".graph").each(function() {
        if (isScrolledIntoView($(this))) {
          $(this).find(".graph-line").addClass("graph-75");
          $(this).find(".graph-line-2").addClass("opacity");
        }
      });
    });
    
    function isScrolledIntoView(elem) {
      var docViewTop = $(window).scrollTop();
      var docViewBottom = docViewTop + $(window).height();
    
      var elemTop = $(elem).offset().top;
      var elemBottom = elemTop + $(elem).height();
    
      return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
    }
    

    Altough this is not perfect, it should point you into the right direction.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search