![](/img/trans.png)
[英]How to make a circular menu on Scroll using JavaScript/CSS with repeating item?
[英]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>
我确信我的填充和填充问题过于复杂。 有没有更简单的方法来实现这种效果?
对于列表中的每个项目,填充量取决于:
使用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) * maxPadding
: Math.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.