如何为具有粘性位置的元素设置动画

问题描述 投票:0回答:1

告诉我如何为具有粘性位置的元素设置动画

我希望动画不要在初始位置播放,但是当元素运动时,动画会平滑地达到顶部值。

假设旋转(900deg); 根据我们向下或向上滚动的位置,动画的方向会发生变化。

我知道你可以跟踪块中元素的初始坐标,如果沿 Y 轴的坐标添加一些值,那么我们就开始滚动,但我无法实现这一点,以便 在初始位置旋转为 0,在最终位置旋转为 900,这将允许动画以不同的滚动速度以不同的速度播放

body {
  display: flex;
  width: 100%;
  height: -moz-max-content;
  height: max-content;
  background: rgb(22, 22, 22);
}

.main {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: -moz-max-content;
  height: max-content;
}

.main__start-page {
  width: 100%;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  background-color: palegreen;
}

.main__start-page p:first-child {
  font-size: 114px;
  color: white;
  font-weight: 900;
  text-shadow: 2px 2px black;
}

.main__start-page p:last-child {
  font-size: 114px;
  color: white;
  font-weight: 900;
  text-shadow: 2px 2px black;
}

.main__center-page {
  width: 100%;
  height: 100vh;
  background-color: plum;
}

.main__end-page {
  width: 100%;
  height: 100vh;
  background-color: palegoldenrod;
}

.main__lorem-center-page {
  width: 50%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  & p {
    padding-left: 50px;
  }
}

.main__wrapper {
  width: 100%;
  height: max-content;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  position: relative;
}

.asterisk__wrapper {
  display: flex;
  justify-content: center;
  position: absolute;
  right: 20px;
  width: 200px;
  height: 50%;
}

.asterisk__wrapper::before {
  content: "start";
  position: absolute;
  top: -60px;
}

.asterisk__wrapper::after {
  content: "stop";
  position: absolute;
  bottom: -60px;
}

.asterisk {
  font-size: 500px;
  position: sticky;
  width: 100px;
  border-radius: 99px;
  height: 100px;
  top: 50%;
  background-color: white;
}
<div class="main">
  <div class="main__wrapper">
    <div class="main__start-page">
      <p>ПРИВЕТ</p>
      <p>МИР</p>
    </div>

    <div class="main__center-page">
      <div class="main__lorem-center-page">
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Fugit deserunt, eaque laudantium inventore magni perferendis saepe reprehenderit possimus quam rerum officia quis veritatis cum est, esse sapiente tempora voluptatum tempore!
        </p>
      </div>
    </div>

    <div class="asterisk__wrapper">
      <div class="asterisk"></div>
    </div>
  </div>
  <div class="main__end-page">
    <div class="main__lorem-center-page">
      <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Sequi aperiam alias fugiat itaque dicta cumque sed soluta possimus reiciendis. Quidem ad voluptatum possimus labore iure magnam quaerat non minus dolore.
      </p>
    </div>
  </div>
</div>

enter image description here

javascript css sticky
1个回答
0
投票

这是一个近似答案,我们得到滚动位置和底部位置之间的差值(以较小者为准),然后减去顶部,这个计算的最大值是253.54,我将其转换为3.549的比率,这样最小值将为零,最大值将为 900

const asterisk = document.getElementsByClassName('asterisk')[0];
const initial =  window.scrollY;
const asteriskWrapper = document.getElementsByClassName('asterisk__wrapper')[0];
const { bottom: bottomY, height: topY } = asteriskWrapper.getBoundingClientRect();
document.addEventListener("scroll", (event) => {
  lastKnownScrollPosition = window.scrollY + topY;
  const rotateValue = Math.round((Math.min(window.scrollY + topY, bottomY) - topY) * 3.549); // 900 / 253.54 (max val of ratio) = 3.549
  asterisk.style.transform = `rotate(${rotateValue}deg)`;
  
});
body {
  display: flex;
  width: 100%;
  height: -moz-max-content;
  height: max-content;
  background: rgb(22, 22, 22);
}

.main {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: -moz-max-content;
  height: max-content;
}

.main__start-page {
  width: 100%;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  background-color: palegreen;
}

.main__start-page p:first-child {
  font-size: 114px;
  color: white;
  font-weight: 900;
  text-shadow: 2px 2px black;
}

.main__start-page p:last-child {
  font-size: 114px;
  color: white;
  font-weight: 900;
  text-shadow: 2px 2px black;
}

.main__center-page {
  width: 100%;
  height: 100vh;
  background-color: plum;
}

.main__end-page {
  width: 100%;
  height: 100vh;
  background-color: palegoldenrod;
}

.main__lorem-center-page {
  width: 50%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  & p {
    padding-left: 50px;
  }
}

.main__wrapper {
  width: 100%;
  height: max-content;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  position: relative;
}

.asterisk__wrapper {
  display: flex;
  justify-content: center;
  position: absolute;
  right: 20px;
  width: 200px;
  height: 50%;
}

.asterisk__wrapper::before {
  content: "start";
  position: absolute;
  top: -60px;
}

.asterisk__wrapper::after {
  content: "stop";
  position: absolute;
  bottom: -60px;
}

.asterisk {
  font-size: 12px;
  position: sticky;
  width: 100px;
  border-radius: 99px;
  height: 100px;
  top: 50%;
  background-color: white;
}
<div class="main">
  <div class="main__wrapper">
    <div class="main__start-page">
      <p>ПРИВЕТ</p>
      <p>МИР</p>
    </div>

    <div class="main__center-page">
      <div class="main__lorem-center-page">
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Fugit deserunt, eaque laudantium inventore magni perferendis saepe reprehenderit possimus quam rerum officia quis veritatis cum est, esse sapiente tempora voluptatum tempore!
        </p>
      </div>
    </div>

    <div class="asterisk__wrapper">
      <div class="asterisk">a</div>
    </div>
  </div>
  <div class="main__end-page">
    <div class="main__lorem-center-page">
      <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Sequi aperiam alias fugiat itaque dicta cumque sed soluta possimus reiciendis. Quidem ad voluptatum possimus labore iure magnam quaerat non minus dolore.
      </p>
    </div>
  </div>
</div>

© www.soinside.com 2019 - 2024. All rights reserved.