Is it possible to emphasize a duration of 25 minutes on an analog clock by utilizing CSS gradients?

I am in the process of incorporating a countdown timer but with an analog clock rather than a digital one. My objective is to emphasize the next 25 minutes as a circle sector that commences from the minute hand on the clock.

Here is what I have developed so far: https://codepen.io/seifjo/pen/ExVQLOd

Below is the pertinent code extracted from the aforementioned codepen:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  background: #68a4ff;
}

.clock {
  width: 350px;
  height: 350px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #bcd0e7;
  border: 20px solid #fff;
  border-radius: 50%;
  background-size: cover;
  box-shadow: inset 0 0 30px rgba(0, 0, 0, .2), 0 20px 20px rgba(0, 0, 0, .2), 0 0 0 4px rgba(255, 255, 255, 1);
}

.clock {
  background-image: url(clock.png), linear-gradient(330deg, transparent 50%, #fff 50%), linear-gradient(540deg, #fff 50%, transparent 50%);
}

.clock::before {
  content: '';
  position: absolute;
  width: 15px;
  height: 15px;
  background: #848484;
  border: 2px solid #fff;
  border-radius: 50%;
  z-index: 10000;
}

.clock .hour,
.clock .min,
.clock .sec {
  position: absolute;
}

.clock .hour,
.hr {
  width: 160px;
  height: 160px;
}

.clock .min,
.mn {
  width: 190px;
  height: 190px;
}

.clock .sec,
.sc {
  width: 230px;
  height: 230px;
}

.hr,
.mn,
.sc {
  display: flex;
  justify-content: center;
  position: absolute;
  border-radius: 50%;
}

.hr::before {
  content: '';
  position: absolute;
  width: 8px;
  height: 80px;
  background: #848484;
  z-index: 10;
  border-radius: 6px 6px 0 0;
}

.mn:before {
  content: '';
  position: absolute;
  width: 4px;
  height: 90px;
  background: #d6d6d6;
  z-index: 11;
  border-radius: 6px 6px 0 0;
}

.sc:before {
  content: '';
  position: absolute;
  width: 2px;
  height: 150px;
  background: #ff6767;
  z-index: 12;
  border-radius: 6px 6px 0 0;
}
<div class="clock">
  <div class="mask"></div>
  <div class="hour">
    <div class="hr" id="hr">

    </div>
  </div>
  <div class="min">
    <div class="mn" id="mn">

    </div>
  </div>
  <div class="sec">
    <div class="sc" id="sc">

    </div>
  </div>
</div>
<script>
  const deg = 6;
  const hr = document.querySelector("#hr");
  const mn = document.querySelector("#mn");
  const sc = document.querySelector("#sc");
  setInterval(() => {
    let day = new Date();
    let hh = day.getHours() * 30;
    let mm = day.getMinutes() * deg;
    let ss = day.getSeconds() * deg;

    hr.style.transform = `rotateZ(${(hh)+(mm/12)}deg)`;
    mn.style.transform = `rotateZ(${mm}deg)`;
    sc.style.transform = `rotateZ(${ss}deg)`;
  }, 1000);
</script>

I have successfully indicated the next 25 minutes beginning from 3 o'clock. However, I am struggling to determine the relationship between the minutes and the degrees. Eventually, this will evolve into a react app where I will pass the current minute as a prop.

Answer №1

To cater to the current time, I have made adjustments by removing the style from the CSS and recalculating it in the script.

It is important to understand that this solution is designed for highlight periods that are less than or equal to 30 minutes. This limitation arises from using a background image of a half circle. If the highlight period exceeds 30 minutes, additional measures need to be taken such as incorporating another second half circle and controlling their overlap to extend the highlighted sector beyond 30 minutes.

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  background: #68a4ff;
}

