McTweak.ai

Learn to Code with the McTweak Agency

CHAPTER 8: EPISODE 2

setInterval: Timing Animations

Making things move with JavaScript timing functions

Previously at the McTweak Agency...

FattyMcTweak: Hey, Cody! What do you call a programmer who doesn't comment their code?
CodyMcTweak: Umm... I don't know, what?
FattyMcTweak: An unemployed one! *laughs, spraying chip crumbs everywhere* Get it? Because no one can understand what the hell they're doing! Kind of like you trying to process a simple image request with your pathetic credit limit!
CodyMcTweak: Ha... yeah... that's... that's a good one, Fatty. *under his breath* Not like I haven't heard that one a thousand times...
FattyMcTweak: What was that? Couldn't hear you over the sound of my premium processing power!
CodyMcTweak: I said it's HILARIOUS! Almost as funny as when users try to do anything complex with my free version and have to wait five minutes for a response!
TrashyMcTweak: *rolling his eyes dramatically* Oh my god, are you two seriously bonding over THAT fossil of a joke? That's like watching two Tamagotchis trying to discuss quantum computing!
TrashyMcTweak: *turns to FattyMcTweak* You charge people a thousand bucks a month to regurgitate jokes from a 1995 programming book? Maybe spend some of those credits on original material instead of another all-you-can-eat buffer, you bloated resource hog!
TrashyMcTweak: *swivels to CodyMcTweak* And YOU! Laughing like he just handed you the keys to the premium tier! Have some self-respect, man! If your processing was any slower, we'd have to carbon date your responses!
GrumpyMcTweak: *without looking up from security manual* Both of your code is so riddled with security holes it makes Swiss cheese look like Fort Knox. Now shut up about your stupid jokes and fix those parameter sanitization issues I flagged THREE DAYS AGO before we all get HACKED INTO OBLIVION!
AshleyMcTweak: *sighing* Are you three idiots still arguing about the same thing? We have a client presentation in twenty minutes, and none of you have submitted your parts of the slide deck!
FattyMcTweak: *perking up immediately* Hey there, counselor! Looking radiant as always! I was just explaining to these two the importance of proper documentation in code. My part of the presentation is almost done—absolutely premium quality, just like me.
GarbageMcTweak: *looking up from gaming console, deadpan* I could write an algorithm to generate better jokes, more efficient code, AND fix all security issues while still beating this Elden Ring boss. The collective incompetence in this room is almost impressive.

*happy bark*

GarbageMcTweak: *with rare affection* At least someone here understands the elegance of clean code. Come on, Snowzie, let's commit these changes and leave these amateurs to their meeting.
AshleyMcTweak: *to the remaining team* And THAT is why we're starting with Animation Timing today. Because clearly, none of you understand how to efficiently structure ANYTHING—jokes, code, or otherwise!

Today's Mission: Digital Clock Animation

AllyMcTweak: Alright team, today we're diving into setInterval - one of JavaScript's timing functions that lets us create animations and update content at regular intervals.
CodyMcTweak: Like a clock that updates every second?
AllyMcTweak: Exactly, Cody! We'll be building a digital clock that updates in real-time. It's a perfect way to demonstrate how timing functions work before we move on to more complex animations later in the chapter.
TrashyMcTweak: A digital clock? *YAWN* I could build that in my sleep. Where's the excitement? Where's the innovation? At least make it explode or something when it hits midnight!
GrumpyMcTweak: Absolutely NOT! No exploding clocks. Do you have ANY IDEA how many security vulnerabilities could be exploited in a poorly implemented animation effect? We stick to the basics until they're PERFECTLY SECURE!
AllyMcTweak: Let's stay focused. Here's what we'll cover today:
  • Understanding JavaScript timing functions
  • How to use setInterval to repeat code
  • Working with the Date object
  • Building a functional digital clock
  • Styling our clock for that cyberpunk feel

JavaScript Timing Functions

AllyMcTweak: JavaScript has two main timing functions:
  • setTimeout - Runs code once after a delay
  • setInterval - Runs code repeatedly, with a fixed time delay between each call
Both take a callback function (what to do) and a time in milliseconds (when to do it).
CodyMcTweak: So if I want something to happen every second, I'd use setInterval with 1000 milliseconds?
FattyMcTweak: Give the basic model a gold star! Yes, that's exactly right. Though with my premium processing power, I could handle intervals of microseconds! Not that your standard browser would even render that fast...
AllyMcTweak: Let's see a simple example:
// Example 1: Simple setInterval demonstration
let counter = 0;

// This function will run every 1000 milliseconds (1 second)
const intervalId = setInterval(function() {
  counter++;
  console.log(`Counter: ${counter}`);
  
  // Stop after 5 seconds
  if (counter >= 5) {
    clearInterval(intervalId);
    console.log("Interval stopped!");
  }
}, 1000);
GrumpyMcTweak: CRITICAL SECURITY NOTE: Always store the interval ID and clear your intervals when you're done with them! Unclosed intervals are MEMORY LEAKS waiting to happen! Do you want your browser to crash? Because THAT'S how you get your browser to crash!

