Analog Clock's Hands not Working Properly - javascript

Something is wrong in java script section of the code
The hour hand is not working properly. It is rotating after every 60 seconds.
Also, the minute hand is showing the wrong time. Please check the formula written in js. The formula I have used was also written by gfg. Please explain the necessary changes. Thank you.
const secHand=document.querySelector('.second-hand');
const minhand=document.querySelector('.minute-hand');
const hrhand=document.querySelector('.hour-hand');
function setDate(){
const d=new Date();
const hr=d.getHours();
const m=d.getMinutes();
const sethrdeg= 30*hr + m/2;
hrhand.style.transform=`rotate(${sethrdeg}deg)`;
const setmdeg=6*m;
minhand.style.transform=`rotate(${setmdeg}deg)`;
const s=d.getSeconds();
const setsdeg=6*s;
secHand.style.transform=`rotate(${setsdeg}deg)`;
}
setInterval(setDate,1000);
*{
background:url(https://images.unsplash.com/photo-1523821741446-edb2b68bb7a0?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxleHBsb3JlLWZlZWR8MXx8fGVufDB8fHx8&w=1000&q=80);
margin: 0;
padding: 0;
font-family: Georgia, 'Times New Roman', Times, serif;
background-size: cover;
}
body{
display: flex;
height: 100vh;
align-items: center;
}
.clock{
border : 3px solid black;
border-radius: 50%;
padding: 5px;
position: relative;
left:30rem;
width: 25rem;
height: 25rem;
justify-content: center;
box-shadow:
0 0 0 4px rgba(0,0,0,0.1),
inset 0 0 0 3px #EFEFEF,
inset 0 0 10px black,
0 0 10px rgba(0,0,0,0.2);
}
.clock-face{
position :relative;
transform: translateY(-3px);
}
.hand{
background: white;
width: 48%;
height: 1.5%;
position: absolute;
top :50%;
transform-origin: 100%;
transform: rotate(90deg);
transition: all 0.06s;
transition-timing-function: cubic-bezier(0.1, 1.09, 0.52, 1.26);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Clock</title>
<link rel="stylesheet" href="clock.css">
</head>
<body>
<div class="clock">
<div class="clock-face"></div>
<div class="hand hour-hand"></div>
<div class="hand minute-hand"></div>
<div class="hand second-hand"></div>
</div>
<script src="clock.js"></script>
</body>
</html>

The issue about the mispositionned hands was due to the 90 degres rotation needed to show 00:00:00. So in the calculation, you always have to add this 90 degres.
About the calculation itself:
The clock has 360 degres for 12 hours (360/12) and for 60 minutes/seconds (360/60).
To have the hours hand constantly moving beween the hour knotches instead of jumping to it: The hour knotch is (360 * hr) / 12 and the minutes elapsed in this hour is (360 * m) / (12 * 60).
The same concept applies for the minutes hand.
Lastly, the seconds hand was strangely jumping when passing from 59 to 0. That was due to the rotation going from 359 degres to zero instead of going to 360. So in fact the hand was animated backward (counter clockwize) very fast. To fix that, I simply added a line to remove the transition animation when at 0 second.
secHand.classList.toggle("hand-transition", s != 0);
Have a look at .toggle([class],[force]).
const secHand = document.querySelector(".second-hand");
const minhand = document.querySelector(".minute-hand");
const hrhand = document.querySelector(".hour-hand");
function setDate() {
const d = new Date();
const hr = d.getHours();
const m = d.getMinutes();
const s = d.getSeconds();
// Remove the transition at 0 sec.
secHand.classList.toggle("hand-transition", s != 0);
const sethrdeg = (360 * hr) / 12 + (360 * m) / (12 * 60) + 90; // 30 * hr + m / 2;
hrhand.style.transform = `rotate(${sethrdeg}deg)`;
const setmdeg = (360 * m) / 60 + (360 * s) / (60 * 60) + 90; // 6 * m;
minhand.style.transform = `rotate(${setmdeg}deg)`;
const setsdeg = (360 / 60) * s + 90; // 6 * s;
secHand.style.transform = `rotate(${setsdeg}deg)`;
}
setInterval(setDate, 1000);
* {
background: url(https://images.unsplash.com/photo-1523821741446-edb2b68bb7a0?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxleHBsb3JlLWZlZWR8MXx8fGVufDB8fHx8&w=1000&q=80);
margin: 0;
padding: 0;
font-family: Georgia, "Times New Roman", Times, serif;
background-size: cover;
}
body {
display: flex;
height: 100vh;
align-items: center;
}
.clock {
border: 3px solid black;
border-radius: 50%;
padding: 5px;
position: relative;
left: 30rem;
width: 25rem;
height: 25rem;
justify-content: center;
box-shadow: 0 0 0 4px rgba(0, 0, 0, 0.1), inset 0 0 0 3px #efefef,
inset 0 0 10px black, 0 0 10px rgba(0, 0, 0, 0.2);
}
.clock-face {
position: relative;
transform: translateY(-3px);
}
.hand {
background: white;
width: 48%;
height: 1.5%;
position: absolute;
top: 50%;
transform-origin: 100%;
transform: rotate(90deg);
}
/* Specific class for the transition, so it can be removed */
.hand-transition {
transition: all 0.06s;
transition-timing-function: cubic-bezier(0.1, 1.09, 0.52, 1.26);
}
.minute-hand {
background: blue;
}
.hour-hand {
background: red;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Clock</title>
<link rel="stylesheet" href="clock.css">
</head>
<body>
<div class="clock">
<div class="clock-face"></div>
<div class="hand hour-hand"></div>
<div class="hand minute-hand"></div>
<div class="hand second-hand"></div>
</div>
<script src="clock.js"></script>
</body>
</html>
CodePen

Related

Two clocks side by side

Sorry if this has been asked a million times already, i'm quite new with this so it's difficult for me to understand some of the responses. I am trying to have two analog clocks side by side, ticking away. I am not sure why this code isn't showing that.
I would like to make a simple website of multiple timezones shown on each clock, but for now they can all be the same time.
const secondHand = document.querySelector('.second-hand');
const minsHand = document.querySelector('.min-hand');
const hourHand = document.querySelector('.hour-hand');
function setDate() {
const now = new Date();
const seconds = now.getSeconds();
const secondsDegrees = ((seconds / 60) * 360) + 90;
secondHand.style.transform = `rotate(${secondsDegrees}deg)`;
const mins = now.getMinutes();
const minsDegrees = ((mins / 60) * 360) + ((seconds / 60) * 6) + 90;
minsHand.style.transform = `rotate(${minsDegrees}deg)`;
const hour = now.getHours();
const hourDegrees = ((hour / 12) * 360) + ((mins / 60) * 30) + 90;
hourHand.style.transform = `rotate(${hourDegrees}deg)`;
}
setInterval(setDate, 1000);
setDate();
html {
background: #018DED url(https://unsplash.it/1500/1000?image=881&blur=5);
background-size: cover;
font-family: 'helvetica neue';
text-align: center;
font-size: 10px;
}
body {
margin: 0;
font-size: 2rem;
display: flex;
flex: 1;
min-height: 100vh;
align-items: center;
}
.clock,
.clocktwo {
width: 30rem;
height: 30rem;
border: 20px solid white;
border-radius: 50%;
margin: 50px auto;
position: relative;
padding: 2rem;
box-shadow: 0 0 0 4px rgba(0, 0, 0, 0.1), inset 0 0 0 3px #EFEFEF, inset 0 0 10px black, 0 0 10px rgba(0, 0, 0, 0.2);
}
.clock-face,
.clock-facetwo {
position: relative;
width: 100%;
height: 100%;
transform: translateY(-3px);
/* account for the height of the clock hands */
}
.hand,
.handtwo {
width: 50%;
height: 6px;
background: black;
position: absolute;
top: 50%;
/* transform-origin will allow us to rotate the clock hands along the x axis, so it */
transform-origin: 100%;
transform: rotate(90deg);
transition: all 0.5s;
transition-timing-function: cubic-bezier(0.1, 2.7, 0.58, 1);
}
<div class="clock">
<div class="clock-face">
<div class="hand hour-hand"></div>
<div class="hand min-hand"></div>
<div class="hand second-hand"></div>
</div>
</div>
<div class="clocktwo">
<div class="clock-facetwo">
<div class="handtwo hour-hand"></div>
<div class="handtwo min-hand"></div>
<div class="handtwo second-hand"></div>
</div>
</div>
The problem is that you have multiple (two to be exact) of each (second, min, hour) clock 'hands'. But you use querySelector which will only select the first (from top to bottom of the HTML structure) element it finds.
What you need to do, is to select all of them using e.g. querySelectorAll and then loop over them.
const secondHand = document.querySelectorAll('.second-hand');
const minsHand = document.querySelectorAll('.min-hand');
const hourHand = document.querySelectorAll('.hour-hand');
function setDate() {
const now = new Date();
const seconds = now.getSeconds();
const secondsDegrees = ((seconds / 60) * 360) + 90;
secondHand.forEach(sec => sec.style.transform = `rotate(${secondsDegrees}deg)`);
const mins = now.getMinutes();
const minsDegrees = ((mins / 60) * 360) + ((seconds / 60) * 6) + 90;
minsHand.forEach(min => min.style.transform = `rotate(${minsDegrees}deg)`);
const hour = now.getHours();
const hourDegrees = ((hour / 12) * 360) + ((mins / 60) * 30) + 90;
hourHand.forEach(hour => hour.style.transform = `rotate(${hourDegrees}deg)`);
}
setInterval(setDate, 1000);
setDate();
html {
background: #018DED url(https://unsplash.it/1500/1000?image=881&blur=5);
background-size: cover;
font-family: 'helvetica neue';
text-align: center;
font-size: 10px;
}
body {
margin: 0;
font-size: 2rem;
display: flex;
flex: 1;
min-height: 100vh;
align-items: center;
}
.clock,
.clocktwo {
width: 30rem;
height: 30rem;
border: 20px solid white;
border-radius: 50%;
margin: 50px auto;
position: relative;
padding: 2rem;
box-shadow: 0 0 0 4px rgba(0, 0, 0, 0.1), inset 0 0 0 3px #EFEFEF, inset 0 0 10px black, 0 0 10px rgba(0, 0, 0, 0.2);
}
.clock-face,
.clock-facetwo {
position: relative;
width: 100%;
height: 100%;
transform: translateY(-3px);
/* account for the height of the clock hands */
}
.hand,
.handtwo {
width: 50%;
height: 6px;
background: black;
position: absolute;
top: 50%;
/* transform-origin will allow us to rotate the clock hands along the x axis, so it */
transform-origin: 100%;
transform: rotate(90deg);
transition: all 0.5s;
transition-timing-function: cubic-bezier(0.1, 2.7, 0.58, 1);
}
<div class="clock">
<div class="clock-face">
<div class="hand hour-hand"></div>
<div class="hand min-hand"></div>
<div class="hand second-hand"></div>
</div>
</div>
<div class="clocktwo">
<div class="clock-facetwo">
<div class="handtwo hour-hand"></div>
<div class="handtwo min-hand"></div>
<div class="handtwo second-hand"></div>
</div>
</div>
You need to use querySelectorAll to get reference to all elements.
Then you can set the transform values for each element like this:
const bothSecondHands = document.querySelectorAll('.second-hand');
bothSecondHands.forEach(secondHand => secondHand.style.transform = `rotate(${secondsDegrees}deg)`);

The new quote function in my script.js file does not make the author name appear

Every time I click the new code button the author's name is 'Unknown' And note the one provided by the API provided data.
The code is in this Codepen:
https://codepen.io/osvaldogrc/pen/poPLyzW
const quoteContainer = document.getElementById('quote-container');
const quoteText = document.getElementById('quote');
const authorText = document.getElementById('author');
const twitterBtn= document.getElementById('twitter');
const newQuoteBtn = document.getElementById('new-quote');
const loader = document.getElementById('loader');
let apiQuotes = [];
//New Quote
function newQuote(){
complete();
//Random quote
const quote = apiQuotes[Math.floor(Math.random() * apiQuotes.length)];
quoteText.textContent = quote.text;
}
newQuote only set `quoteText.textContent
try adding authorText.textContent = quote.author ? quote.author : "Unknown"; in the function
You need to assign the author property of the response object to the textContent of the corresponding span:
const quoteContainer = document.getElementById('quote-container');
const quoteText = document.getElementById('quote');
const authorText = document.getElementById('author');
const twitterBtn= document.getElementById('twitter');
const newQuoteBtn = document.getElementById('new-quote');
const loader = document.getElementById('loader');
let apiQuotes = [];
// Show loading
function loading() {
loader.hidden = false;
quoteContainer.hidden = true;
}
// Hide loading
function complete() {
quoteContainer.hidden = false;
loader.hidden =true;
}
//New Quote
function newQuote(){
complete();
//Random quote
const quote = apiQuotes[Math.floor(Math.random() * apiQuotes.length)];
quoteText.textContent = quote.text;
author.textContent = quote.author;
}
// Check quote length
if(quoteText.length > 50) {
quoteText.classList.add('long-quote');
} else {
quoteText.classList.remove('long-quote');
}
// Set quote
quoteText.textContent = quoteText;
complete();
//Author field
authorText.textContent = quote.author ? quote.author : "Unknown";
//Get Quotes fom API
async function getQuotes(){
loading();
const apiUrl = `https://type.fit/api/quotes`;
try {
const response = await fetch(apiUrl);
apiQuotes = await response.json();
newQuote();
} catch (error){
//Error here
}
}
//Twee
function tweetQuote() {
const twitterUrl =`https://twitter.com/intent/tweet?text=${quoteText.textContent} - ${authorText.textContent}`;
window.open(twitterUrl, '_blank');
}
//Event Listener
newQuoteBtn.addEventListener('click', newQuote);
twitterBtn.addEventListener('click', tweetQuote)
//On load
getQuotes();
#import url('https://fonts.googleapis.com/css2?family=Montserrat&display=swap');
html {
box-sizing: border-box;
}
body{
margin: 0;
min-height: 100vh;
background-color: #DFDBE5;
background-image: url("data:image/svg+xml,%3Csvg width='48' height='32' viewBox='0 0 48 32' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%239C92AC' fill-opacity='0.4'%3E%3Cpath d='M27 32c0-3.314 2.686-6 6-6 5.523 0 10-4.477 10-10S38.523 6 33 6c-3.314 0-6-2.686-6-6h2c0 2.21 1.79 4 4 4 6.627 0 12 5.373 12 12s-5.373 12-12 12c-2.21 0-4 1.79-4 4h-2zm-6 0c0-3.314-2.686-6-6-6-5.523 0-10-4.477-10-10S9.477 6 15 6c3.314 0 6-2.686 6-6h-2c0 2.21-1.79 4-4 4C8.373 4 3 9.373 3 16s5.373 12 12 12c2.21 0 4 1.79 4 4h2z' /%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
color: black;
font-family: Montserrar, sans-serif;
font-weight: 600;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
}
.quote-container{
width: auto;
max-width: 900px;
padding: 20px 30px;
border-radius: 15px;
background-color: rgba(255, 255, 255, 0.4);
box-shadow: 0 10px 10px 10px rgba(0, 0, 0, 0.2);
}
.quote-text {
font-size: 2.75rem;
}
#long-quote{
font-size: 2rem;
}
.fa-quote-left{
font-size: 4rem;
}
.quote-author{
margin-top: 15px;
font-size: 2rem;
font-weight: 400;
font-style: italic;
}
.button-container {
margin-top: 15px;
display: flex;
justify-content: space-between;
}
button{
cursor: pointer;
font-size: 1.2rem;
height: 2.5rem;
border: none;
border-radius: 10px;
color: #fff;
background-color: #333;
outline: none;
padding: 0.5rem 1.8rem;
box-shadow: 0 0.3rem rgba(121, 121, 121, 0.65);
}
button:hover{
filter: brightness(110%);
}
button:active{
transform: translate(0, 0.3rem);
box-shadow: 0 0.1rem rgba(255, 255, 255, 0.65);
}
.twitter-button:hover{
color: #38a1f3;
}
.fa-twitter{
font-size: 1.5rem;
}
/* Media query*/
#media screen and (max-width: 1000px) {
.quote-container{
margin: auto 10px;
}
.quote-text{
font-size: 2.5rem;
}
}
/*Loader*/
.loader {
border: 16px solid #f3f3f3; /* Light grey */
border-top: 16px solid#333; /* Blue */
border-radius: 50%;
width: 120px;
height: 120px;
animation: spin 2s linear infinite;
}
#keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Quote Generator</title>
<link rel="icon" type="image/png" href="https://www.google.com/s2/u/0/favicons?domain=css-tricks.com">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<div class="quote-container" id="quote-container">
<div class="quote-text">
<!--Quote-->
<i class="fas fa-quote-left"></i>
<span id="quote"></span>
</div>
<!-- Author-->
<div class="quote-author">
<span id="author"></span>
</div>
<!--Buttons-->
<div class="button-container">
<button class="twitter-button" id="twitter" title="Tweet This!">
<i class="fab fa-twitter"></i>
</button>
<button id="new-quote">New Quote</button>
</div>
</div>
<!--Loader-->
<div class="loader" id="loader"></div>
<script src="script.js"></script>
<script src="quotes.js"></script>
</body>
</html>
Nowhere in the newQuote function are you setting a value to the "author text". If you want to set a value to authorText, set a value to authorText:
authorText.textContent = quote.author;
Adding authorText.textContent in line 30 of the code resolved the issue.
Thanks to everyone.
//New Quote
function newQuote(){
complete();
//Random quote
const quote = apiQuotes[Math.floor(Math.random() * apiQuotes.length)];
quoteText.textContent = quote.text;
authorText.textContent = quote.author;
}

Audio is not playing when I am trying to call it by function

//Audio
var myAudio = document.getElementById('listening_audio');
var audioProgressSize = 100;
var bar = document.getElementById('listening_progress_bar');
//Audio
playAudio(); // When i am calling this function, i keep having an error.
function playAudio(){
myAudio.play();
}
//Audio functions
$('#play_listening_btn').on('click', function(e) {
e.preventDefault();
myAudio.play();
setInterval(updateAudioProgress, 500);
});
$("#listening_audio").on("ended", function() {
$(".audio_progress_bar").css('--value',"0%");
$('.question_wrapper .listening_assessment_choices input[type="radio"]').css('transform','scale(1.5)');
$('.btn_submit').show();
startCountdown();
});
function updateAudioProgress(){
if (!myAudio.ended) {
var playedMinutes = parseInt(myAudio.currentTime/60);
var playedSeconds = parseInt(myAudio.currentTime%60);
var size = parseInt(myAudio.currentTime * audioProgressSize/myAudio.duration);
$(".audio_progress_bar").css('--value',size +"%");
}
}
//Done Audio functions
.listening_assessment_circle {
border-radius: 50%;
width: 80px;
height: 80px;
-webkit-box-shadow: 0px 5px 5px 0px rgba(60, 60, 60, 0.6);
-moz-box-shadow: 0px 5px 5px 0px rgba(60, 60, 60, 0.6);
box-shadow: 0px 5px 5px 0px rgba(60, 60, 60, 0.6);
margin:auto;
}
.listening_assessment_circle {
width: 80px;
height: 80px;
margin: 1em auto;
border-radius: 50%;
background-image: conic-gradient(rgb(237,28,36) var(--value), lightgrey var(--value));
position: relative;
}
.listening_assessment_circle::after {
content: "";
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: calc(100% - var(--bord));
height: calc(100% - var(--bord));
background: rgba(64,64,64);
border-radius: inherit;
}
.listening_assessment_circle:hover {
background: rgb(237,28,36);
-webkit-box-shadow: 0px 5px 20px 10px rgba(60, 60, 60, 0.6);
-moz-box-shadow: 0px 5px 20px 10px rgba(60, 60, 60, 0.6);
box-shadow: 0px 5px 20px 10px rgba(60, 60, 60, 0.6);
}
.audio_progress_bar{
--value: 0%;
}
.listening_assessment_arrow_right{
width: 0px;
position: absolute;
height: 0px;
border-top: 20px solid transparent;
border-bottom: 20px solid transparent;
border-left: 35px solid #FAFAFA;
margin-left: 28px;
margin-top: 20px;
cursor: pointer;
z-index: 1;
}
#listening_audio{
display: none;
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Bootstrap Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<audio id="listening_audio" controls>
<source src="https://ia800905.us.archive.org/19/items/FREE_background_music_dhalius/backsound.mp3" type="audio/mpeg">
</audio>
<div id="listening_progress_bar" class="audio_progress_bar listening_assessment_circle">
<div id="play_listening_btn" class="listening_assessment_arrow_right">
</div>
</div>
</body>
</html>
I am having a problem regarding with the use of Audio play in HTML.
I already read their new rules, and I already followed their guidelines.
Link Here for their new guidelines in html audio.
I already tried to mute it and just unmute it on my Javascript but it is still not working. Here is the code that I currently have.
HTML
<audio id="listening_audio" controls=muted>
<source src="" type="audio/mpeg">
</audio>
My javascript
function tickAudio() {
var timeDisplay = document.getElementById('question_timer');
var min = Math.floor(secondsRemaining / 60);
var sec = secondsRemaining - (min * 60);
if (sec < 10) {
sec = '0' + sec;
}
var message = min.toString() + ':' + sec;
timeDisplay.innerHTML = message;
//stop if down to zero
if (secondsRemaining === 0) {
clearInterval(intervalHandle);
document.getElementById("play_listening_btn").click();
}
secondsRemaining--;
}
$('#play_listening_btn').on('click', function(e) {
e.preventDefault();
myAudio.play();
setInterval(updateAudioProgress, 500);
});
function updateAudioProgress(){
if (!myAudio.ended) {
var playedMinutes = parseInt(myAudio.currentTime/60);
var playedSeconds = parseInt(myAudio.currentTime%60);
var size = parseInt(myAudio.currentTime * audioProgressSize/myAudio.duration);
$(".audio_progress_bar").css('--value',size +"%");
}
}
So basically what I want is, when the timer is already at 0 seconds, it will play the audio. But when I do that, I keep having an error of
Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first.
Can anyone please help me.

How to change the background image of an element randomly?

I have recently created a program which creates new element when someone clicks it. The new element which is created has some specific CSS styling. Now i want it's background to randomly change when the user clicks on button. Like the first time when someone clicks the background is red another time its green and so on like this.. My code is -
function a1click(){
var body = document.querySelector('body');
var bubbles = document.createElement("span");
var size = Math.random() * 100;
bubbles.style.width = 10 + size+'px';
bubbles.style.height = 10 + size+'px';
body.appendChild(bubbles);
setTimeout(function(){
bubbles.remove();
},1000)
}
*{
margin: 0;
padding: 0;
}
body{
background: rgb(73, 156, 145);
}
#a1{
position: relative;
top: 350px;
left: 100px;
width: 30px;
height: 150px;
border: 2px solid #fff;
background: rgb(0, 0, 0);
float: left;
cursor: pointer;
perspective: 600;
}
span{
position: absolute;
top: 120px;
left: 60%;
width: 50px;
height: 50px;
background: #000;
animation: tweek 1s linear infinite;
transform-origin: top;
background-size: cover;
pointer-events: none;
}
#keyframes tweek {
0% {
transform: rotate(90deg) translate(300px);
}
100% {
transform: rotate(0deg) translate(250px);
opacity: 0;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Document</title>
</head>
<body onkeydown="keypress(event)">
<div id="a1" onclick="a1click()"></div>
<script src="script.js"></script>
</body>
</html>
I want the background color of this box to change randomly..Please help, any help is appreciated..
as you can see from the code, I created a function that randomizes the numbers and puts them in the rgb.
function random_bg_color() {
var x = Math.floor(Math.random() * 256);
var y = Math.floor(Math.random() * 256);
var z = Math.floor(Math.random() * 256);
var bgColor = "rgb(" + x + "," + y + "," + z + ")";
return bgColor;
}
function a1click(){
var body = document.querySelector('body');
var bubbles = document.createElement("span");
var size = Math.random() * 100;
bubbles.style.width = 10 + size+'px';
bubbles.style.height = 10 + size+'px';
bubbles.style.backgroundColor = random_bg_color();
body.appendChild(bubbles);
setTimeout(function(){
bubbles.remove();
},1000)
}
*{
margin: 0;
padding: 0;
}
body{
background: rgb(73, 156, 145);
}
#a1{
position: relative;
top: 350px;
left: 100px;
width: 30px;
height: 150px;
border: 2px solid #fff;
background: rgb(0, 0, 0);
float: left;
cursor: pointer;
perspective: 600;
}
span{
position: absolute;
top: 120px;
left: 60%;
width: 50px;
height: 50px;
background: #000;
animation: tweek 1s linear infinite;
transform-origin: top;
background-size: cover;
pointer-events: none;
}
#keyframes tweek {
0% {
transform: rotate(90deg) translate(300px);
}
100% {
transform: rotate(0deg) translate(250px);
opacity: 0;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Document</title>
</head>
<body onkeydown="keypress(event)">
<div id="a1" onclick="a1click()"></div>
<script src="script.js"></script>
</body>
</html>
For answer your comment :
Generate random image:
var Images = new Array("https://via.placeholder.com/150/0000FF/808080","https://via.placeholder.com/150/FF0000/FFFFFF",
"https://via.placeholder.com/150/FFFF00/000000");
function randompic() {
var randomNum = Math.floor(Math.random() * Images.length);
return Images[randomNum];
}
function a1click(){
var body = document.querySelector('body');
var bubbles = document.createElement("span");
var size = Math.random() * 100;
bubbles.style.width = 10 + size+'px';
bubbles.style.height = 10 + size+'px';
bubbles.style.backgroundImage = "url('"+randompic()+"')";
body.appendChild(bubbles);
setTimeout(function(){
bubbles.remove();
},1000)
}
*{
margin: 0;
padding: 0;
}
body{
background: rgb(73, 156, 145);
}
#a1{
position: relative;
top: 350px;
left: 100px;
width: 30px;
height: 150px;
border: 2px solid #fff;
background: rgb(0, 0, 0);
float: left;
cursor: pointer;
perspective: 600;
}
span{
position: absolute;
top: 120px;
left: 60%;
width: 50px;
height: 50px;
background: #000;
animation: tweek 1s linear infinite;
transform-origin: top;
background-size: cover;
pointer-events: none;
}
#keyframes tweek {
0% {
transform: rotate(90deg) translate(300px);
}
100% {
transform: rotate(0deg) translate(250px);
opacity: 0;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Document</title>
</head>
<body onkeydown="keypress(event)">
<div id="a1" onclick="a1click()"></div>
<script src="script.js"></script>
</body>
</html>
This seems to work:
http://jsfiddle.net/mcuzq9rb/
I included a random color generator and applied it to the style of the floating squares.
Let me know if it's what you wanted.
I would style the box with an rga-value, similar to how you randomly set the size of the bubble:
var r = Math.floor(Math.random() * 256);
var g = Math.floor(Math.random() * 256);
var b = Math.floor(Math.random() * 256);
bubbles.style.backgroundColor = "rgb("+r+", "+g+", "+b+")";
Here's a little function that uses rando.js to set an element's background color to a random hex string.
function setRandomBackgroundColor(element) {
var hexString = "#";
for (var i = 0; i < 3; i++) {
var hex = rando(255).toString(16);
hexString += hex.length == 1 ? "0" + hex : hex;
}
element.style.backgroundColor = hexString;
}
<script src="https://randojs.com/1.0.0.js"></script>
<button onclick="setRandomBackgroundColor(document.body);">Set random background color</button>

How do I increment a number using 0:00:00 format?

I am trying to create a time tracker in the following format; 0:00:00. The first zero represents the hour, then minutes, then seconds. Currently, I have a working function that increments the number every second. I know there is a proper way to do this with getDate() and then modifying the hours, minutes and seconds using getHours(), getMinutes() and so on. I just can't seem to get it all to work together. I've attached a working jsFiddle to show how far I've gotten.
The goal is to have it look something like ... 0:00:59 then turn into 0:01:00 and so on. Thank you.
Full example # http://jsfiddle.net/London804/628xz9x7/2/
$('#submit').click(function(){
var start = setInterval(updateDisplay, 1000), // every millisecond call updateDisplay
timer = $('#timer'),
value = parseInt($(timer).find('.value').text(), 10);
function updateDisplay(){
value++;
$(timer).find('.value').text(value);
if (value >= 60) {
$('#sec').replaceWith("min");
}
if (value >= 3600) {
$('#sec').replaceWith("hrs");
}
if (value >= 86400) {
value = 0;
console.log('stop and take a break, you have been working over 24hrs!');
}
}
$('#stop').click(function(){
clearInterval(start);
});
$('#reset').click(function(){
clearInterval(start);
value = parseInt($(timer).find('.value').text('0'));
});
});
Here is a solution that doesn't involve all the slicing and dicing of html elements. I'm using Date objects to track elapsed time in milliseconds and updating the display by extracting a substring of a standard format string provided by the Date object.
The end result will be more accurate as you are not relying on the timer to tick off seconds but are using an actual elapsed time between calls.
You still have to mess with the final output formatting but the Date object has nice functions that allow you to pull all the components you many need in terms our hours, minutes, seconds etc...
var starting_ms ;
var elapsed ;
var $timer = $('#timer .value');
var $hrs = $('#elapsedtime #hrs');
var $min = $('#elapsedtime #min');
var $sec = $('#elapsedtime #sec');
var start;
function updateDisplay() {
elapsed.setTime(Date.now() - starting_ms);
$timer.text(elapsed.toUTCString().substr(20, 5));
$hrs.text(elapsed.getUTCHours() );
$min.text(elapsed.getUTCMinutes() );
$sec.text(elapsed.getUTCSeconds() );
}
$('#submit').click(function() {
if( start )
clearInterval(start);
starting_ms = Date.now();
elapsed = new Date(0);
start = setInterval(updateDisplay, 1000); // every millisecond call updateDisplay
});
$('#stop').click(function() {
clearInterval(start);
});
$('#reset').click(function() {
clearInterval(start);
starting_ms = Date.now();
updateDisplay();
});
* {
-webkit-tap-highlight-color: transparent
}
body {
-webkit-touch-callout: none;
-webkit-text-size-adjust: none;
-webkit-user-select: none;
background-color: #E4E4E4;
background-image: linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
background-image: -webkit-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
background-image: -ms-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #A7A7A7), color-stop(0.51, #E4E4E4));
background-attachment: fixed;
font-family: 'HelveticaNeue-Light', 'HelveticaNeue', Helvetica, Arial, sans-serif;
font-size: 12px;
height: 100%;
margin: 0px;
padding: 0px;
text-transform: uppercase;
width: 100%
}
.app {
background: transparent url(../../img/logo.png) no-repeat center top;
position: absolute;
left: 50%;
top: 50%;
height: 50px;
width: 225px;
text-align: center;
padding: 180px 0px 0px 0px;
margin: -115px 0px 0px -112px
}
.app #login {
margin-top: 20px;
position: relative;
font-size: 18px;
text-transform: uppercase
}
.app #login:active {
color: #cbcbcb
}
#welcome {
width: 90%;
margin: 20px auto
}
#media screen and (min-aspect-ratio: 1 / 1) and (min-width: 400px) {
.app {
background-position: left center;
padding: 75px 0px 75px 170px;
margin: -90px 0px 0px -198px
}
}
h1 {
font-size: 24px;
font-weight: normal;
margin: 0px;
overflow: visible;
padding: 0px;
text-align: center
}
.event {
border-radius: 4px;
-webkit-border-radius: 4px;
color: #FFFFFF;
font-size: 12px;
margin: 0px 30px;
padding: 2px 0px
}
.event.listening {
background-color: #333333;
display: block
}
.event.received {
background-color: #4B946A;
display: none
}
#keyframes fade {
from {
opacity: 1.0
}
50% {
opacity: 0.4
}
to {
opacity: 1.0
}
}
#-webkit-keyframes fade {
from {
opacity: 1.0
}
50% {
opacity: 0.4
}
to {
opacity: 1.0
}
}
.blink {
animation: fade 3000ms infinite;
-webkit-animation: fade 3000ms infinite
}
#timer-container {
min-width: 300px;
max-width: 50%;
margin: 0 auto
}
#timer-container #timer {
text-align: center;
font-size: 20px;
color: #4887da;
font-weight: bold
}
#timer-container label {
display: block
}
#timer-container label input {
width: 98%
}
#timer-container #button-container {
text-align: center
}
#timer-container #button-container button {
-webkit-box-shadow: 0px 1px 5px 3px #9c899c;
-moz-box-shadow: 0px 1px 5px 3px #9c899c;
box-shadow: 0px 1px 5px 3px #9c899c;
width: 35%;
margin: 10px auto;
position: relative
}
#timer-container #button-container button:nth-child(2) {
width: 20%
}
/*# sourceMappingURL=styles.css.map */
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="welcome">
<h2>Welcome please log in</h2>
<p>Stuff ...</p>
</div>
<div>
<fieldset id="timer-container">
<div id="timer"><span class="value">0:00</span> <span id="sec">sec</span>
</div>
<div id="button-container">
<button id="submit" type="submit">Start</button>
<button id='reset' type="reset">Reset</button>
<button id="stop" type="stop">Stop</button>
</div>
</fieldset>
<table id="elapsedtime">
<caption>Just for fun</caption>
<tr>
<td>Hrs</td><td>Min</td><td>Sec</td>
</tr>
<tr>
<td><span id="hrs"></span></td><td><span id="min"></td><td><span id="sec"></td>
</tr>
</table>
</div>
When you start the timer, save the current date-time.
var start_dt = Date.now();
When you want to update the display, start by using the following:
var current_dt = Date.now();
var elapsed_ms = current_dt - start_dt;
That gives an accurate count of the elapsed time. Repeatedly incrementing a variable as you are doing will drift.
Now, it's time to format as H:MM:SS
function format_timer(ms) {
var s = ("0" + Math.floor((ms / ( 1000)) % 60)).substr(-2);
var m = ("0" + Math.floor((ms / ( 60*1000)) % 60)).substr(-2);
var h = Math.floor((ms / (60*60*1000)) );
return h + ":" + m + ":" + s;
}
You can accomplish it with converting your seconds to dateTime format and then with simple regex:
var myDate = new Date(null, null, null, null, null, value).toTimeString().replace(/.*(\d{2}:\d{2}:\d{2}).*/, "$1");
Here is working fiddle: http://jsfiddle.net/628xz9x7/6/
if you are certain on implementing this logic by yourself, you can make some use of some basic mathematics.
function updateDisplay(){
value++;
// Example for minutes
if (value >= 60) {
secs = value % 60;
mins = (value - secs) / 60;
$(timer).find('.value').text("00:"+min+":"+secs);
//$('#sec').replaceWith("hrs");
}
}
You can add the implementation for the other fields, but what we simply do here is find how many seconds are over the minute, by using modulus and then subtract the seconds from the minutes and divide by 60 to get the amount of minutes elapsed, we can then set the labels with these new values.
One thing you may want to do is provide a formatNumber method:
function formatNumber(number) {
if (number < 10) {
return "0" + number;
}
return number;
}
What this will do is provide the formatted string for the number to update label for values under 10, a test fiddle is here, I have not implemented all functionality but its a start for you : https://jsfiddle.net/628xz9x7/14/
JS Fiddle Demo
Note that I do an iteration every millisecond instead of a second, for faster testing.
var start, value, timer = $('#timer');
$('#submit').click(function(){
value = readTime(timer.text());
start = setInterval(updateDisplay, 1); // replace 1 with 1000
});
$('#stop').click(function(){ clearInterval(start); });
$('#reset').click(function(){
clearInterval(start);
value = parseInt(timer.text(formatTime(0)));
});
function updateDisplay(){
value++;
timer.text(formatTime(value));
if (value >= 86400) {
value = 0;
console.log('stop and take a break, you have been working over 24hrs!');
}
}
function formatTime(t){
var h = ('0' + parseInt( t / 3600 ) % 24).slice(-2),
m = ('0' + parseInt( t / 60 ) % 60).slice(-2),
s = ('0' + t % 60).slice(-2);
return h+':'+m+':'+s;
}
function readTime(s){
var r = s.split(':');
return parseInt(r[0])*3600 + parseInt(r[1])*60 + parseInt(r[2]);
}

Categories