Search code examples
javascriptjqueryanimationvertical-scrolling

jQuery scrolling clock - limit to certain hours?


I've been working on this codeine to create a clock that updates as user scrolls. It seems to work fine for a 24 hour cycle but now I would like to modify it for only a portion of a day, from 6:00 AM to 8:00 PM (14 hours), for instance.

I did manage to "set" the clock on load to 6:00 using the CSS but that of course won't change the basic logic of the script which still wants a full page scroll to be 24 hours, not 14. I tried to dissect the JS/JQuery to figure out where that's defined but I can't seem to untangle it. I imagine it's somewhere in this block:

rotateElement('#svg-hour', progressToText(progress, 720, null, false));
        rotateElement('#svg-minute', progressToText(progress, (518400 / 60), null, false));

but I don't understand why the values of 720 and 518400 / 60 are used.

Can someone help point me in the right direction, please?


Solution

  • I removed some part of your code for simply it. you should use your code if you want.

    So you want to rotate hour and minute when you scroll and you want to start it from 6:00 AM

    what we should do here:

    • first we must rotate clock hour_stick to 6:00
    • limit maximum rotation hour to 20:00

    here is some explanation:

    • documentHeight - viewportHeight - this gives us how much we can scroll. Lets say this can_scroll
    • and we want to scroll it 20:00. so (can_scroll / 20) this gives us how much we should scroll for each hour.
    • and we want 20 hour so our maximum hour_stick degree is (360 / 12) * 20 = 600
    • we must rotate minute_stick to 360 degree for each hour.so maximum minute_stick degree is 20 * 360 = 7200.
    • and we want to start it from 6:00 AM so scroll window to $(window).scrollTop((documentHeight - viewportHeight) / 20 * 6); when document is ready.

    And here is code example:

    $(document).ready(function() {
    
        const documentHeight = $(document).height();
        var viewportHeight = window.innerHeight;
        function progressToText(progress, ratio) {
            return  (progress * ratio).toString();
        }
    
        function rotateElement(id, val) {
            $(id).css({
                transform: 'rotate(' + val + 'deg)',
                '-webkit-transform': 'rotate(' + val + 'deg)',
                '-ms-transform': 'rotate(' + val + 'deg)'
            });
        }
    
        function updateUI(progress) {
            rotateElement('#svg-hour', progressToText(progress, 600));
            rotateElement('#svg-minute', progressToText(progress, 7200));
            }
    
        function scrollClock(e) {
            var progress = $(window).scrollTop()/ (documentHeight - viewportHeight);
            updateUI(progress);
        };
      $(window).scrollTop((documentHeight - viewportHeight) / 20 * 6);
        $(window).scroll(_.throttle(function() {
            scrollClock();
        }, 80));
    });
    body {
      background-color: #3e4c53;
      height: 2400px;
      font-family: 'Open Sans', sans-serif;
    }
    
    #svg-clock {
      position: fixed;
      right: 500px;
        top: 50px;
        width: 150px; /* width of clock */
        height: 150px; /* height of clock */
        z-index: 999;
    }
    
    /* Clock styles */
    .circle {
      fill: none;
      stroke: #fff;
      stroke-width: 9;
      stroke-miterlimit: 10;
    }
    
    .mid-circle {
      fill: #fff;
    }
    
    .hour-marks {
      fill: none;
      stroke: #fff;
      stroke-width: 9;
      stroke-miterlimit: 10;
    }
    
    .hour-arm {
      fill: none;
      stroke: #fff;
      stroke-width: 17;
      stroke-miterlimit: 10;
    }
    
    .minute-arm {
      fill: none;
      stroke: #fff;
      stroke-width: 11;
      stroke-miterlimit: 10;
    }
    
    /* Transparent box ensuring arms center properly. */
    .sizing-box {
      fill: none;
    }
    
    /* Optional: Use transition for animation. */
    
    #svg-hour,
    #svg-minute,
    #svg-second {
      transform-origin: 300px 300px;
      transition: transform 0.5s ease-in-out;
    }
    
    #svg-hour {
     /*  transform: rotate(-180deg); */
    }
    <body>
    <!--svg clock-->
        <svg id="svg-clock" xmlns="http://www.w3.org/2000/svg" width="300" height="200" viewBox="0 0 600 600">
          <g id="face">
            <circle class="circle" cx="300" cy="300" r="253.9" />
            <path class="hour-marks" d="M300.5 94V61M506 300.5h32M300.5 506v33M94 300.5H60M411.3 107.8l7.9-13.8M493 190.2l13-7.4M492.1 411.4l16.5 9.5M411 492.3l8.9 15.3M189 492.3l-9.2 15.9M107.7 411L93 419.5M107.5 189.3l-17.1-9.9M188.1 108.2l-9-15.6" />
            <circle class="mid-circle" cx="300" cy="300" r="16.2" />
          </g>
          <g id="svg-hour">
            <path class="hour-arm" d="M300.5 298V142" />
            <circle class="sizing-box" cx="300" cy="300" r="253.9" />
          </g>
          <g id="svg-minute">
            <path class="minute-arm" d="M300.5 298V67" />
            <circle class="sizing-box" cx="300" cy="300" r="253.9" />
          </g>
        </svg>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js'></script>
    <!--<script src='https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.15.0/moment.min.js'></script>-->
    <script src='//cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.min.js'></script>
    </body>