How to convert the height of a div to 100% value using JavaScript

Viewed 89

I have a div that I want to apply CSS transform scale property with a dynamic value based on the parent div's scroll position.

So say I have a div with an id called #circle that has a parent div called #main. I want to find the #main div's height and divide it by 100 to create a dynamic value. Using this dynamic value, I want to animate the #circle div on scroll event. So when the user is at the top of the #main div, the #circle is scaled at zero per cent, and when the user scrolls to the bottom of the main div, the circle has a scaling value of 100%.

Here is a jsFiddle.

2 Answers

You can use the offsetHeight property to get the height of the element.

ex. document.getElementById("circle").offsetHeight

Currently your scrolling container is actually the html element itself. So based on it's scrollTop,scrollHeight and the visible height i.e. window.innerHeight, we can calculate the circleScale value. All that part is handled inside scrollLogic() function.

const circle = document.getElementById('circle');
const html = document.documentElement;
document.body.onscroll = () => {
  const circleScale = scrollLogic();
  circle.style.transform = `scale(${circleScale})`;
};

const scrollLogic = () => {
  const scrollTop = html.scrollTop;
  const maxScrollTop = html.scrollHeight - window.innerHeight;
  const scrollFraction = scrollTop / maxScrollTop;
  const circleScale = Math.min(
    1,
    scrollFraction+0.1
  );
  return circleScale
};
* {
  box-sizing: border-box;
  margin: 0;
  padding:0;
}



#main {
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 30px 0;
  border: 3px solid green;
  overflow: scroll;
}

#circle {
  width: 200px;
  height: 200px;
  background-color: red;
  transform: scale(0.1);
  border-radius: 50%;
}

.spacing {
  height: 150vh;
}
<section id="main">
  <div id="circle"></div>
  <div class="spacing"></div>
</section>

Edit - For main to be a scrolling-container, it needs a certain fixed height so that the spacing of height 150vh can cause the main of height 80vh to overflow. Then the scroll event and calculations will happen on main itself. But also keep in mind that now since main itself is scrolling, the perceived position of the circle will also change and as it's scale increases, some of it will get cut down by the top of main container.

const circle = document.getElementById('circle');
const html = document.documentElement;
const main = document.getElementById('main');
main.onscroll = () => {
  const circleScale = scrollLogic();
  circle.style.transform = `scale(${circleScale})`;
};

const scrollLogic = () => {
  const scrollTop = main.scrollTop;
  const maxScrollTop = main.scrollHeight - main.offsetHeight;
  const scrollFraction = scrollTop / maxScrollTop;
  const circleScale = Math.min(
    1,
    scrollFraction+0.1
  );
  return circleScale
};
* {
  box-sizing: border-box;
  margin: 0;
  padding:0;
}



#main {
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 30px 0;
  border: 3px solid green;
  height:80vh;
  overflow: scroll;
}

#circle {
  width: 200px;
  height: 200px;
  background-color: red;
  transform: scale(0.1);
  border-radius: 50%;
}

.spacing {
  height: 150vh;
}
<section id="main">
  <div id="circle"></div>
  <div class="spacing"></div>
</section>

Related