一个交互式自定义光标,自动填充圆圈以指示当前滚动位置。
1.为自定义光标和滚动位置指示器编码HTML。
<div class="cursor" id="cursor"></div> <div class="cursor2" id="cursor2"> <div class="progress-wrap"> <svg class="progress-circle svg-content" width="100%" height="100%" viewBox="-1 -1 102 102"> <path d="M50,1 a49,49 0 0,1 0,98 a49,49 0 0,1 0,-98"/> </svg> </div> </div> <div class="cursor3" id="cursor3"></div>
2.自定义光标所需的CSS样式。
.cursor, .cursor2, .cursor3{ position: fixed; border-radius: 50%; transform: translateX(-50%) translateY(-50%); pointer-events: none; left: -100px; top: 50%; -webkit-transition: all 300ms linear; transition: all 300ms linear; } .cursor{ background-color: #fff; z-index: 99999; height: 0; width: 0; } .cursor2,.cursor3{ height: 46px; width: 46px; z-index:99998; -webkit-transition:all 0.3s ease-out; transition:all 0.3s ease-out } .cursor2.hover, .cursor3.hover{ -webkit-transform:scale(1.4) translateX(-35%) translateY(-35%); transform:scale(1.4) translateX(-35%) translateY(-35%); border:none } .cursor2.hover{ background: rgba(255,255,255,0.1); } .cursor2.hover .progress-wrap { box-shadow: inset 0 0 0 2px rgba(255,255,255,0); } .cursor2.hover .progress-wrap svg.progress-circle path { opacity: 0.4; }
3.设置滚动位置指示器的样式。
.progress-wrap { height: 46px; width: 46px; cursor: pointer; display: block; border-radius: 50px; box-shadow: inset 0 0 0 2px rgba(255,255,255,0.2); z-index: 10000; -webkit-transition: all 200ms linear; transition: all 200ms linear; } .progress-wrap svg path { fill: none; } .progress-wrap svg.progress-circle path { stroke: var(--grey); stroke-width: 4; box-sizing: border-box; -webkit-transition: all 200ms linear; transition: all 200ms linear; }
4.在文档末尾加载所需的jQuery库。
<script src="/path/to/cdn/jquery.slim.min.js"></script>
5.用于激活自定义光标和滚动位置指示器的主JavaScript。
(function($) { "use strict"; // Page cursors document.getElementsByTagName("body")[0].addEventListener("mousemove", function(n) { t.style.left = n.clientX + "px", t.style.top = n.clientY + "px", e.style.left = n.clientX + "px", e.style.top = n.clientY + "px", i.style.left = n.clientX + "px", i.style.top = n.clientY + "px" }); var t = document.getElementById("cursor"), e = document.getElementById("cursor2"), i = document.getElementById("cursor3"); function n(t) { e.classList.add("hover"), i.classList.add("hover") } function s(t) { e.classList.remove("hover"), i.classList.remove("hover") } s(); for (var r = document.querySelectorAll(".hover-target"), a = r.length - 1; a >= 0; a--) { o(r[a]) } function o(t) { t.addEventListener("mouseover", n), t.addEventListener("mouseout", s) } $(document).ready(function(){"use strict"; //Scroll indicator var progressPath = document.querySelector('.progress-wrap path'); var pathLength = progressPath.getTotalLength(); progressPath.style.transition = progressPath.style.WebkitTransition = 'none'; progressPath.style.strokeDasharray = pathLength + ' ' + pathLength; progressPath.style.strokeDashoffset = pathLength; progressPath.getBoundingClientRect(); progressPath.style.transition = progressPath.style.WebkitTransition = 'stroke-dashoffset 10ms linear'; var updateProgress = function () { var scroll = $(window).scrollTop(); var height = $(document).height() - $(window).height(); var progress = pathLength - (scroll * pathLength / height); progressPath.style.strokeDashoffset = progress; } updateProgress(); $(window).scroll(updateProgress); }); })(jQuery);