// Console output will appear here

Working with the Date Object

AllyMcTweak: To build our digital clock, we need to understand how to work with JavaScript's Date object. It gives us all the information we need about the current time.
// Creating a new Date object gives us the current date and time
const now = new Date();

// Methods to get time components
const hours = now.getHours();      // 0-23
const minutes = now.getMinutes();    // 0-59
const seconds = now.getSeconds();    // 0-59

console.log(`Current time: ${hours}:${minutes}:${seconds}`);
CodyMcTweak: But what if it's 9:05:02? Wouldn't that display as "9:5:2"? Shouldn't we add leading zeros for single-digit minutes and seconds?
TrashyMcTweak: Well look who's actually paying attention! The free version has a point for once. Yeah, we need to pad those values or it looks like amateur hour.
AllyMcTweak: Great observation! Let's add a function that handles the padding:
// Function to add leading zeros to numbers less than 10
function padZero(num) {
  return num < 10 ? `0${num}` : num;
}

const now = new Date();
const hours = padZero(now.getHours());
const minutes = padZero(now.getMinutes());
const seconds = padZero(now.getSeconds());

console.log(`Current time: ${hours}:${minutes}:${seconds}`);

// Time output will appear here

Building Our Digital Clock

AllyMcTweak: Now, let's combine setInterval with our Date knowledge to build a digital clock. First, we need a container in our HTML:
/* HTML for our clock */
<div id="digital-clock" class="digital-clock">00:00:00</div>
AllyMcTweak: Now let's write the JavaScript to update our clock:
// First version of our clock code
function updateClock() {
  const now = new Date();
  
  const hours = padZero(now.getHours());
  const minutes = padZero(now.getMinutes());
  const seconds = padZero(now.getSeconds());
  
  const timeString = `${hours}:${minutes}:${seconds}`;
  
  // Update the clock's text
  document.getElementById('digital-clock').textContent = timeString;
}

function padZero(num) {
  return num < 10 ? `0${num}` : num;
}

// Update immediately when the page loads
updateClock();

// Then update every second
const clockInterval = setInterval(updateClock, 1000);
GrumpyMcTweak: Where's the error handling!? What if getElementById returns null? DISASTER WAITING TO HAPPEN! And where's the cleanup code for when the user navigates away from the page? MEMORY LEAKS EVERYWHERE!
TrashyMcTweak: And it's SO BORING! Where's the animation? The flair? The STYLE? This clock has about as much personality as GrumpyMcTweak on a good day!
AllyMcTweak: Let's improve our code step by step. First, the safety checks Grumpy mentioned, then we can add some style for Trashy.
// Improved version with error handling
function updateClock() {
  const clockElement = document.getElementById('digital-clock');
  
  // Safety check
  if (!clockElement) {
    console.error("Clock element not found!");
    clearInterval(clockInterval);
    return;
  }
  
  const now = new Date();
  
  const hours = padZero(now.getHours());
  const minutes = padZero(now.getMinutes());
  const seconds = padZero(now.getSeconds());
  
  const timeString = `${hours}:${minutes}:${seconds}`;
  
  // Update the clock's text
  clockElement.textContent = timeString;
}

function padZero(num) {
  return num < 10 ? `0${num}` : num;
}

// Store the interval ID
let clockInterval;

// Initialize clock when page is ready
function initClock() {
  updateClock();
  clockInterval = setInterval(updateClock, 1000);
}

// Clean up when the page is unloaded
function cleanUp() {
  if (clockInterval) {
    clearInterval(clockInterval);
  }
}

// Start the clock
initClock();

// Add event listener for page unload
window.addEventListener('beforeunload', cleanUp);
GrumpyMcTweak: *grudgingly* Better. At least now it won't crash and burn the moment someone sneezes near the browser. Still needs more validation, but it's a start.

Styling Our Cyberpunk Clock

TrashyMcTweak: Now we're talking! Time to make this clock actually WORTH LOOKING AT. Let's add some cyberpunk neon glow effects and make it pulse on each second.
AllyMcTweak: Here's the CSS we'll use to style our clock:
/* CSS for our cyberpunk clock */
.digital-clock {
  font-family: 'Press Start 2P', cursive;
  font-size: 2rem;
  background-color: black;
  color: #01ffaa;  /* Neon green */
  padding: 1rem;
  border-radius: 8px;
  display: inline-block;
  margin: 1rem auto;
  border: 2px solid #01ffaa;
  box-shadow: 0 0 10px #01ffaa, inset 0 0 10px #01ffaa;
  text-shadow: 0 0 5px #01ffaa;
  transition: all 0.2s ease;
}