.clock {
  width: 350px;
  height: 350px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #bcd0e7;
  border: 20px solid #fff;
  border-radius: 50%;
  background-size: cover;
  box-shadow: inset 0 0 30px rgba(0, 0, 0, .2), 0 20px 20px rgba(0, 0, 0, .2), 0 0 0 4px rgba(255, 255, 255, 1);
}

.clock::before {
  content: '';
  position: absolute;
  width: 15px;
  height: 15px;
  background: #848484;
  border: 2px solid #fff;
  border-radius: 50%;
  z-index: 10000;
}

.clock .hour,
.clock .min,
.clock .sec {
  position: absolute;
}

.clock .hour,
.hr {
  width: 160px;
  height: 160px;
}

.clock .min,
.mn {
  width: 190px;
  height: 190px;
}

.clock .sec,
.sc {
  width: 230px;
  height: 230px;
}

.hr,
.mn,
.sc {
  display: flex;
  justify-content: center;
  position: absolute;
  border-radius: 50%;
}

.hr::before {
  content: '';
  position: absolute;
  width: 8px;
  height: 80px;
  background: #848484;
  z-index: 10;
  border-radius: 6px 6px 0 0;
}

.mn:before {
  content: '';
  position: absolute;
  width: 4px;
  height: 90px;
  background: #d6d6d6;
  z-index: 11;
  border-radius: 6px 6px 0 0;
}

.sc:before {
  content: '';
  position: absolute;
  width: 2px;
  height: 150px;
  background: #ff6767;
  z-index: 12;
  border-radius: 6px 6px 0 0;
}
<div class="clock">
  <div class="mask"></div>
  <div class="hour">
    <div class="hr" id="hr">

    </div>
  </div>
  <div class="min">
    <div class="mn" id="mn">

    </div>
  </div>
  <div class="sec">
    <div class="sc" id="sc">

    </div>
  </div>
</div>
<script>
  const deg = 6;
  const hr = document.querySelector("#hr");
  const mn = document.querySelector("#mn");
  const sc = document.querySelector("#sc");
  setInterval(() => {
    let day = new Date();
    let hh = day.getHours() * 30;
    let mm = day.getMinutes() * deg;
    let ss = day.getSeconds() * deg;

    hr.style.transform = `rotateZ(${(hh)+(mm/12)}deg)`;
    mn.style.transform = `rotateZ(${mm}deg)`;
    sc.style.transform = `rotateZ(${ss}deg)`;
  }, 1000);

  let lauchTime = new Date();
  let clock = document.querySelector('.clock');
  let startDeg = ((lauchTime.getMinutes() * deg) + 360 - 90) % 360;
  let highlightPeriod = 25;
  let endDeg = startDeg + (highlightPeriod * deg);

clock.style.backgroundImage = `linear-gradient(${startDeg}deg, transparent 50%,  #fff 50%), linear-gradient(${endDeg}deg,  #fff 50%, transparent 50%)`;
</script>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

CSS Vertical Accordion Menu

I am struggling to modify the vertical accordion menu CSS. I am having difficulty adjusting the sub-menu list items. <div id="menuleft"> <div class="top">header</div> <ul> <li><a href="#">Main 1</a> ...

Are you in need of a BISON middleware solution for socket.io encoding and decoding?

Is there a method to manipulate the data transmitted by socket.io just before it is sent or received? I was considering implementing something like an express middleware. This way, I could encode the data after the normal .emit() call and before the socket ...

Creating a legitimate svg element using javascript

While working with SVG, I had an issue where I added a <rect> element directly into the svg using html, and then created a new element (without namespace) <circle> with javascript. However, the <circle> element did not display in the svg ...

Why isn't my AJAX POST request to PHP functioning correctly?

It was all working perfectly fine earlier, but now something seems off and I must have made a mistake somewhere. I'm in the process of setting up a form where the information entered is sent via AJAX to my PHP file, which then outputs the username an ...

What is the reason behind the browser not reusing the authorization headers following an authenticated XMLHttpRequest?

