基于transform与matrix3d的自定义滚动条:如何实现水平滚动条?
用matrix3d实现水平自定义滚动条(基于现有垂直方案)
要实现水平自定义滚动条,逻辑和你已有的垂直版本完全对应,只需将高度维度的计算替换为宽度维度,同时调整transform的原点与方向。以下是完整实现代码:
HTML 结构
<div class="container"> <div class="v-thumb"></div> <!-- 垂直滚动条 --> <div class="h-thumb"></div> <!-- 新增水平滚动条 --> <div class="content"></div> <!-- 撑出滚动的内容 --> </div>
CSS 样式
.container { position: relative; width: 180px; height: 180px; border: 1px solid black; perspective: 1px; overflow: scroll; } /* 垂直滚动条样式 */ .v-thumb { position: absolute; top: 0; right: 0; background-color: red; transform-origin: top right; width: 20px; } /* 水平滚动条样式 */ .h-thumb { position: absolute; bottom: 0; left: 0; background-color: blue; transform-origin: bottom left; height: 20px; } /* 同时撑出垂直和水平滚动的内容 */ .content { width: 400px; height: 400px; }
JavaScript 逻辑
const scroller = document.querySelector('.container'); const vThumb = document.querySelector('.v-thumb'); const hThumb = document.querySelector('.h-thumb'); // 垂直滚动条原有逻辑保留 const scrollerHeight = scroller.getBoundingClientRect().height; const vThumbHeight = scrollerHeight * scrollerHeight / scroller.scrollHeight; const factorY = (scrollerHeight - vThumbHeight) / (scroller.scrollHeight - scrollerHeight); vThumb.style.height = vThumbHeight + 'px'; vThumb.style.right = (scroller.clientWidth - scroller.getBoundingClientRect().width) + 'px'; vThumb.style.transform = ` matrix3d(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,-1) scale(${1/factorY}) translateZ(${1 - 1/factorY}px) translateZ(-2px) `; // 水平滚动条对应逻辑(替换为宽度维度计算) const scrollerWidth = scroller.getBoundingClientRect().width; const hThumbWidth = scrollerWidth * scrollerWidth / scroller.scrollWidth; const factorX = (scrollerWidth - hThumbWidth) / (scroller.scrollWidth - scrollerWidth); hThumb.style.width = hThumbWidth + 'px'; hThumb.style.bottom = (scroller.clientHeight - scroller.getBoundingClientRect().height) + 'px'; hThumb.style.transform = ` matrix3d(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,-1) scale(${1/factorX}) translateZ(${1 - 1/factorX}px) translateZ(-2px) `;
关键调整说明
- DOM结构:新增水平滚动条元素
.h-thumb,用.content同时撑出垂直和水平滚动空间 - CSS定位:水平滚动条定位在容器底部左侧,transform原点设为
bottom left,确保缩放方向匹配滚动逻辑 - 参数计算:将垂直方向的
height、scrollHeight全部替换为水平方向的width、scrollWidth,计算逻辑完全对称 - Transform逻辑:matrix3d的翻转效果保留,scale使用水平方向的因子
1/factorX,translateZ的透视偏移逻辑与垂直版本一致
内容的提问来源于stack exchange,提问作者Murhaf Sousli
相关产品推荐
相关产品推荐

