jquery 为圆添加渐变背景线

ibps3vxo  于 2023-08-04  发布在  jQuery
关注(0)|答案(3)|浏览(96)

我有一个块的页面上有一个背景线,就行本身有一个圆圈,滚动沿着主滚动
问题是,你怎么能让它和圆一起,沿着这条线滚动另一条和圆颜色相同的线,它看起来像这样:


的数据
我试着添加样式到之前,但它没有工作出我所期望的

left: 50%;
transform: translate(-50%, -50%);
width: 3px;
height: 40vh;
background: #4f8eff;
box-shadow: inset 0 20vh 10vh -10vh #f6e75e, inset 0 -20vh 10vh -10vh #f6e75e;
z-index: 2;

字符串
一切都应该像在图片中,我扔了,圆圈应该是白色的,蓝色应该完全重叠的黄色,当我们滚动到最顶部,从底部相同。而在块的中心,让我们说蓝色应该既在圆圈的上方,也在下方,同时保持渐变
在我的例子中,几乎和我想要的一样,但不是到最后,我想要当蓝色线到达块的末尾,或者到块的开头,然后蓝色完全重叠黄色。现在我们发现,当圆圈在顶部的最大位置时,黄色仍然在顶部

const circle = document.querySelector(".circle");
const cases = document.querySelectorAll(".case");

circle.style.transition = ""

const handleScroll = () => {
  const {
    height: blockHeight
  } = document.querySelector(".block2").getBoundingClientRect()

  const maxTop = cases[cases.length - 1].offsetTop + cases[cases.length - 1].offsetHeight - 200
  const minTop = cases[0].offsetTop

  let {
    height: startTop
  } = cases[0].getBoundingClientRect()

  const scrollDist = Math.min(maxTop, Math.max(startTop / 2 + window.scrollY, minTop))

  circle.style.top = `${scrollDist}px`
  circle.style.backgroundSize = `17px ${blockHeight}px`
  circle.style.backgroundPosition = `0 ${-scrollDist}px`
}

const handleWindowSizeAndScroll = () => {
  window.removeEventListener("scroll", handleScroll)
  window.removeEventListener("resize", handleScroll)
  window.addEventListener("scroll", handleScroll)
  window.addEventListener("resize", handleScroll)
}

handleScroll()
handleWindowSizeAndScroll()
window.addEventListener("resize", handleWindowSizeAndScroll)

x

.block1 {
  height: 200px;
  background-color: gray;
}

.block3 {
  height: 600px;
  background-color: gray;
}

.block2 {
  height: 100%;
  position: relative;
}

