英文:
Add a gradient background line to the circle
问题
I can help with that. Here's the translated content:
我在页面上有一个区块,在区块内有一条背景线,线上有一个随着主滚动一起滚动的圆圈。
问题是,如何使另一条与圆圈相同颜色的线随着圆圈一起滚动,并且看起来像这样:
[![点击此处输入图片描述][1]][1]
我尝试在之前添加样式,但没有达到我预期的效果
```css
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;
一切都应该像我发送的图片中那样,圆圈内部应该是白色的,当我们滚动到最顶部时,蓝色应该完全覆盖黄色,从底部也是一样的。在区块的中心,蓝色应该在圆圈上方和下方都存在,并保持渐变。
在我的示例中,几乎与我想要的一样,但不完全符合,我希望当蓝色线到达区块的末端或区块的开头时,蓝色完全覆盖黄色。而现在的情况是,当圆圈在顶部的最大位置时,黄色仍然在顶部。
<!-- 开始代码片段: js 隐藏: false 控制台: true babel: false -->
<!-- 语言: lang-js -->
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)
<!-- 语言: lang-css -->
.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;
}
<!-- 语言: lang-html -->
<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>
<!-- 结束代码片段 -->
<details>
<summary>英文:</summary>
I have a block on the page where there is a background line, on the line itself there is a circle that scrolls along with the main scroll
The question is, how can you make it so that, along with the circle, another line of the same color as the circle scrolls along the line, and it all would look something like this:
[![enter image description here][1]][1]
I tried adding styles to before, but it didn't work out what I expected
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;
Everything should be like in the picture that I threw off, the circle should be white inside, and the blue color should completely overlap the yellow when we scrolled to the very top, and the same from the bottom. And in the center of the block, let's say the blue color should be both above the circle and below, while maintaining the gradient
In my example, almost the same as I want, but not to the end, I want that when the blue line reaches the end of the block, or to the beginning of the block, then the blue color completely overlaps the yellow. And now it turns out that when the circle is at the maximum position in the top, then yellow colors remain on top
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
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)
<!-- language: lang-css -->
.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;
}
<!-- language: lang-html -->
<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>
<!-- end snippet -->
[1]: https://i.stack.imgur.com/a981w.png
</details>
# 答案1
**得分**: 2
以下是您的自定义滚动条。请注意,如果您想要抓住滑块并滚动,您需要添加额外的事件监听器。尝试使用鼠标滚轮滚动以查看效果。
```javascript
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>
英文:
Here's your custom scrollbar. Note that you need to add additional event listeners if you want to be able to grab the thumb and scroll. Try scrolling with mouse-wheel to see the effect.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
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}%`)
})
<!-- language: lang-css -->
.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;
}
<!-- language: lang-html -->
<div class='outer-container'>
<div class='container'>
<div class='scroll'>
<div class='thumb'></div>
</div>
</div>
</div>
<!-- end snippet -->
答案2
得分: 1
根据您对评论的回复,我认为您想要随着各个部分滚动圆圈。请在全屏中检查解决方案。
以下是代码部分,不需要翻译:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
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);
<!-- language: lang-css -->
/* CSS代码部分,不需要翻译 */
<!-- language: lang-html -->
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/css/bootstrap.min.css" integrity="sha512-t4GWSZ...(省略部分)">
</head>
<body>
<div class="block1"></div>
<div class="container">
<div class="block2">
<div class="circle"></div>
<div class="case">
<!-- 省略部分HTML代码 -->
</div>
<div class="case">
<!-- 省略部分HTML代码 -->
</div>
<div class="case">
<!-- 省略部分HTML代码 -->
</div>
</div>
<div class="block3"></div>
</div>
</body>
</html>
<!-- end snippet -->
希望这有助于您的项目!
英文:
As per your replies to comments, I believe that you want to scroll the circle along with the sections. Please check the solution in full screen
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
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);
<!-- language: lang-css -->
.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;
}
<!-- language: lang-html -->
<!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>
<!-- end snippet -->
答案3
得分: 1
这是你想要实现的代码的翻译部分:
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)
请注意,这是JavaScript代码的翻译部分。其他CSS和HTML部分没有被翻译,因为它们没有需要翻译的文本。
英文:
This should be close to what you want to achieve:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
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)
<!-- language: lang-css -->
.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;
}
<!-- language: lang-html -->
<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>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论