Nahorniak Templates
База референсів шаблонів і компонентів
Назад до шаблону · Runok - Web Agency HTML5 Template
c222

scroll-progress-orb

Декор·Шаблон: Runok - Web Agency HTML5 Template·Складність анімації: medium·Адаптивний: Так
scroll-progress-orb

Файли-джерела

  • index.htmlheader.header.sticky-active

Бібліотеки

jquery

Summary

A fixed bottom-right circular orb that displays the page scroll percentage and doubles as a back-to-top trigger. The fill ring is painted with a CSS conic-gradient written each frame from JavaScript; once scroll passes 96 % the percentage text swaps to an up-arrow icon and clicking the orb scrolls smoothly to top.

HTML structure (minimal)

<div id="scroll-percentage">
  <span id="scroll-percentage-value"></span>
</div>

Key SCSS tokens

#scroll-percentage {
  position: fixed; bottom: 30px; right: 30px;
  width: 50px; height: 50px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: conic-gradient(var(--rr-color-theme-primary) 0%, #fff 0%);
  cursor: pointer; opacity: 0; visibility: hidden;
  transition: opacity .3s ease, visibility .3s ease;
  z-index: 990;
  &.active { opacity: 1; visibility: visible; }
  &::before {
    content: ""; position: absolute; inset: 4px; background: var(--rr-color-bg-1);
    border-radius: 50%; z-index: -1;
  }
  #scroll-percentage-value {
    color: var(--rr-color-common-white); font-size: 12px; font-weight: 700;
  }
}

Animation logic

function scrollTopPercentage() {
  const scrollPercentage = () => {
    const scrollTopPos = document.documentElement.scrollTop;
    const calcHeight   = document.documentElement.scrollHeight - document.documentElement.clientHeight;
    const scrollValue  = Math.round((scrollTopPos / calcHeight) * 100);
    const wrap         = $("#scroll-percentage");

    wrap.css(
      "background",
      `conic-gradient( var(--rr-color-theme-primary) ${scrollValue}%, var(--rr-color-common-white) ${scrollValue}%)`
    );
    wrap.toggleClass("active", scrollTopPos > 100);

    if (scrollValue < 96) {
      $("#scroll-percentage-value").text(`${scrollValue}%`);
    } else {
      $("#scroll-percentage-value").html('<i class="fa-sharp fa-regular fa-arrow-up-long"></i>');
    }
  };
  window.onscroll = scrollPercentage;
  window.onload   = scrollPercentage;

  $("#scroll-percentage").on("click", function () {
    document.documentElement.scrollTo({ top: 0, behavior: "smooth" });
  });
}
scrollTopPercentage();

Notable details

  • The progress ring is a single conic-gradient; the inner circle (::before) sits at inset: 4px to leave a 4-px ring visible — no SVG, no <canvas>, just CSS.
  • The percentage text doubles as an icon: < 96% shows numeric 42%; ≥ 96% swaps to a FontAwesome arrow-up-long glyph signalling "you can use me to go back to top".
  • Element is hidden by default (opacity 0); .active class is added once scrollTop > 100, keeping the orb out of the way during the hero.

Use when

  • Long single-page agency sites that want both a progress indicator AND a back-to-top affordance in one element.
  • Sites already using a flat dark surface where an SVG ring would feel over-engineered.

Caveats

  • window.onscroll = … overwrites any previously assigned handler; integrate via addEventListener if other scripts need the same event.
  • The conic-gradient updates on every scroll tick without rAF throttling — fine on modern hardware but worth wrapping in requestAnimationFrame for older devices.