I'm fairly new to coding and trying to recreate a simple animated JavaScript clock (from Javascript30 course) in a Rails app using Stimulus (as these are what I'm most familiar with).
I want to change the transform property of the .hand class at regular intervals to replicate a ticking clock in Stimulus where you'd use .style.transform in JavaScript. I can't understand how to change a property regularly using .classList
This is the working code:
<body>
<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>
<style>
.clock {
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 {
position: relative;
width: 100%;
height: 100%;
transform: translateY(-3px); /* account for the height of the clock hands */
}
.hand {
width: 50%;
height: 6px;
background: black;
position: absolute;
top: 50%;
transform-origin: 100%;
**transform: rotate(90deg);**
transition: all 0.05s;
transition-timing-function: cubic-bezier(0.1, 2.7, 0.58, 1);
}
</style>
<script>
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();
</script>
What I cannot figure out is how to recreate
minsHand.style.transform = `rotate(${minsDegrees}deg)`;
With the same CSS as above, this HTML with data controllers, targets and actions:
And this Stimulus controller:
import { Controller } from "stimulus"
export default class extends Controller {
// static targets = [ "output" ]
static values = { refreshInterval: Number }
static targets = [ "hour", "min", "sec" ]
connect() {
this.setDate();
if (this.hasRefreshIntervalValue) {
this.startRefreshing()
}
}
setSeconds(){
const now = new Date();
const seconds = now.getSeconds();
const secondsDegrees = ((seconds / 60) * 360 )+ 90;
**console.dir(this.secTarget)**
}
setDate() {
this.setSeconds();
}
startRefreshing() {
setInterval(() => {
this.setDate()
}, this.refreshIntervalValue)
}
}