As I work on developing a Single Page Application using Angular, I have encountered an interesting challenge. The backend system exposes REST services that require Basic authentication. Surprisingly, while obtaining index.html or any of the scripts does no ...

Transferring the values of JavaScript objects to HTML as strings

My goal is to generate HTML elements based on the values of specific JavaScript objects that are not global variables. However, when attempting to execute the code below, I encounter an error stating "params is not defined." What I actually aim to achieve ...

Angular Igx-calendar User Interface Component

I need assistance with implementing a form that includes a calendar for users to select specific dates. Below is the code snippet: Here is the HTML component file (about.component.html): <form [formGroup]="angForm" class="form-element"> <d ...

The prototype chaining for JavaScript inheritance was not functioning as expected

I have been studying Stoyan Stefanov's book on JavaScript Patterns and I seem to be stuck...I am having trouble inheriting the prototype. What could I possibly be doing wrong? (Please execute this code in NodeJS) // implementing inheritance function ...

The function angular.factory does not exist

Hey there! I am encountering an error in the title related to my factory. Any suggestions on how I can resolve this issue? (function (angular,namespace) { var marketplace = namespace.require('private.marketplace'); angular.factory(&apo ...

When using Javascript to append content to the body, it may not be displayed as HTML on

My current project involves creating an HTML document through JavaScript templates. In the code snippet below, I have a const button which serves as my template. By using the replace method, I am able to update the content within the button template from c ...

Animating sprites using TypeScript

I've been tackling the development of a small Mario game lately. However, I'm facing some difficulty when it comes to animating sprites. For instance, I have a mario.gif file featuring running Mario (although he's not actually running in th ...

How to Use Vanilla JavaScript to Fetch a JSON File, Convert the Data into an Array, and Iterate Through Each Object

Imagine having a JSON file called map.json: { "images":{ "background": ["images/mountains.png","images/sea.png"] } } The goal is for JavaScript to retrieve "images/mountains.png" from map.json and us ...

Determining the repetition and placement of background images when employing multiple backgrounds

Is it possible to apply two background images to the same div? I want one image to repeat along the x-axis and the other to appear only once. I've tried using multiple background images, but I'm not sure how to target specific rules for each bac ...

Tips for only retrieving specific data from a JSON call

Is there a way to modify this code so that it only retrieves 5 items from the database? I would like to have a "get more" button to fetch another set of 5 items. The current code pulls in all available items: $.ajax({ url: 'getFeed.php', ...

When using .map() to iterate through an array of objects in Next.js, why does the data display in the console but

I'm facing an issue with displaying the elements of an array in HTML. I'm fetching data from the Bscscan API and while I can retrieve data successfully from the first API, the second one doesn't display the data in the local browser. I' ...

Perform batch updates on multiple documents using MongoDB

How can I efficiently update multiple documents in MongoDB by iterating through an array of objects and then returning the modified documents in the response? Be sure to refer to the code comments for guidance .put(function (req, res) { var data = r ...

Error message: "Attempting to assign a value to the 'size' property of an undefined object, despite the fact that

I recently started delving into NodeJS development and have configured Visual Studio Code for JavaScript development in node applications. During a Pluralsight lecture on Objects, the instructor demonstrated creating two scripts, dice.js and program.js, a ...

Merging two arrays concurrently in Angular 7

When attempting to merge two arrays side by side, I followed the procedure below but encountered the following error: Cannot set Property "account" of undefined. This is the code in question: acs = [ { "account": "Cash In Hand", ...

Is there a way to customize the CSS ul menu specifically for the JavaScript autocomplete feature?

I have created a search page with autocomplete for the first textbox, but I noticed that the ul/li CSS classes used for styling the main menu are impacting the JavaScript list. How can I override the menu styling to display a regular list format? Being a ...

Interval function failing to update information on Jade template

Currently, I am working on a Node app using Express and Jade. My aim is to retrieve JSON data from an API and have it refresh on the page periodically. To achieve this, I have created an empty div where I intend to inject the contents of a different route/ ...