Austin's Live-Page Hacker

Learn to modify web pages live using Chrome DevTools

Based on the TechNoviceTools SW Disk Modification Demo

Start Hacking!

Introduction

What You'll Learn

This tutorial teaches you how to modify running web pages directly in your browser using the Developer Console. This powerful technique allows you to:

  • Inspect and modify JavaScript variables in real-time
  • Override functions to change behavior on the fly
  • Add animations using mathematical functions like Math.sin()
  • Debug and experiment with code without editing source files

Our Goal

We'll work with a simple disk animation (similar to the TechNoviceTools SW Disk Demo) and modify it to:

  1. Pulse in size using a sine wave function
  2. Cycle through colors using sine wave calculations

Opening Developer Tools

Step 1: Access the Developer Console

The browser's Developer Tools (DevTools) is your gateway to modifying web pages. Here's how to open it:

Right-Click Method

  1. Right-click anywhere on the page
  2. Select "Inspect" or "Inspect Element"
  3. Click the "Console" tab

Keyboard Shortcut

  • Windows/Linux: F12 or Ctrl+Shift+J
  • Mac: +Option+J

Menu Method

  1. Click the browser menu (⋮)
  2. Go to More Tools → Developer Tools
  3. Select Console tab

Try It Now!

After clicking, look for the message in your Console tab!

Step 2: Understanding the Console

The Console serves multiple purposes:

  • Execute JavaScript: Run any JS code directly
  • Access Page Variables: Read and modify global variables
  • Modify DOM: Change HTML elements on the fly
  • Override Functions: Replace existing functions with your own

The Demo Disk

Our Practice Canvas

Below is a simple disk animation created with p5.js (similar to the TechNoviceTools SW Disk). This disk has global variables that we'll modify through the console.

Current Values:

  • Disk Size: 100px
  • Disk Color: #ff6b6b
  • X Position: 200
  • Y Position: 200

The Source Code

Here's the JavaScript code powering the disk:

// Global variables - accessible from console!
let diskSize = 100;
let diskX = 200;
let diskY = 200;
let diskColor = '#ff6b6b';

function setup() {
    let canvas = createCanvas(400, 400);
    canvas.parent('disk-canvas');
}

function draw() {
    background(30, 30, 40);
    
    // Draw the disk
    fill(diskColor);
    noStroke();
    ellipse(diskX, diskY, diskSize, diskSize);
    
    // Draw center point
    fill(255);
    ellipse(diskX, diskY, 10, 10);
}

Key Insight

The variables diskSize, diskX, diskY, and diskColor are global, meaning we can access and modify them directly from the browser console!

Step 3: Basic Console Modifications

Let's start with simple modifications. Open your console and try these commands:

Change the Disk Size

// Make the disk bigger
diskSize = 150;

// Make it smaller
diskSize = 50;

Change the Disk Color

// Change to blue
diskColor = '#4ecdc4';

// Change to purple
diskColor = '#9b59b6';

// Change to gold
diskColor = '#f1c40f';

Move the Disk

// Move to top-left
diskX = 100;
diskY = 100;

// Move to center
diskX = 200;
diskY = 200;

Sin Wave Pulsing Effect

Understanding Math.sin()

The Math.sin() function returns a value that oscillates smoothly between -1 and 1. This makes it perfect for creating pulsing animations!

Sin Wave Properties

  • Output Range: -1 to 1
  • Period: 2π (≈6.28) radians
  • Smooth: Creates natural, organic motion

Key Formula

newSize = baseSize + Math.sin(time) * amplitude

Where amplitude controls how much the size changes

Step 4: Creating the Pulse Effect

We'll override the draw() function to add pulsing. Here's the code to paste into your console:

Basic Pulsing Disk

// Store the base size
let baseDiskSize = 100;
let pulseAmplitude = 30;  // How much it grows/shrinks
let pulseSpeed = 0.05;    // How fast it pulses
let time = 0;

// Override the draw function
draw = function() {
    background(30, 30, 40);
    
    // Calculate pulsing size using sin wave
    time += pulseSpeed;
    diskSize = baseDiskSize + Math.sin(time) * pulseAmplitude;
    
    // Draw the disk
    fill(diskColor);
    noStroke();
    ellipse(diskX, diskY, diskSize, diskSize);
    
    // Draw center point
    fill(255);
    ellipse(diskX, diskY, 10, 10);
    
    // Update display
    document.getElementById('display-size').textContent = 
        Math.round(diskSize);
}

How to Apply

  1. Open Developer Console (F12)
  2. Copy the code above
  3. Paste it into the console
  4. Press Enter
  5. Watch the disk start pulsing!

Step 5: Fine-Tuning the Pulse

After applying the pulse effect, you can adjust parameters in real-time:

Adjust Pulse Speed

// Slower pulse
pulseSpeed = 0.02;

// Faster pulse
pulseSpeed = 0.1;

// Very fast
pulseSpeed = 0.2;

Adjust Pulse Amplitude

// Subtle pulse
pulseAmplitude = 10;

// Medium pulse
pulseAmplitude = 30;

// Dramatic pulse
pulseAmplitude = 60;

Interactive Controls

Use these sliders to see the effect of different values:

Breaking Down the Math

The Pulse Formula Explained

diskSize = baseDiskSize + Math.sin(time) * pulseAmplitude;
Component Meaning Example
baseDiskSize The center size the disk oscillates around 100
Math.sin(time) Oscillates between -1 and 1 0.5 (at some moment)
pulseAmplitude Maximum change from base size 30
time Increases each frame to animate Keeps growing...

When Math.sin(time) = 1: size = 100 + 30 = 130

When Math.sin(time) = -1: size = 100 - 30 = 70

The disk smoothly oscillates between 70 and 130 pixels!

Sin Wave Color Cycling

Color Theory with Sin Waves

We can use sin waves to smoothly cycle through colors! Since colors have Red, Green, and Blue components (RGB), we can oscillate each component independently.

Red Channel

Math.sin(time)

Green Channel

Math.sin(time + 2)

Blue Channel

Math.sin(time + 4)

Phase Offset

By adding different values to time for each color channel, we create a phase offset. This means each color reaches its peak at a different moment, creating smooth color transitions!

Step 6: RGB Color Cycling

Paste this code into your console to make the disk cycle through rainbow colors:

Rainbow Cycling Disk

// Color cycling variables
let colorTime = 0;
let colorSpeed = 0.03;

// Override draw with color cycling
draw = function() {
    background(30, 30, 40);
    
    // Calculate RGB values using sin waves
    // Map sin output (-1 to 1) to color range (50 to 255)
    let r = Math.floor(150 + Math.sin(colorTime) * 105);
    let g = Math.floor(150 + Math.sin(colorTime + 2.094) * 105);  // +2π/3
    let b = Math.floor(150 + Math.sin(colorTime + 4.189) * 105);  // +4π/3
    
    colorTime += colorSpeed;
    
    // Apply the calculated color
    fill(r, g, b);
    noStroke();
    ellipse(diskX, diskY, diskSize, diskSize);
    
    // Draw center point
    fill(255);
    ellipse(diskX, diskY, 10, 10);
    
    // Update display
    let hexColor = '#' + 
        r.toString(16).padStart(2,'0') + 
        g.toString(16).padStart(2,'0') + 
        b.toString(16).padStart(2,'0');
    document.getElementById('display-color').textContent = hexColor;
    document.getElementById('display-color').style.color = hexColor;
}

Color Preview

This shows the color sequence created by the sin wave formula

Step 7: Combining Pulse AND Color!

Now let's combine both effects for the ultimate animated disk:

Complete Pulsing Rainbow Disk

// Combined animation variables
let baseDiskSize = 100;
let pulseAmplitude = 30;
let pulseSpeed = 0.05;
let colorSpeed = 0.03;
let time = 0;

// The ultimate draw function!
draw = function() {
    background(30, 30, 40);
    
    // Update time
    time += pulseSpeed;
    
    // Calculate pulsing size
    let currentSize = baseDiskSize + Math.sin(time) * pulseAmplitude;
    
    // Calculate rainbow colors
    let colorPhase = time * (colorSpeed / pulseSpeed);
    let r = Math.floor(150 + Math.sin(colorPhase) * 105);
    let g = Math.floor(150 + Math.sin(colorPhase + 2.094) * 105);
    let b = Math.floor(150 + Math.sin(colorPhase + 4.189) * 105);
    
    // Draw the disk with both effects!
    fill(r, g, b);
    noStroke();
    ellipse(diskX, diskY, currentSize, currentSize);
    
    // Draw glowing center
    fill(255, 255, 255, 200);
    ellipse(diskX, diskY, 15, 15);
    
    // Add a subtle outer ring
    noFill();
    stroke(r, g, b, 100);
    strokeWeight(3);
    ellipse(diskX, diskY, currentSize + 20, currentSize + 20);
    
    // Update displays
    diskSize = currentSize;
    document.getElementById('display-size').textContent = 
        Math.round(currentSize);
    
    let hexColor = '#' + 
        r.toString(16).padStart(2,'0') + 
        g.toString(16).padStart(2,'0') + 
        b.toString(16).padStart(2,'0');
    document.getElementById('display-color').textContent = hexColor;
    document.getElementById('display-color').style.color = hexColor;
}

Quick Apply

Click to instantly apply the pulsing rainbow effect to the demo disk above.

Understanding the Color Math

let r = Math.floor(150 + Math.sin(colorPhase) * 105);
1
Math.sin(colorPhase)

Returns a value between -1 and 1

2
... * 105

Scales the range to -105 to +105

3
150 + ...

Shifts range to 45-255 (valid RGB values)

4
Math.floor(...)

Rounds down to whole number (colors need integers)

Why +2.094 and +4.189?

These are 2π/3 and 4π/3 radians, which divide one complete cycle (2π) into three equal parts. This creates evenly-spaced color peaks!

R: 0°
G: 120°
B: 240°

Chrome DevTools Local Overrides

What Are Local Overrides?

While console commands are great for quick experiments, they disappear when you refresh the page. Chrome's Local Overrides feature lets you:

  • Edit actual source files directly in DevTools (JavaScript, CSS, HTML)
  • Save changes permanently to a local folder on your computer
  • Changes persist across page refreshes - your modifications stay!
  • See your edits in the actual Sources panel, not just paste commands

⚠️ Important to Understand

Local Overrides modify your local copy of the website files. The actual website is unchanged - only YOU see your modifications. This is perfect for learning, experimenting, and testing ideas!

Step 1: Create an Overrides Folder

First, create a folder on your computer where Chrome will save your modified files:

Windows

  1. Open File Explorer
  2. Navigate to your Documents folder (or Desktop)
  3. Right-click → NewFolder
  4. Name it DevTools-Overrides

Example path: C:\Users\YourName\Documents\DevTools-Overrides

Mac

  1. Open Finder
  2. Go to Documents folder
  3. Click File → New Folder
  4. Name it DevTools-Overrides

Example path: /Users/YourName/Documents/DevTools-Overrides

Tip

You only need to create this folder once. You can use the same folder for all your override experiments on any website!

Step 2: Enable Local Overrides in DevTools

Now connect your folder to Chrome DevTools:

1

Open DevTools

Press F12 (or Ctrl+Shift+I on Windows, +Option+I on Mac)

2

Go to the Sources Panel

Click the "Sources" tab at the top of DevTools (not Console!)

3

Find the Overrides Tab

In the left sidebar, you'll see tabs like Page, Filesystem, Overrides, Snippets. Click "Overrides".

(If you don't see it, click the >> arrows to show more tabs)

4

Select Your Folder

Click "+ Select folder for overrides" and choose the DevTools-Overrides folder you created.

5

Grant Permission

Chrome will ask: "DevTools requests full access to [folder]". Click "Allow".

6

Verify It's Enabled

You should see a checkbox: ☑ Enable Local Overrides. Make sure it's checked!

Elements Console Sources Network

← Your Sources panel will look something like this

Step 3: Find and Edit the JavaScript File

Now let's actually modify the disk-demo.js file:

1

Switch to the "Page" Tab

In the Sources sidebar, click "Page" to see the website's files.

2

Navigate to the JavaScript File

Expand the folders until you find disk-demo.js. Click to open it.

You'll see the full source code in the editor panel!

3

Find the draw() Function

Scroll down or use Ctrl+F to search for function draw()

function draw() {
    background(30, 30, 40);
    
    // Draw the disk
    fill(diskColor);
    noStroke();
    ellipse(diskX, diskY, diskSize, diskSize);
    ...
4

Edit the Code Directly!

Click inside the code and start typing! Add the pulsing effect by modifying the draw function:

// Add these at the top of the file (before function setup)
let time = 0;
let pulseSpeed = 0.05;
let pulseAmplitude = 30;
let baseDiskSize = 100;

// Then modify the draw() function:
function draw() {
    background(30, 30, 40);
    
    // Calculate pulsing size
    time += pulseSpeed;
    let currentSize = baseDiskSize + Math.sin(time) * pulseAmplitude;
    
    // Draw the disk with pulsing size
    fill(diskColor);
    noStroke();
    ellipse(diskX, diskY, currentSize, currentSize);
    
    // Draw center point
    fill(255);
    ellipse(diskX, diskY, 10, 10);
}
5

Save Your Changes

Press Ctrl+S (or +S on Mac) to save!

You'll see an indicator that the file has been saved to your overrides folder.

Success Indicators

  • A purple dot appears next to the filename indicating it's overridden
  • The changes take effect immediately (or after refresh)
  • If you look in your DevTools-Overrides folder, you'll see the modified file saved there!

Step 4: Test Your Persistent Changes

Now for the magic - refresh the page!

  1. Press F5 or click the refresh button
  2. Your modifications are still there!
  3. The disk should be pulsing with your custom code

Console Commands

  • Lost on page refresh
  • Must re-paste every time
  • Can't see full code context
  • Good for quick tests only

Local Overrides

  • Persists across refreshes
  • Saved to your computer
  • Edit full source code
  • Real development experience

Step 5: Managing Your Overrides

Remove an Override

Right-click the overridden file in the Sources panel and select "Delete override" to restore the original.

Temporarily Disable

Uncheck "Enable Local Overrides" in the Overrides tab to temporarily use original files.

Find Your Files

Check your DevTools-Overrides folder - you can open and edit the saved files in any code editor!

Pro Tips

  • You can override CSS files too! Great for experimenting with styles.
  • Overrides work on any website, not just local files.
  • Use this technique to prototype features before making real code changes.
  • The overrides folder creates subfolders matching the website's structure.

Practice: Full Override Workflow

Let's do a complete example from scratch. Follow these exact steps:

Goal: Add rainbow color cycling to the disk using Local Overrides
  1. Open DevTools (F12)
  2. Go to SourcesOverrides
  3. Select your overrides folder (create one if needed)
  4. Check "Enable Local Overrides"
  5. Go to SourcesPage
  6. Find and open disk-demo.js
  7. Find this line: let diskColor = '#ff6b6b';
  8. Add new lines after the variable declarations:
// Add these new variables at the top:
let colorTime = 0;
let colorSpeed = 0.03;

Then find the draw() function and replace the fill(diskColor); line with:

// Calculate rainbow color
colorTime += colorSpeed;
let r = Math.floor(150 + Math.sin(colorTime) * 105);
let g = Math.floor(150 + Math.sin(colorTime + 2.094) * 105);
let b = Math.floor(150 + Math.sin(colorTime + 4.189) * 105);
fill(r, g, b);
  1. Press Ctrl+S to save
  2. Refresh the page - your rainbow disk is permanent!

Advanced Techniques

Custom Waveforms

Sin isn't the only option! Try these variations:

Bouncing Effect (Absolute Sin)

// Only positive values - creates "bounce"
diskSize = baseDiskSize + 
    Math.abs(Math.sin(time)) * pulseAmplitude;

Heartbeat Effect

// Double-bump heartbeat
let beat = Math.pow(Math.sin(time), 2);
let beat2 = Math.pow(Math.sin(time + 0.5), 2);
diskSize = baseDiskSize + 
    (beat + beat2 * 0.5) * pulseAmplitude;

Breathing Effect

// Slow, smooth breathing
let breath = (Math.sin(time * 0.5) + 1) / 2;
diskSize = baseDiskSize * (0.7 + breath * 0.6);

Wobble Effect

// Multiple frequencies combined
diskSize = baseDiskSize + 
    Math.sin(time) * 20 + 
    Math.sin(time * 2.5) * 10 +
    Math.sin(time * 5) * 5;

Saving Your Modifications

Console modifications are lost on page refresh. Here's how to preserve them:

Method 1: Snippets

  1. In DevTools, go to Sources tab
  2. Find Snippets in the left sidebar
  3. Click + New snippet
  4. Paste your code
  5. Right-click → Run to execute

Method 2: Local Overrides

  1. In DevTools Sources tab, find Overrides
  2. Select a local folder for overrides
  3. Edit the page's JS file
  4. Changes persist across refreshes!

Method 3: Browser Extension

Use extensions like Tampermonkey or User JavaScript and CSS to automatically inject your code on specific pages.

Debugging Tips

Finding Variables

// List all global variables
Object.keys(window)

// Search for specific names
Object.keys(window).filter(k => 
    k.includes('disk'))

Pausing Animation

// Stop the animation
noLoop();

// Resume animation
loop();

Monitoring Values

// Watch a variable
setInterval(() => {
    console.log('Size:', diskSize);
}, 500);

Reverting Changes

// Simply refresh the page!
location.reload();

// Or restore original function
// (if you saved it first)

Challenges

Test Your Skills!

Try these challenges to practice what you've learned:

Beginner

Challenge 1: Slow Motion

Make the disk pulse 3 times slower than the default speed.

Hint pulseSpeed = 0.05 / 3;
Beginner

Challenge 2: Mega Disk

Make the disk oscillate between 50px and 200px.

Hint baseDiskSize = 125; pulseAmplitude = 75;
Intermediate

Challenge 3: Warm Colors Only

Modify the color formula to only show warm colors (reds, oranges, yellows).

Hint

Keep red high, vary green 0-200, keep blue low

Intermediate

Challenge 4: Position Oscillation

Make the disk move left/right while pulsing using sin on the X position.

Hint diskX = 200 + Math.sin(time * 2) * 50;
Advanced

Challenge 5: Inverse Pulse

When the disk grows, make it get darker. When it shrinks, make it brighter.

Hint

Link color brightness to the inverse of size: brightness = 255 - (diskSize - 70) * 2;

Advanced

Challenge 6: Multiple Disks

Create 3 disks with different sizes and phase-offset colors.

Hint

Draw multiple ellipses with different time offsets for each color calculation.

Quick Reference

Copy-Paste Commands

Enable Pulsing

let baseDiskSize=100,pulseAmplitude=30,pulseSpeed=0.05,time=0;draw=function(){background(30,30,40);time+=pulseSpeed;diskSize=baseDiskSize+Math.sin(time)*pulseAmplitude;fill(diskColor);noStroke();ellipse(diskX,diskY,diskSize,diskSize);fill(255);ellipse(diskX,diskY,10,10);}

Enable Rainbow

let colorTime=0,colorSpeed=0.03;draw=function(){background(30,30,40);let r=Math.floor(150+Math.sin(colorTime)*105),g=Math.floor(150+Math.sin(colorTime+2.094)*105),b=Math.floor(150+Math.sin(colorTime+4.189)*105);colorTime+=colorSpeed;fill(r,g,b);noStroke();ellipse(diskX,diskY,diskSize,diskSize);fill(255);ellipse(diskX,diskY,10,10);}

Enable Both

let baseDiskSize=100,pulseAmplitude=30,pulseSpeed=0.05,colorSpeed=0.03,time=0;draw=function(){background(30,30,40);time+=pulseSpeed;let currentSize=baseDiskSize+Math.sin(time)*pulseAmplitude,colorPhase=time*(colorSpeed/pulseSpeed),r=Math.floor(150+Math.sin(colorPhase)*105),g=Math.floor(150+Math.sin(colorPhase+2.094)*105),b=Math.floor(150+Math.sin(colorPhase+4.189)*105);fill(r,g,b);noStroke();ellipse(diskX,diskY,currentSize,currentSize);fill(255);ellipse(diskX,diskY,10,10);}

Reset to Default

diskSize=100;diskX=200;diskY=200;diskColor='#ff6b6b';draw=function(){background(30,30,40);fill(diskColor);noStroke();ellipse(diskX,diskY,diskSize,diskSize);fill(255);ellipse(diskX,diskY,10,10);}