Home > OS >  Starting an animation when it is scrolled into view
Starting an animation when it is scrolled into view

Time:01-11

I have 2 <hr> elements that are animated and move into close to each other. I want the animation to take place once the <hr> elements are in the viewport, instead of occurring right when the page is loaded. I have included my JavaScript code but this code didn't work; not sure if I'm using the right event.

'use strict';

const linebreak = document.querySelector('#hero--one');
const symbolContainer = document.querySelector('.header__container-symbol')

linebreak.addEventListener('scroll', function(e) {
  e.preventDefault();

  const containerCoords = symbolContainer.getBoundingClientRect();

  symbolContainer.scrollIntoView({
    behavior: 'smooth'
  });
  linebreak.classList.remove('hidden');


})
/* Lines and Diamond above title */

.header__container-symbol {
  display: flex;
  justify-content: center;
  align-content: center;
  background-color: rgba(25, 25, 25, 1);
}

.span-D {
  align-self: center;
}

.hr-symbol {
  width: 60rem;
  display: inline-block;
  height: 0.3rem;
  background-color: #eee;
}

#hero--one {
  margin-right: 3px;
  animation: moveInLeftHr;
  animation-duration: 2s;
}

#symbol {
  font-size: 3rem;
}

#hero--two {
  margin-left: 3px;
  animation: moveInRightHr;
  animation-duration: 2s;
}

#symbol {
  color: #eee;
  margin-right: 2rem;
  margin-left: 2rem;
}

.hidden {
  display: none;
}


/* End Diamon and Lines above title */


/* KeyFrames Animations */

@keyframes moveInLeftHr {
  0% {
    opacity: 0;
    transform: translateX(-100px);
  }
  100% {
    opacity: 1;
    transform: translate(0);
  }
}

@keyframes moveInRightHr {
  0% {
    opacity: 0;
    transform: translateX(100px);
  }
  100% {
    opacity: 1;
    transform: translate(0);
  }
}
<div >
  <span ><hr   id="hero--one"/></span>
  <span id="symbol"> &#11033; </span>
  <span ><hr  id="hero--two"/></span>
</div>

CodePudding user response:

You can use the Intersection Observer API to detect when the element intersects with the viewport.

The threshold option is set to 1, meaning it will check for when the element is fully within the viewport.

A test div has been inserted at the top of the html to demonstrate the behavior.

'use strict';

const linebreak1 = document.querySelector('#hero--one');
const linebreak2 = document.querySelector('#hero--two');
const symbolContainer = document.querySelector('.header__container-symbol')

const observer = new IntersectionObserver((entries, observer) => {
  if (!entries[0].isIntersecting) return;
  linebreak1.classList.remove('hidden');
  linebreak2.classList.remove('hidden');
}, { threshold: 1 });

observer.observe(symbolContainer);
/* Lines and Diamond above title */

.header__container-symbol {
  display: flex;
  justify-content: center;
  align-content: center;
  background-color: rgba(25, 25, 25, 1);
}

.span-D {
  align-self: center;
}

.hr-symbol {
  width: 60rem;
  display: inline-block;
  height: 0.3rem;
  background-color: #eee;
}

#hero--one {
  margin-right: 3px;
  animation: moveInLeftHr;
  animation-duration: 2s;
}

#symbol {
  font-size: 3rem;
}

#hero--two {
  margin-left: 3px;
  animation: moveInRightHr;
  animation-duration: 2s;
}

#symbol {
  color: #eee;
  margin-right: 2rem;
  margin-left: 2rem;
}

.hidden {
  display: none;
}


/* End Diamon and Lines above title */


/* KeyFrames Animations */

@keyframes moveInLeftHr {
  0% {
    opacity: 0;
    transform: translateX(-100px);
  }
  100% {
    opacity: 1;
    transform: translate(0);
  }
}

@keyframes moveInRightHr {
  0% {
    opacity: 0;
    transform: translateX(100px);
  }
  100% {
    opacity: 1;
    transform: translate(0);
  }
}
<div style="height: 500px;"></div>

<div >
  <span ><hr   id="hero--one"/></span>
  <span id="symbol"> &#11033; </span>
  <span ><hr  id="hero--two"/></span>
</div>

  •  Tags:  
  • Related