gsap+ScrollTrigger实现可拐角弯曲的滚动条效果代码
代码语言:html
所属分类:加载滚动
代码描述:gsap+ScrollTrigger实现可拐角弯曲的滚动条效果代码,配合dat.gui可修改参数
代码标签: gsap ScrollTrigger 拐角 弯曲 滚动条
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <style> *, *:after, *:before { box-sizing: border-box; } :root { --size: 300px; --radius: 32; --padding: 64px; --bg: hsl(180 0% 33%); --bar: hsl(0 0% 100% / 0.5); --panel: hsl(20 60% 50%); timeline-scope: --scroller; } body { display: grid; place-items: center; min-height: 100vh; background: hsl(0 0% 2%); font-family: "SF Pro Text", "SF Pro Icons", "AOS Icons", "Helvetica Neue", Helvetica, Arial, sans-serif, system-ui; } /** * Think the idea here would be to translate a fake scrollbar up/down * Clip the edges and rotate a clipped bordered element on the ends * If we need the fatness, we need to go with something like a morphing SVG * Or we might get away with transform-origin 100% 0 and scale 1.1 to get the thicc * Might be easier to drop two SVG at each end though for that. * */ .scroller { position: relative; width: 300px; aspect-ratio: 3 / 4; resize: both; overflow: hidden; padding: 0 0.5rem 0 0; } .bar__thumb, .bar__track { opacity: 0; transition: opacity 0.2s; } [data-rounded-scroll] .scroller :is(.bar__thumb, .bar__track) { opacity: 1; } .scroller > svg { position: absolute; top: 0; bottom: 0; right: 0.5rem; pointer-events: none; height: 100%; width: calc(var(--radius) * 2px); overflow: visible !important; } [data-rounded-scroll] .scroller ul::-webkit-scrollbar { display: none; } [data-rounded-scroll] ul::-webkit-scrollbar { display: none; opacity: 0 !important; } [data-rounded-scroll] .scroller ul { scrollbar-width: 0; scrollbar-width: none; -ms-overflow-style: none; } .scroller path { stroke-width: calc(var(--stroke-width) * 1px); } .bar__thumb { stroke: hsl(0 0% 100% / var(--bar-alpha, 0.5)); stroke-dasharray: var(--thumb-size) var(--track-length); } @supports (animation-timeline: scroll()) { .bar__thumb { -webkit-animation: scroll both linear; animation: scroll both linear; animation-timeline: --scroller; } } /* Keyframes are generated via JavaScript for dynamic stuff */ .bar__track { stroke: hsl(0 0% 100% / var(--track-alpha, 0)); } .scroller ul { height: 100%; width: 100%; overflow: auto; background: var(--bg); border-radius: calc(var(--radius) * 1px); display: grid; grid-auto-flow: row; gap: 1rem; margin: 0; padding: calc(var(--padding) * 1px) 0; list-style-type: none; -ms-scroll-snap-type: y mandatory; scroll-snap-type: y mandatory; scroll-timeline: --scroller; scroll-behavior: smooth; } .scroller li { background: var(--panel); height: calc(var(--size) * 0.75); width: 100%; border-radius: calc(var(--radius) * 1px); scroll-snap-align: center; } .scroller li:first-of-type { scroll-snap-align: start; } .scroller li:last-of-type { scroll-snap-align: end; } body::before { --line: hsl(0 0% 95% / 0.15); content: ""; height: 100vh; width: 100vw; position: fixed; background: linear-gradient(90deg, var(--line) 1px, transparent 1px 10vmin) 0 -5vmin / 10vmin 10vmin, linear-gradient(var(--line) 1px, transparent 1px 10vmin) 0 -5vmin / 10vmin 10vmin; -webkit-mask: linear-gradient(-15deg, transparent 30%, white); mask: linear-gradient(-15deg, transparent 30%, white); top: 0; z-index: -1; transform: translate3d(0, 0, -100vmin); } </style> </head> <body > <div class="scroller"> <svg class="scroller__bar bar" viewBox="0 0 56 56" xmlns="http://www.w3.org/2000/svg"> <path class="bar__thumb" fill="none" stroke-linecap="round" /> <path class="bar__track" fill="none" stroke-linecap="round" /> </svg> <ul> <li></li> <li></li> <li></li> <li></li> <li></li> </ul> <style id="scroller-frames"></style> </div> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/gsap.3.12.2.js"></script> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/ScrollTrigger.3.10.4.js"></script> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/dat.gui-min.js"></script> <script > const scroller = document.querySelector('.scroller'); const list = scroller.querySelector('ul'); const bar = scroller.querySelector('.scroller__bar'); const track = scroller.querySelector('.bar__track'); const thumb = bar.querySelector('.bar__thumb'); const styles = scroller.querySelector('style'); const CONFIG = { show: true, radius: 32, scrollPadding: 100, stroke: 7, inset: 4, trail: 0, track: true, thumb: 80, finish: 5, alpha: 0.75, track: 0, cornerLength: 0 }; /** * Set up a ResizeObserver that syncs the SVG path and viewBox * with the size of the scroller. If you have a static sized scroller * and radius, etc. You can take a snapshot of it and use it over and over. * The ResizeObserver is mainly for demo purposes so you can make what you * want. * */ const syncBar = scrollerBar => { const mid = CONFIG.radius; const innerRad = Math.max( 0, CONFIG.radius - (CONFIG.inset + CONFIG.stroke * 0.5)); const padTop = CON.........完整代码请登录后点击上方下载按钮下载查看
网友评论0