繁体   English   中英

如何使用JavaScript / CSS制作圆形ScrollBox?

[英]How to make a circular ScrollBox using JavaScript/CSS?

我想重新创建圆形滚动框,如下面的GIF所示,

在此输入图像描述

我不认为如果使用css制作圆形滚动框是有可能的,所以我想为ul每个子节点添加padding-left以使滚动框显示为圆形。

为达到这个,
向li-1添加0px的填充
向li-2添加2px的填充
添加4px的填充到li-3
添加6px的填充到li-4
在li-5中添加8px的填充
添加6px的填充到li-6
添加4px的填充到li-7
在li-8中添加2px的填充
添加0px的填充到li-9

可以更改滚动填充以向li-2添加0px的填充
添加2px的填充到li-3
添加4px的填充到li-4
添加6px的填充到li-5
向li-6添加8px的填充
添加6px的填充到li-7
添加4px的填充到li-8
在li-9中添加2px的填充
添加0px的填充到li-10等等......

我的代码问题是,当滚动框通过鼠标滚轮滚动时,它会正常运行,但当用户使用滚动条中的滚动标签/滚动按钮时,填充会急剧增加。

到目前为止我的代码是:

 var scrollBox = $(".circularScrollbox"), num = $(".scrollboxList li").length, vjListItem = $(".vjListItem"), max = num * 3, padding = 0, currentPadding = padding, scrollPos = scrollBox.scrollTop(); scrollBox.scroll(function() { if (scrollPos < scrollBox.scrollTop() && currentPadding < max) { currentPadding += 2; vjListItem.css("padding", "0 0 0 " + currentPadding + "px"); } else if (scrollPos > scrollBox.scrollTop() && currentPadding > padding) { currentPadding -= 2; vjListItem.css("padding", "0 0 0 " + currentPadding + "px"); } if (scrollBox.scrollTop() == 0) vjListItem.css("padding", padding + "px"); scrollPos = scrollBox.scrollTop(); }); 
 body { display: flex; flex-direction: column; height: 95vh; justify-content: center; align-items: center; background: #222; color: #eee; font-family: 'Ubuntu Mono', monospace; } .circularScrollbox { width: 200px; height: 10.6em; padding: 0 2em; overflow-Y: scroll; background: #161616; border: 2px solid aqua; } .circularScrollbox>ol { list-style-type: none; padding-left: 0; } 
 <head> <link href="https://fonts.googleapis.com/css?family=Ubuntu+Mono" rel="stylesheet"> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> </head> <body> <div class='circularScrollbox'> <ol class='scrollboxList'> <li class="vjListItem">Item 01</li> <li class="vjListItem">Item 02</li> <li class="vjListItem">Item 03</li> <li class="vjListItem">Item 04</li> <li class="vjListItem">Item 05</li> <li class="vjListItem">Item 06</li> <li class="vjListItem">Item 07</li> <li class="vjListItem">Item 08</li> <li class="vjListItem">Item 09</li> <li class="vjListItem">Item 10</li> <li class="vjListItem">Item 11</li> <li class="vjListItem">Item 12</li> <li class="vjListItem">Item 13</li> <li class="vjListItem">Item 14</li> <li class="vjListItem">Item 15</li> <li class="vjListItem">Item 16</li> <li class="vjListItem">Item 17</li> <li class="vjListItem">Item 18</li> <li class="vjListItem">Item 19</li> <li class="vjListItem">Item 20</li> <li class="vjListItem">Item 21</li> <li class="vjListItem">Item 22</li> <li class="vjListItem">Item 23</li> <li class="vjListItem">Item 24</li> <li class="vjListItem">Item 25</li> <li class="vjListItem">Item 26</li> <li class="vjListItem">Item 27</li> <li class="vjListItem">Item 28</li> <li class="vjListItem">Item 29</li> <li class="vjListItem">Item 30</li> <li class="vjListItem">Item 31</li> <li class="vjListItem">Item 32</li> <li class="vjListItem">Item 33</li> <li class="vjListItem">Item 34</li> <li class="vjListItem">Item 35</li> <li class="vjListItem">Item 36</li> <li class="vjListItem">Item 37</li> <li class="vjListItem">Item 38</li> <li class="vjListItem">Item 39</li> <li class="vjListItem">Item 40</li> </ol> </div> </body> 

我确信我的填充和填充问题过于复杂。 有没有更简单的方法来实现这种效果?

对于列表中的每个项目,填充量取决于:

  1. 它在盒子里的位置
  2. 滚动框的数量
  3. 而且由于“圆形”的东西,盒子有多大

使用jQuery, $item.offset().top为您提供页面上项目的Y位置。
这包括滚动,因此当滚动框时值会下降。

现在$item.offset().top - $box.offset().top 相对于框 $item.offset().top - $box.offset().top的位置。
如果您已滚动框以使项目23位于顶部,则其值将为0,并且任何项目的值位于底部(但仍然可见)将是框的高度。

因此除以高度: ($item.offset().top - $box.offset().top) / $box.height()

每个(可见)项目现在都有一个介于0和1之间的值,告诉您它当前位于框的顶部,底部还是介于两者之间的某个位置!

然后,您可以使用三角函数, Math.sin(value*Math.PI) * maxPaddingMath.sin(value*Math.PI) * maxPadding

工作实例

这是一个依赖CSS而且只有少量JS的解决方案。 诀窍是考虑shape-outside以获得曲线,JS将仅用于调整滚动形状的位置。

这是一个非常简单的方法,但您需要注意浏览器支持( https://caniuse.com/#feat=css-shapes

 var shape = document.querySelector(".left"); document.querySelector(".circularScrollbox").onscroll=function() { shape.style.marginTop = this.scrollTop+"px"; }; 
 body { display: flex; flex-direction: column; height: 95vh; justify-content: center; align-items: center; background: #222; color: #eee; font-family: 'Ubuntu Mono', monospace; } .circularScrollbox { width: 200px; height: 10.6em; padding: 0 2em; overflow-Y: scroll; background: #161616; border: 2px solid aqua; } .circularScrollbox>ol { list-style-type: none; padding-left: 0; } .left { float: left; shape-outside: ellipse(50px 85px at 0% calc(100% - 85px)); width: 100px; height: 100%; margin-top:0; } 
 <link href="https://fonts.googleapis.com/css?family=Ubuntu+Mono" rel="stylesheet"> <div class='circularScrollbox'> <div class="left"></div> <ol class='scrollboxList'> <li class="vjListItem">Item 01</li> <li class="vjListItem">Item 02</li> <li class="vjListItem">Item 03</li> <li class="vjListItem">Item 04</li> <li class="vjListItem">Item 05</li> <li class="vjListItem">Item 06</li> <li class="vjListItem">Item 07</li> <li class="vjListItem">Item 08</li> <li class="vjListItem">Item 09</li> <li class="vjListItem">Item 10</li> <li class="vjListItem">Item 11</li> <li class="vjListItem">Item 12</li> <li class="vjListItem">Item 13</li> <li class="vjListItem">Item 14</li> <li class="vjListItem">Item 15</li> <li class="vjListItem">Item 16</li> <li class="vjListItem">Item 17</li> <li class="vjListItem">Item 18</li> <li class="vjListItem">Item 19</li> <li class="vjListItem">Item 20</li> <li class="vjListItem">Item 21</li> <li class="vjListItem">Item 22</li> <li class="vjListItem">Item 23</li> <li class="vjListItem">Item 24</li> <li class="vjListItem">Item 25</li> <li class="vjListItem">Item 26</li> <li class="vjListItem">Item 27</li> <li class="vjListItem">Item 28</li> <li class="vjListItem">Item 29</li> <li class="vjListItem">Item 30</li> <li class="vjListItem">Item 31</li> <li class="vjListItem">Item 32</li> <li class="vjListItem">Item 33</li> <li class="vjListItem">Item 34</li> <li class="vjListItem">Item 35</li> <li class="vjListItem">Item 36</li> <li class="vjListItem">Item 37</li> <li class="vjListItem">Item 38</li> <li class="vjListItem">Item 39</li> <li class="vjListItem">Item 40</li> </ol> </div> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM