Kevin Zhang
Kevin Zhang

Reputation: 1072

How to handle the scroll event with animation in each moment's state?

I want to do a scroll event animation, here is the steps:

  1. A card element(div&img, let's named it CARD) in the middle of screen;
  2. Do scroll down;
  3. The CARD will rotate & scale;
  4. Do scroll up;
  5. The CARD will rotate & scale back to step 1 state;

So generally, the CARD will rotate&scale during the scroll up/down event, now the question is how to deal with the relationship between the scroll event and CARD state in every moment? The scroll up/down will do the "reverse like" state, scoll speed also impact the CARD state.

PS: this is the demo animation site I want to follow.

Upvotes: 2

Views: 778

Answers (2)

Aman Chadha
Aman Chadha

Reputation: 2496

I tried to imitate the scroll animation of the link you mentioned in your question

Below is the output(Its just a part of it and don't go by GIF's fps,its lot smoother in the output) enter image description here

What i have done is that i changed the transform property of the card based on some values of scrollY.

Here i used certain scrollY values such as 1300,1750,2950 etc to chain the animation.

Now in the case when scrollY<=1300

i gave rotation animation till the scrollY reaches 1300.

enter image description here

So final point=1300,Initial point=0.

Total no of elements between the two=1300-0=1300.

Suppose i want the element to rotate about 174deg anticlockwise.(As i did in the code). so when scrollY=1300 i want to rotate angle to be -174deg. therefore when scrollY=1 rotate angle would be (-174/1300) and for scrollY=2 it would be 2*(-174/1300) and so on thus the value depends on scrollY So a general expression in this case would be =-((scrollY)*(174/1300)).

and for scale property i want to scale it down to 0.48 times to its regular size when scrollY reaches 1300.

Initial scale value=1 final scale value=0.48,

now so as to get scale value 0.48 when scrollY=1300 i have to subtract (1-0.48)=>0.52(Here 0.52 is delta S) from 1

and when scrollY=1 then i will subtract (0.52/1300) from 1 Change of scale value depends on scrollY value

Thus we can apply this expression to achieve scale animation 1-(((0.52)/1300)*(scrollY))

Now when it comes to the case where initial point is not 0 then we shift it to 0 by subtracting initial point from scrollY

In case 2(scrollY lies between 1300 and 1750)

enter image description here

Total number of elements between the two=1750-1300=450.

Here i gave rotation animation wrt x axis

Initial rotateX value=10deg,final rotateX value=70deg.

so i want to increase the value by 60deg when it reaches to scrollY=1750.Thus delta Rx=60deg

A general formula when the initial value of scrollY is not equal to 0(here in this case it is 1300) (Initial rotation value + (scrollY-Initial scrollY value)*(delta Rx/total number of elements))

or

(10 +(scrollY-1300)*(60/450))deg

Thus we can use expressions like above to manipulate transform property's value(Just replace delta Rx with delta Ry ,delta Rz,delta S etc) or top and left property as well.

SEE THIS IN FULLSCREEN

var card = document.getElementsByClassName('card')[0];
var parent = document.getElementsByClassName('parent')[0];
var end = document.getElementsByClassName('end')[0];

window.addEventListener('scroll', function() {

  var scrollY = window.scrollY;

  if (scrollY <= 1300) {
    card.style.marginTop = "0px";
    card.style.transform = " rotateY(-25deg)rotateX(10deg)rotateZ(" + (-scrollY) * (174 / 1300) + "deg)scale(" + (1 - ((0.52 / 1300) * scrollY)) + ")"; //scale(0.48);rotateZ(174.4);   
    parent.style.top = "200px";
    parent.style.left = "1150px";
  }

  if (scrollY > 1300 && scrollY <= 1750) {
    var top_init = 200;
    var left_init = 1150;
    var range = 1750 - 1300;

    parent.style.position = "fixed";
    parent.style.marginTop = "0px";

    card.style.transform = " rotateY(-25deg)rotateX(" + (10 + (scrollY - 1300) * (60 / range)) + "deg)rotateZ(-174deg)scale(0.48)";

    parent.style.top = top_init + ((scrollY - 1300) * ((750 - 200) / range)) + "px";
    parent.style.left = left_init - ((scrollY - 1300) * ((1405 - 1150) / range)) + "px";

    if (scrollY == 1950) {
      card.style.transform = " rotateY(-25deg)rotateX(70deg)rotateZ(-174deg)scale(0.48)";
      parent.style.top = "750px";
      parent.style.left = "1405px";
    }

  }

  if (scrollY > 1750) {
    var end_point = 2950;
    range = end_point - 1750;

    parent.style.position = "fixed";
    parent.style.marginTop = "0px";
    parent.style.left = 895 - ((scrollY - 1750) * (120 / range)) + "px";

    card.style.transform = "rotateY(" + ((-25) + ((scrollY - 1750) * (25 / range))) + "deg)rotateX(" + (70 - ((scrollY - 1750) * (70 / range))) + "deg)rotateZ(" + ((-174) + ((scrollY - 1750) * (84 / range))) + "deg)" +
      "scale(" + (0.48 + ((scrollY - 1750) * (2.3 / range))) + "," + (0.48 + ((scrollY - 1750) * (3.426 / range))) + ")";
    card.style.filter = "brightness(" + (100 - ((scrollY - 1750) * (50 / range))) + "%)";


    if (scrollY > end_point) {
      card.style.transform = "rotateY(0deg)rotateX(0deg)rotateZ(90deg)scale(2.78,4.036)";
      card.style.filter = "brightness(50%)";
      parent.style.left = "775px";
      parent.style.position = "absolute";
      parent.style.marginTop = end_point + "px";
      end.style.opacity = "1";
    }
  }

  var opac = scrollY > end_point ? "1" : "0";
  end.style.opacity = opac;

});
* {
  margin: 0px;
  padding: 0px;
  font-family: 'arial';
}

body {
  height: 4300px;
  overflow-x: hidden;
  width: 100%;
}

.parent {
  top: 200px;
  left: 1150px;
  position: fixed;
}

.card {
  top: 200px;
  left: 1150px;
  background-color: #6154C1;
  height: 500px;
  width: 350px;
  color: white;
  border-radius: 20px;
  transform-origin: 50%;
  transform-style: preserve-3d;
  transform: rotateY(-20deg)rotateX(10deg);
}

.content_1 {
  padding: 100px 100px;
  height: 100vh;
  width: 100%;
}

.content_1 h1 {
  font-size: 60px;
}

.content_1 p {
  margin-top: 25px;
  font-size: 22px;
  width: 60%;
}

.end {
  position: absolute;
  height: 100vh;
  width: 100%;
  transition: 0.4s;
  top: 505px;
  left: 0px;
  opacity: 0;
  margin-top: 2950px;
}

.end h1 {
  color: white;
  font-size: 250px;
  padding-top: 300px;
  letter-spacing: 8px;
  font-weight: normal;
  text-align: center;
}
<div class="parent">
  <div class="card">
    <div class="chip"></div>

  </div>

</div>
<div class="end">
  <h1>THE END</h1>
</div>
<div class="content_1">
  <h1>Heading</h1>

  <p>Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up
    one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum
    et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section
    1.10.32. The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact original form, accompanied by
    English versions from the 1914 translation by H. Rackham.</p>

  <p>Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up
    one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum
    et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section
    1.10.32. The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact original form, accompanied by
    English versions from the 1914 translation by H. Rackham.</p>
</div>
<div class="content_1">
  <h1>Heading</h1>
  <p>Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up
    one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum
    et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section
    1.10.32. The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact original form, accompanied by
    English versions from the 1914 translation by H. Rackham.</p>
  <p>Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up
    one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum
    et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section
    1.10.32. The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact original form, accompanied by
    English versions from the 1914 translation by H. Rackham.</p>
</div>

Upvotes: 2

SdtElectronics
SdtElectronics

Reputation: 586

Try this:

const el = document.querySelector("#card");
let deg = 0;
let scale = 1;

document.onwheel = e => {
  deg += event.deltaY * 0.09;
  scale *= 1 + event.deltaY * -0.002;
  scale = Math.min(Math.max(.125, scale), 4);
  el.style.transform = `rotate(${deg}deg)`;
  el.style.transform += `scale(${scale})`;
}
#card{
  height: 50px;
  width: 50px;
  background-color: #66CCFF;
}
<!DOCTYPE>
<html>
<head>

</head>
<body>
<div id = "card"></div>
</body>
</html>
  

Note: scroll inside stackoverflow page would shift the page as well. Try it in jsfiddle for better view.

Upvotes: 1

Related Questions