我正在尝试创建一个进度条,显示用户还剩多少特定元素可以查看。以下是一些详细信息:
.postProgressBar
默认显示在.postHeroImage
下- 当用户滚动时,我希望
.postProgressBar
根据剩余的.spacer
元素的滚动量慢慢填满。 - 当
.postProgressBar
到达header
底部时,我希望它固定
到header 底部
(并在.postHeroImage
再次出现时取消修复)。
查看我当前的方法:
$(function() {
gsap.registerPlugin(ScrollTrigger);
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 1) {
$(".header").addClass("fixed");
} else {
$(".header").removeClass("fixed");
}
});
var action = gsap.set('.postProgressBar', { position:'fixed', paused:true});
gsap.to('progress', {
value: 100,
ease: 'none',
scrollTrigger: {
trigger: "#startProgressBar",
scrub: 0.3,
markers:true,
onEnter: () => action.play(),
onLeave: () => action.reverse(),
onLeaveBack: () => action.reverse(),
onEnterBack: () => action.reverse(),
}
});
});
body {
background-color: lightblue;
--white: #FFFFFF;
--grey: #002A54;
--purple: #5D209F;
}
.header {
position: absolute;
top: 0;
width: 100%;
padding: 20px 15px;
z-index: 9999;
background-color: var(--white);
}
.header.fixed {
position: fixed;
background-color: var(--white);
border-bottom: 1px solid var(--grey);
}
.postHeroImage {
padding: 134px 0 0 0;
margin-bottom: 105px;
position: relative;
}
.postHeroImage__bg {
background-size: cover;
background-repeat: no-repeat;
width: 100%;
min-height: 400px;
}
progress {
position: absolute;
bottom: -15px;
left: 0;
-webkit-appearance: none;
appearance: none;
width: 100%;
height: 15px;
border: none;
background: transparent;
z-index: 9999;
}
progress::-webkit-progress-bar {
background: transparent;
}
progress::-webkit-progress-value {
background: var(--purple);
background-attachment: fixed;
}
progress::-moz-progress-bar {
background: var(--purple);
background-attachment: fixed;
}
.spacer {
height: 1000vh;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.0/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.0/ScrollTrigger.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="43212c2c37303731223303766d736d71" rel="noreferrer noopener nofollow">[email protected]</a>/dist/css/bootstrap.min.css" rel="stylesheet">
<body>
<header class="header">Header</header>
<section class="postHeroImage" id="startProgressBar">
<progress class="postProgressBar" max="100" value="0"></progress>
<div class="container">
<div class="row">
<div class="col-12">
<div class="postHeroImage__bg" style="background-image: url( 'https://picsum.photos/200/300' );" loading="lazy"></div>
</div>
</div>
</div>
</section>
<div class="spacer">lorum ipsum</div>
</body>
当前问题:
.postProgressBar
不会变为固定
(在检查模式下看不到固定
内联样式).postProgressBar
显示的进度根据剩余滚动的.spacer
数量并不准确。
最佳答案
- 职位 sticky在这里非常有用。您可以将其用于标题和进度栏。它会毫不费力地将元素固定在顶部。
- 为了获得准确的位置,您需要使用
scrollTrigger
的start
和end
属性。这将告诉 gsap 何时开始动画以及何时结束。最后,我们需要向滚动添加 64px(标题高度),因为我们的容器距视口(viewport)顶部下方 64px。
演示:
$(function() {
//read the css variable
let bodyStyles = window.getComputedStyle(document.body);
let headerHeight = bodyStyles.getPropertyValue('--header-height');
gsap.registerPlugin(ScrollTrigger);
gsap.to('progress', {
value: 100,
ease: 'none',
scrollTrigger: {
trigger: "#startProgressBar",
scrub: 0.3,
start: 'start 0px',
end: 'bottom' + headerHeight,
markers: true,
}
});
});
body {
background-color: lightblue;
--white: wheat;
--grey: #002A54;
--purple: #5D209F;
/* 40px padding top and bottom + 24px line height*/
--header-height: 64px;
}
.header {
/* position: absolute;*/
position: sticky;
top: 0;
width: 100%;
padding: 20px 15px;
z-index: 9999;
background-color: var(--white);
}
.postHeroImage {
padding: 134px 0 0 0;
margin-bottom: 105px;
position: relative;
}
.postHeroImage__bg {
background-size: cover;
background-repeat: no-repeat;
width: 100%;
min-height: 400px;
}
progress {
position: sticky;
top: var(--header-height);
left: 0;
-webkit-appearance: none;
appearance: none;
width: 100%;
height: 15px;
border: none;
background: transparent;
/*z-index: 9999;*/
}
progress::-webkit-progress-bar {
background: transparent;
}
progress::-webkit-progress-value {
background: var(--purple);
background-attachment: fixed;
}
progress::-moz-progress-bar {
background: var(--purple);
background-attachment: fixed;
}
.spacer {
height: 1000vh;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.0/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.0/ScrollTrigger.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6c0e0303181f181e0d1c2c59425c425e" rel="noreferrer noopener nofollow">[email protected]</a>/dist/css/bootstrap.min.css" rel="stylesheet">
<header class="header">Header</header>
<section class="postHeroImage" id="startProgressBar">
<progress class="postProgressBar" max="100" value="0"></progress>
<div class="container">
<div class="row">
<div class="col-12">
<div class="postHeroImage__bg" style="background-image: url( 'https://picsum.photos/id/705/300/200' );" loading="lazy"></div>
</div>
</div>
</div>
</section>
<div class="spacer">lorum ipsum</div>
您可以使用开始和结束属性。如果您只想跟踪内容的进度,请将
trigger
更改为 '.container'
。
无粘性的解决方案 这里我使用了固定位置:
$(function() {
//read the css variable
let bodyStyles = window.getComputedStyle(document.body);
let headerHeight = bodyStyles.getPropertyValue('--header-height');
gsap.registerPlugin(ScrollTrigger);
var action = gsap.set('.postProgressBar', {
position: 'fixed',
paused: true
});
ScrollTrigger.create({
trigger: '.postProgressBar',
start: 'top 64px',
onEnter: () => action.play(),
onLeaveBack: () => action.reverse(),
});
gsap.to('progress', {
value: 100,
ease: 'none',
scrollTrigger: {
trigger: "#mainContent",
scrub: 0.3,
end: 'bottom 110%',
markers: false,
}
});
});
* {
margin: 0;
padding: 0;
}
body {
background-color: lightblue;
--white: wheat;
--grey: #002A54;
--purple: #5D209F;
/* 40px padding top and bottom + 24px line height*/
--header-height: 64px;
position: relative;
height:100%
}
.header {
position: fixed;
top: 0;
width: 100%;
padding: 20px 15px;
z-index: 9999;
background-color: var(--white);
}
.postHeroImage {
padding: 134px 0 0 0;
margin-bottom: 105px;
position: relative;
margin-top: var(--header-height);
}
.postHeroImage__bg {
background-size: cover;
background-repeat: no-repeat;
width: 100%;
min-height: 400px;
}
progress {
position: static;
top: var(--header-height);
left: 0px;
-webkit-appearance: none;
appearance: none;
width: 100%;
height: 15px;
border: none;
background: transparent;
/*z-index: 9999;*/
}
progress::-webkit-progress-bar {
background: transparent;
}
progress::-webkit-progress-value {
background: var(--purple);
background-attachment: fixed;
}
progress::-moz-progress-bar {
background: var(--purple);
background-attachment: fixed;
}
.spacer {
height: 1000vh;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.0/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.0/ScrollTrigger.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c0a2afafb4b3b4b2a1b080f5eef0eef2" rel="noreferrer noopener nofollow">[email protected]</a>/dist/css/bootstrap.min.css" rel="stylesheet">
<header class="header">Header</header>
<section class="postHeroImage" id="startProgressBar">
<div class="container">
<div class="row">
<div class="col-12">
<div class="postHeroImage__bg" style="background-image: url( 'https://picsum.photos/id/705/300/200' );" loading="lazy"></div>
</div>
</div>
</div>
<progress class="postProgressBar" max="100" value="0"></progress>
</section>
<div id="mainContent" class="spacer">lorum ipsum</div>
关于javascript - GSAP:当进度条击中元素时固定进度条+进度条不准确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70481727/