.block2,
.block2 .circle {
  background: linear-gradient(214deg, rgba(79, 142, 255, 0) 0%, #f5e550 10%, #f5e550 90%, rgba(79, 142, 255, 0) 100%) center/3px calc(100% - 100px) no-repeat;
}

.block2 .circle {
  background: #4f8eff;
  width: 17px;
  height: 17px;
  left: 50%;
  transform: translate(-50%, -50%);
}

.block2 .circle,
.block2 .circle::before {
  position: absolute;
  border-radius: 50%;
}

.block2 .circle::before {
  content: "";
  inset: 3px;
  background-color: white;
}

.block2 .circle::before {
  left: 50%;
  transform: translate(-50%, -50%);
  width: 3px;
  height: 40vh;
  background: #4f8eff;
  box-shadow: inset 0 20vh 10vh -10vh #f6e75e, inset 0 -20vh 10vh -10vh #f6e75e;
  z-index: 2;
}

.text {
  text-align: center;
  padding: 200px 50px;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/css/bootstrap.min.css" integrity="sha512-t4GWSVZO1eC8BM339Xd7Uphw5s17a86tIZIj8qRxhnKub6WoyhnrxeCIMeAqBPgdZGlCcG2PrZjMc+Wr78+5Xg==" crossorigin="anonymous" referrerpolicy="no-referrer"
/>
<div class="block1"></div>
<div class="block2">
  <div class="circle"></div>
  <div class="case">
    <div class="row">
      <div class="col-5 text">Text 1</div>
      <div class="col-2"></div>
      <div class="col-5 text">Text 1</div>
    </div>
  </div>
  <div class="case">
    <div class="row">
      <div class="col-5 text">Text 2</div>
      <div class="col-2"></div>
      <div class="col-5 text">Text 2</div>
    </div>
  </div>
  <div class="case">
    <div class="row">
      <div class="col-5 text">Text 3</div>
      <div class="col-2"></div>
      <div class="col-5 text">Text 3</div>
    </div>
  </div>
</div>
<div class="block3"></div>

的字符串

cvxl0en2

cvxl0en21#

根据您对评论的回复,我相信您希望滚动圆圈沿着部分。请全屏查看解决方案

const circle = document.querySelector(".circle");
const cases = document.querySelectorAll(".case");
const text1 = document.querySelector(".text1");
const block3 = document.querySelector(".block3");

const handleScroll = () => {
  const {
    height: blockHeight
  } = document.querySelector(".block2").getBoundingClientRect();

  const maxTop = cases[cases.length - 1].offsetTop + cases[cases.length - 1].offsetHeight - 200;
  const minTop = cases[0].offsetTop;
  const block3Top = block3.offsetTop - 700;

  let {
    height: startTop
  } = cases[0].getBoundingClientRect();

  let scrollDist = Math.min(maxTop, Math.max(startTop / 2 + window.scrollY, minTop));

  if (scrollDist <= minTop || scrollDist >= maxTop || scrollDist >= block3Top) {
    scrollDist = scrollDist <= minTop ? minTop : (scrollDist >= block3Top ? block3Top : maxTop);
    circle.style.backgroundSize = `17px 100%`;
    circle.classList.remove('active');
  } else {
    circle.style.backgroundSize = `17px ${blockHeight}px`;
    if (scrollDist >= 250) {
      circle.classList.add('active');
    } else {
      circle.classList.remove('active');
    }
  }

  circle.style.top = `${scrollDist}px`;
  circle.style.backgroundPosition = `0 ${-scrollDist}px`;
};

const handleWindowSizeAndScroll = () => {
  handleScroll();
};

handleScroll();
handleWindowSizeAndScroll();
window.addEventListener("resize", handleWindowSizeAndScroll);
window.addEventListener("scroll", handleScroll);
.block1 {
  height: 200px;
  background-color: gray;
  position: relative;
  z-index: 1;
}

.block3 {
  height: 600px;
  background-color: gray;
}

.block2 {
  height: 100%;
  position: relative;
}

.block2,
.block2 .circle {
  background: linear-gradient(214deg, rgba(79, 142, 255, 0) 0%, #f5e550 10%, #f5e550 90%, rgba(79, 142, 255, 0) 100%) center/3px calc(100% - 100px) no-repeat;
}

.block2 .circle {
  width: 17px;
  height: 17px;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  position: fixed;
  border: 2px solid #4f8eff;
  border-radius: 50%;
  background: white;
  transition: visibility 0.3s ease-out, opacity 0.3s ease-out;
}

.block2 .circle::before,
.block2 .circle::after {
  content: "";
  inset: 3px;
}

.block2 .circle::after {
  left: 50%;
  width: 3px;
  height: 100px;
  background: #4f8eff;
  box-shadow: inset 0 50vh 25vh -25vh #4f8eff, inset 0 -50vh 25vh -25vh #4f8eff;
  z-index: 1;
  position: fixed;
  top: 65px;
  transform: translate(-50%, -50%);
}

.block2 .circle::before {
  left: 50%;
  width: 3px;
  height: 100px;
  background: #4f8eff;
  box-shadow: inset 0 50vh 25vh -25vh #4f8eff, inset 0 -50vh 25vh -25vh #4f8eff;
  z-index: 1;
  position: fixed;
  top: -50px;
  transform: translate(-50%, -50%);
}

.text {
  text-align: center;
  padding: 200px 50px;
}

.text1 .circle.active,
.text1 .circle.active::before,
.text1 .circle.active::after {
  visibility: visible;
  opacity: 1;
}

.circle,
.circle::before,
.circle::after {
  visibility: hidden;
  opacity: 0;
}

.circle.active,
.circle.active::before,
.circle.active::after {
  visibility: visible;
  opacity: 1;
}

.block3 .circle,
.block3 .circle::before,
.block3 .circle::after {
  transition: visibility 0.3s ease-out, opacity 0.3s ease-out;
}

.block3 .circle,
.block3 .circle::before,
.block3 .circle::after {
  visibility: hidden;
  opacity: 0;
}
<!DOCTYPE html>
<html>

<head>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/css/bootstrap.min.css" integrity="sha512-t4GWSVZO1eC8BM339Xd7Uphw5s17a86tIZIj8qRxhnKub6WoyhnrxeCIMeAqBPgdZGlCcG2PrZjMc+Wr78+5Xg==" crossorigin="anonymous" referrerpolicy="no-referrer">

</head>

<body>
  <div class="block1"></div>
  <div class="container">
    <div class="block2">
      <div class="circle"></div>
      <div class="case">
        <div class="row">
          <div class="col-5 text">Text 1</div>
          <div class="col-2"></div>
          <div class="col-5 text">Text 1</div>
        </div>
      </div>
      <div class="case">
        <div class="row">
          <div class="col-5 text">Text 2</div>
          <div class="col-2"></div>
          <div class="col-5 text">Text 2</div>
        </div>
      </div>
      <div class="case">
        <div class="row">
          <div class="col-5 text text3">Text 3</div>
          <div class="col-2"></div>
          <div class="col-5 text text3">Text 3</div>
        </div>
      </div>
    </div>
    <div class="block3"></div>
  </div>

</body>

</html>
bejyjqdl

bejyjqdl2#

这是您的自定义滚动条。请注意,如果您希望能够抓取拇指并滚动,则需要添加额外的事件侦听器。尝试用鼠标滚轮滚动以查看效果。

const scrollBarEl = document.getElementsByClassName('scroll')[0];
const scrollEl = document.getElementsByClassName('outer-container')[0];
scrollEl.addEventListener('scroll', e => {
  const scrollSpan = scrollEl.scrollHeight - scrollEl.clientHeight;
  if (scrollSpan !== 0)
    scrollBarEl.style.setProperty('--scroll', `${scrollEl.scrollTop / scrollSpan * 100}%`)
})
.outer-container {
  max-height: 90vh;
  overflow: auto;
}

.container {
  min-height: 400vh;
}

.scroll {
  --scroll: 0%;
  position: fixed;
  right: 10px;
  top: 10px;
  bottom: 10px;
  width: 5px;
  background: linear-gradient(to bottom, #ff00, #ff0, #00f var(--scroll), #ff0, #ff00);
}

.thumb {
  height: 10px;
  width: 10px;
  border: 2px solid #00f;
  border-radius: 50%;
  background: #fff;
  position: absolute;
  top: calc(var(--scroll) - 6px);
  left: -4px;
}
<div class='outer-container'>
  <div class='container'>
    <div class='scroll'>
      <div class='thumb'></div>
    </div>
  </div>
</div>
y0u0uwnf

y0u0uwnf3#

这应该接近你想要实现的目标:

const circle = document.querySelector(".circle");
const cases = document.querySelectorAll(".case");

circle.style.transition = ""

const handleScroll = () => {
  const {
    height: blockHeight
  } = document.querySelector(".block2").getBoundingClientRect()

  const maxTop = cases[cases.length - 1].offsetTop + cases[cases.length - 1].offsetHeight - 200
  const minTop = cases[0].offsetTop

  let {
    height: startTop
  } = cases[0].getBoundingClientRect()

  const scrollDist = Math.min(maxTop, Math.max(startTop / 2 + window.scrollY, minTop))

  circle.style.top = `${scrollDist}px`
  circle.style.backgroundSize = `17px ${blockHeight}px`
  circle.style.backgroundPosition = `0 ${-scrollDist}px`
}

const handleWindowSizeAndScroll = () => {
  window.removeEventListener("scroll", handleScroll)
  window.removeEventListener("resize", handleScroll)
  window.addEventListener("scroll", handleScroll)
  window.addEventListener("resize", handleScroll)
}

handleScroll()
handleWindowSizeAndScroll()
window.addEventListener("resize", handleWindowSizeAndScroll)
.block1 {
  height: 200px;
  background-color: gray;
}

.block3 {
  height: 600px;
  background-color: gray;
}

.block2 {
  height: 100%;
  position: relative;
}

.block2 {
  background: linear-gradient(180deg, rgba(79, 142, 255, 0) 0%, #f5e550 140px, #f5e550 calc(100% - 140px), rgba(79, 142, 255, 0) 100%) center/3px calc(100% - 100px) no-repeat;
}

.block2 .circle {
  width: 17px;
  height: 17px;
  left: 50%;
  transform: translate(-50%, -50%);
}

.block2 .circle,
.block2 .circle::before {
  position: absolute;
  border-radius: 50%;
}

.block2 .circle .gradient-container::before {
  content: "";
  inset: 3px;
  background-color: white;
  position: absolute;
  background: #4f8eff;
  width: 27px;
  height: 60%;
  left: 50%;
  transform: translate(-50%, 32%);
  box-shadow: 0 0 40px 30px #4f8eff;
}

.block2 .circle .gradient-container {
  left: 50%;
  transform: translate(-50%, -50%);
  width: 3px;
  height: 40vh;
  z-index: 2;
  position: absolute;
  overflow: hidden;
}

.block2 .circle::after {
content: "";
    position: absolute;
    border-radius: 50%;
    background: white;
    width: 17px;
    height: 17px;
    left: 50%;
    transform: translate(-50%, 2px);
    z-index: 5;
    border: 4px solid #4f8eff;
}

.text {
  text-align: center;
  padding: 200px 50px;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/css/bootstrap.min.css" integrity="sha512-t4GWSVZO1eC8BM339Xd7Uphw5s17a86tIZIj8qRxhnKub6WoyhnrxeCIMeAqBPgdZGlCcG2PrZjMc+Wr78+5Xg==" crossorigin="anonymous" referrerpolicy="no-referrer"
/>
<div class="block1"></div>
<div class="block2">
  <div class="circle">
    <div class="gradient-container"></div>
  </div>
  <div class="case">
    <div class="row">
      <div class="col-5 text">Text 1</div>
      <div class="col-2"></div>
      <div class="col-5 text">Text 1</div>
    </div>
  </div>
  <div class="case">
    <div class="row">
      <div class="col-5 text">Text 2</div>
      <div class="col-2"></div>
      <div class="col-5 text">Text 2</div>
    </div>
  </div>
  <div class="case">
    <div class="row">
      <div class="col-5 text">Text 3</div>
      <div class="col-2"></div>
      <div class="col-5 text">Text 3</div>
    </div>
  </div>
</div>
<div class="block3"></div>

相关问题