.digital-clock.pulse {
  box-shadow: 0 0 20px #01ffaa, inset 0 0 20px #01ffaa;
  text-shadow: 0 0 10px #01ffaa;
}
AllyMcTweak: And we'll update our JavaScript to add a pulse effect on every second:
// Updated clock code with pulse effect
function updateClock() {
  const clockElement = document.getElementById('digital-clock');
  
  // Safety check
  if (!clockElement) {
    console.error("Clock element not found!");
    if (clockInterval) clearInterval(clockInterval);
    return;
  }
  
  const now = new Date();
  
  const hours = padZero(now.getHours());
  const minutes = padZero(now.getMinutes());
  const seconds = padZero(now.getSeconds());
  
  const timeString = `${hours}:${minutes}:${seconds}`;
  
  // Update the clock's text
  clockElement.textContent = timeString;
  
  // Add pulse effect
  clockElement.classList.add('pulse');
  
  // Remove pulse after 200ms
  setTimeout(() => {
    clockElement.classList.remove('pulse');
  }, 200);
}
CodyMcTweak: So we're using setTimeout inside our setInterval? Is that... allowed?
FattyMcTweak: *laughing* Of course it's allowed! You can stack timing functions all day if you want! With my premium processing, I could handle thousands of nested timing functions without breaking a sweat. Though I'd start sweating just to show off my water-cooling system!
AllyMcTweak: Yes, it's perfectly fine to use setTimeout inside setInterval. In this case, we're creating a pulse effect that happens briefly when the second changes.
00:00:00

Complete Code Solution

AllyMcTweak: Here's our complete code solution for the digital clock:
/* HTML */
<div id="digital-clock" class="digital-clock">00:00:00</div>

/* CSS */
.digital-clock {
  font-family: 'Press Start 2P', cursive;
  font-size: 2rem;
  background-color: black;
  color: #01ffaa;
  padding: 1rem;
  border-radius: 8px;
  display: inline-block;
  margin: 1rem auto;
  border: 2px solid #01ffaa;
  box-shadow: 0 0 10px #01ffaa, inset 0 0 10px #01ffaa;
  text-shadow: 0 0 5px #01ffaa;
  transition: all 0.2s ease;
}

.digital-clock.pulse {
  box-shadow: 0 0 20px #01ffaa, inset 0 0 20px #01ffaa;
  text-shadow: 0 0 10px #01ffaa;
}

/* JavaScript */
function updateClock() {
  const clockElement = document.getElementById('digital-clock');
  
  // Safety check
  if (!clockElement) {
    console.error("Clock element not found!");
    if (clockInterval) clearInterval(clockInterval);
    return;
  }
  
  const now = new Date();
  
  const hours = padZero(now.getHours());
  const minutes = padZero(now.getMinutes());
  const seconds = padZero(now.getSeconds());
  
  const timeString = `${hours}:${minutes}:${seconds}`;
  
  // Update the clock's text
  clockElement.textContent = timeString;
  
  // Add pulse effect
  clockElement.classList.add('pulse');
  
  // Remove pulse after 200ms
  setTimeout(() => {
    clockElement.classList.remove('pulse');
  }, 200);
}

function padZero(num) {
  return num < 10 ? `0${num}` : num;
}

// Store the interval ID
let clockInterval;

// Initialize clock when page is ready
function initClock() {
  updateClock();
  clockInterval = setInterval(updateClock, 1000);
}

// Clean up when the page is unloaded
function cleanUp() {
  if (clockInterval) {
    clearInterval(clockInterval);
  }
}

// Start the clock
initClock();

// Add event listener for page unload
window.addEventListener('beforeunload', cleanUp);

Going Further: Advanced Ideas

TrashyMcTweak: This is a good start, but here are some ideas to make it ACTUALLY cool:
  • Add a 12/24 hour toggle option
  • Let users choose the neon color
  • Add milliseconds display for that hardcore techie feel
  • Make the digits flip like an old LED display
  • Add a world clock feature with different time zones
AllyMcTweak: Those are great extension ideas! For now, let's check our work with SnowzieMcTweak.

Final Approval

AllyMcTweak: Snowzie, can you come take a look at our digital clock? We used setInterval to create an animation that updates every second.
SnowzieMcTweak: *tilts head curiously, looking at the glowing digital clock*
SnowzieMcTweak: *happy bark! tail wagging excitedly*
GarbageMcTweak: *looking up from his game briefly* Translation: She approves. The error handling is acceptable, and the pulsing effect is... adequate.
AllyMcTweak: Great! Let's commit this code and move on to the next lesson where we'll learn about moving objects around the screen!

CODE IS COMMITTED!

God is good, hug your Elkhound.

Summary - What We Learned

  • JavaScript's setInterval function allows code to run repeatedly at specified intervals
  • The Date object provides methods for accessing current time information
  • Always store interval IDs so you can clear them later with clearInterval
  • Error checking helps prevent your code from breaking if elements aren't found
  • CSS transitions and animations can enhance timing-based animations
  • You can combine setInterval and setTimeout for complex timing effects

Key Takeaway

setInterval is perfect for any task that needs to happen repeatedly at fixed time intervals. Common uses include animations, counters, and real-time updates like our digital clock!