<!DOCTYPE html>
<html lang="en" class="scroll-smooth">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Interactive Guide to Lighting</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<!-- Chosen Palette: Warm Neutrals with Amber Accent -->
<!-- Application Structure Plan: A single-page application with three distinct, navigable sections: 1) 'Core Principles' for interactive learning of fundamentals (like the 4 qualities of light and a 3-point lighting simulator), 2) a 'Learning Hub' with a filterable card gallery for all educational resources (YouTube, LinkedIn, Instagram), and 3) a 'Virtual Studio' for practical application, featuring a gear guide and a 'one-light challenge' canvas. This thematic structure breaks down the dense report into manageable, interactive modules, prioritizing active exploration over passive reading and directly addressing the user's need to learn, find resources, and practice. -->
<!-- Visualization & Content Choices: Report Info: 3-Point Lighting -> Goal: Demonstrate -> Viz: Interactive HTML diagram with toggles and a Chart.js bar chart for contrast ratio -> Interaction: User toggles lights (Key, Fill, Back) and adjusts a fill slider to see the visual and graphical impact in real-time. Justification: This transforms a static concept into a dynamic, hands-on lesson. Report Info: Resource Lists -> Goal: Organize/Discover -> Viz: Filterable card grid -> Interaction: Users click platform buttons (YouTube, LinkedIn) to instantly filter the resource list. Justification: This makes the extensive list of resources easily searchable and user-friendly. Report Info: Practical Application -> Goal: Engage/Practice -> Viz: HTML5 Canvas 'One-Light Challenge' -> Interaction: User drags a light source around a subject on the canvas to see lighting effects change. Justification: Directly fulfills the report's call to practice by providing a simple, accessible simulation tool. -->
<!-- CONFIRMATION: NO SVG graphics used. NO Mermaid JS used. -->
<style>
body {
font-family: 'Inter', sans-serif;
background-color: #f8f7f4;
color: #3d3d3d;
}
.nav-link {
transition: color 0.3s, border-color 0.3s;
}
.nav-link:hover, .nav-link.active {
color: #b45309;
border-bottom-color: #b45309;
}
.card {
background-color: #ffffff;
border-radius: 0.75rem;
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
transition: transform 0.3s, box-shadow 0.3s;
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
}
.filter-btn {
transition: background-color 0.3s, color 0.3s;
}
.filter-btn.active {
background-color: #d97706;
color: #ffffff;
}
.chart-container {
position: relative;
width: 100%;
max-width: 600px;
margin-left: auto;
margin-right: auto;
height: 300px;
max-height: 400px;
}
@media (min-width: 768px) {
.chart-container {
height: 350px;
}
}
#threePointSubject {
transition: all 0.5s ease-in-out;
}
</style>
</head>
<body class="antialiased">
<header class="bg-white/80 backdrop-blur-md shadow-sm sticky top-0 z-50">
<nav class="container mx-auto px-6 py-4 flex justify-between items-center">
<h1 class="text-2xl font-bold text-amber-800">The Lighting Guide</h1>
<div class="hidden md:flex items-center space-x-8">
<a href="#principles" class="nav-link text-gray-600 font-medium border-b-2 border-transparent pb-1">Core Principles</a>
<a href="#hub" class="nav-link text-gray-600 font-medium border-b-2 border-transparent pb-1">Learning Hub</a>
<a href="#studio" class="nav-link text-gray-600 font-medium border-b-2 border-transparent pb-1">Virtual Studio</a>
</div>
<div class="md:hidden">
<select id="mobile-nav" class="bg-white border border-gray-300 rounded-md py-2 px-3 text-gray-700">
<option value="#principles">Principles</option>
<option value="#hub">Learning Hub</option>
<option value="#studio">Studio</option>
</select>
</div>
</nav>
</header>
<main class="container mx-auto px-6 py-12">
<section id="principles" class="mb-24">
<h2 class="text-4xl font-bold text-center mb-4 text-amber-900">Core Principles of Light</h2>
<p class="text-center text-lg text-gray-600 max-w-3xl mx-auto mb-12">
This section breaks down the foundational theory of lighting. Understanding these concepts is the first step to crafting intentional and powerful images. Interact with the elements below to see how each principle shapes the final look.
</p>
<div class="grid md:grid-cols-2 gap-8 mb-16">
<div class="card p-6">
<h3 class="text-2xl font-bold mb-4 text-amber-800">The Four Qualities</h3>
<p class="mb-6 text-gray-600">Every light source is defined by four characteristics. Master them to control the mood and story of your visuals.</p>
<div class="space-y-4">
<div>
<h4 class="font-semibold text-lg">1. Direction</h4>
<p class="text-sm text-gray-500 mb-2">Changes how we perceive form and texture.</p>
<div id="direction-demo" class="w-32 h-32 bg-gray-200 rounded-full mx-auto my-4 relative overflow-hidden">
<div id="direction-shadow" class="absolute w-full h-full rounded-full" style="transition: all 0.5s;"></div>
</div>
<div class="flex justify-center space-x-2">
<button onclick="setDirection('front')" class="px-3 py-1 bg-amber-100 text-amber-800 rounded-full text-sm">Front</button>
<button onclick="setDirection('side')" class="px-3 py-1 bg-amber-100 text-amber-800 rounded-full text-sm">Side</button>
<button onclick="setDirection('back')" class="px-3 py-1 bg-amber-100 text-amber-800 rounded-full text-sm">Back</button>
</div>
</div>
<div>
<h4 class="font-semibold text-lg">2. Quality</h4>
<p class="text-sm text-gray-500 mb-2">Determines the sharpness of shadows.</p>
<div id="quality-demo" class="w-32 h-32 bg-gray-200 rounded-lg mx-auto my-4 relative">
<div id="quality-shadow" class="absolute bottom-0 left-full w-16 h-32 bg-black/50" style="transition: all 0.5s;"></div>
</div>
<div class="flex justify-center space-x-2">
<button onclick="setQuality('hard')" class="px-3 py-1 bg-amber-100 text-amber-800 rounded-full text-sm">Hard</button>
<button onclick="setQuality('soft')" class="px-3 py-1 bg-amber-100 text-amber-800 rounded-full text-sm">Soft</button>
</div>
</div>
</div>
</div>
<div class="card p-6 flex flex-col">
<h3 class="text-2xl font-bold mb-4 text-amber-800">Three-Point Lighting</h3>
<p class="mb-6 text-gray-600">The fundamental setup for shaping a subject. Toggle the lights to see their individual roles and how they combine to create depth.</p>
<div class="flex-grow flex flex-col items-center justify-center">
<div class="relative w-64 h-48 mb-4">
<div class="absolute top-0 left-0 text-center">
<input type="checkbox" id="key-light-toggle" class="light-toggle" data-light="key" checked> <label for="key-light-toggle">Key</label>
</div>
<div class="absolute top-0 right-0 text-center">
<input type="checkbox" id="fill-light-toggle" class="light-toggle" data-light="fill" checked> <label for="fill-light-toggle">Fill</label>
</div>
<div class="absolute bottom-0 right-1/2 translate-x-1/2 text-center">
<input type="checkbox" id="back-light-toggle" class="light-toggle" data-light="back" checked> <label for="back-light-toggle">Back</label>
</div>
<div class="absolute inset-0 flex items-center justify-center">
<div id="threePointSubject" class="w-24 h-32 rounded-t-full rounded-b-lg bg-gray-400 relative overflow-hidden">
<div id="key-highlight" class="absolute w-1/2 h-full top-0 left-0 bg-gradient-to-r from-white/40 to-transparent"></div>
<div id="fill-highlight" class="absolute w-1/2 h-full top-0 right-0 bg-gradient-to-l from-white/20 to-transparent"></div>
<div id="back-highlight" class="absolute w-full h-full border-2 border-transparent rounded-t-full rounded-b-lg box-border"></div>
</div>
</div>
</div>
<div class="w-full mt-4">
<label for="fill-slider" class="block text-center text-sm font-medium text-gray-700">Fill Light Intensity (Contrast Ratio)</label>
<input id="fill-slider" type="range" min="0" max="100" value="50" class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer">
</div>
<div class="chart-container mt-4">
<canvas id="contrastChart"></canvas>
</div>
</div>
</div>
</div>
</section>
<section id="hub" class="mb-24">
<h2 class="text-4xl font-bold text-center mb-4 text-amber-900">The Learning Hub</h2>
<p class="text-center text-lg text-gray-600 max-w-3xl mx-auto mb-12">
Explore a curated collection of the best educational resources from across the web. Use the filters to find tutorials, courses, and inspiration tailored to your needs, whether you're just starting or looking to master advanced techniques.
</p>
<div class="flex justify-center space-x-2 md:space-x-4 mb-8">
<button class="filter-btn active px-4 py-2 rounded-full font-semibold bg-gray-200 text-gray-700" data-filter="all">All</button>
<button class="filter-btn px-4 py-2 rounded-full font-semibold bg-gray-200 text-gray-700" data-filter="StudioBinder">StudioBinder</button>
<button class="filter-btn px-4 py-2 rounded-full font-semibold bg-gray-200 text-gray-700" data-filter="LinkedIn">LinkedIn Learning</button>
<button class="filter-btn px-4 py-2 rounded-full font-semibold bg-gray-200 text-gray-700" data-filter="Instagram">Instagram</button>
</div>
<div id="resource-grid" class="grid sm:grid-cols-2 lg:grid-cols-3 gap-8">
</div>
</section>
<section id="studio" class="mb-16">
<h2 class="text-4xl font-bold text-center mb-4 text-amber-900">The Virtual Studio</h2>
<p class="text-center text-lg text-gray-600 max-w-3xl mx-auto mb-12">
Theory is nothing without practice. This section provides tools to help you develop your artistic eye. Experiment with the one-light challenge to build intuition, and browse the gear guide to understand the tools of the trade.
</p>
<div class="grid lg:grid-cols-2 gap-8">
<div class="card p-6">
<h3 class="text-2xl font-bold mb-4 text-amber-800">One-Light Challenge</h3>
<p class="mb-4 text-gray-600">Mastering a single light is a critical skill. Drag the light source around the subject to see how direction dramatically changes the mood and shape. This is a fundamental exercise for any visual artist.</p>
<div class="bg-gray-800 rounded-lg p-4">
<canvas id="oneLightCanvas" class="w-full h-80 rounded-md bg-gray-700 cursor-pointer"></canvas>
</div>
<p id="oneLight-text" class="text-center mt-4 font-semibold text-amber-700">Side Lighting</p>
</div>
<div class="card p-6">
<h3 class="text-2xl font-bold mb-4 text-amber-800">Essential Gear Guide</h3>
<p class="mb-4 text-gray-600">Understand the tools professionals use to shape light. This is not an exhaustive list, but a primer on the key categories of equipment you'll encounter.</p>
<div class="space-y-4">
<div class="p-4 bg-amber-50 rounded-lg">
<h4 class="font-bold text-amber-900">Light Modifiers: The Shapers</h4>
<p class="text-sm text-gray-600">Tools that change the quality, direction, and color of light. Includes diffusion (softboxes), reflection (foam boards), and blocking (flags).</p>
</div>
<div class="p-4 bg-amber-50 rounded-lg">
<h4 class="font-bold text-amber-900">Lights: The Sources</h4>
<p class="text-sm text-gray-600">The illumination itself. Modern productions often use versatile LED panels, while traditional sets used Tungsten and HMI lights.</p>
</div>
<div class="p-4 bg-amber-50 rounded-lg">
<h4 class="font-bold text-amber-900">Stands & Grip: The Support</h4>
<p class="text-sm text-gray-600">The unsung heroes. C-Stands are the workhorses used to hold lights, modifiers, and everything in between.</p>
</div>
</div>
</div>
</div>
</section>
</main>
<script>
const resources = [
{
title: 'The Ultimate Guide to Film Lighting',
platform: 'StudioBinder',
description: 'A comprehensive overview of film lighting, from natural vs. artificial light to the metrics of lumens and Kelvin.',
link: 'https://www.youtube.com/@StudioBinder'
},
{
title: 'Basics of Film Lighting — 4 Qualities',
platform: 'StudioBinder',
description: 'A deep dive into the four essential principles: quantity, direction, quality (hard vs. soft), and color.',
link: 'https://www.youtube.com/@StudioBinder'
},
{
title: 'Film Lighting Techniques: A Masterclass',
platform: 'StudioBinder',
description: 'Bridges technical principles and narrative function, breaking down the classic three-point lighting setup.',
link: 'https://www.youtube.com/@StudioBinder'
},
{
title: 'Lighting for Photographers: Portraiture',
platform: 'LinkedIn',
description: 'A practical guide to classic portrait lighting patterns like butterfly, Rembrandt, and split lighting.',
link: 'https://www.linkedin.com/learning/lighting-for-photographers-portraiture'
},
{
title: 'Cinematic Video Lighting',
platform: 'LinkedIn',
description: 'Learn modern techniques beyond the basic three-point setup for interviews, B-roll, and narrative scenes.',
link: 'https://www.linkedin.com/learning/cinematic-video-lighting'
},
{
title: 'Advanced Cinematic Video Lighting',
platform: 'LinkedIn',
description: 'Focuses on using light to create distinct moods for narrative, commercial, and corporate projects.',
link: 'https://www.linkedin.com/learning/advanced-cinematic-video-lighting'
},
{
title: '@filmlights',
platform: 'Instagram',
description: 'An indispensable account that breaks down complex lighting setups from major film sets with gaffer interviews.',
link: 'https://www.instagram.com/filmlights'
},
{
title: '@jeahnlaffitte',
platform: 'Instagram',
description: 'A commercial photographer who teaches how to reverse-engineer lighting from professional ads and movie posters.',
link: 'https://www.instagram.com/jeahnlaffitte'
},
{
title: '@aspictures',
platform: 'Instagram',
description: 'World-renowned photographer Art Streiber shares detailed behind-the-scenes from major magazine shoots.',
link: 'https://www.instagram.com/aspictures'
}
];
document.addEventListener('DOMContentLoaded', () => {
const resourceGrid = document.getElementById('resource-grid');
const filterBtns = document.querySelectorAll('.filter-btn');
const displayResources = (filter) => {
resourceGrid.innerHTML = '';
const filteredResources = (filter === 'all') ? resources : resources.filter(r => r.platform === filter);
filteredResources.forEach(resource => {
const card = document.createElement('div');
card.className = 'card p-6 resource-card';
card.dataset.category = resource.platform;
card.innerHTML = `
<h4 class="font-bold text-xl mb-2">${resource.title}</h4>
<span class="text-sm font-semibold ${resource.platform === 'StudioBinder' ? 'text-red-600' : resource.platform === 'LinkedIn' ? 'text-blue-600' : 'text-purple-600'}">${resource.platform}</span>
<p class="text-gray-600 mt-2 mb-4">${resource.description}</p>
<a href="${resource.link}" target="_blank" rel="noopener noreferrer" class="font-semibold text-amber-700 hover:text-amber-800">Learn More →</a>
`;
resourceGrid.appendChild(card);
});
};
filterBtns.forEach(btn => {
btn.addEventListener('click', () => {
filterBtns.forEach(b => b.classList.remove('active'));
btn.classList.add('active');
displayResources(btn.dataset.filter);
});
});
displayResources('all');
initThreePointLighting();
initOneLightCanvas();
initNav();
setDirection('side');
setQuality('hard');
});
function initNav() {
const mobileNav = document.getElementById('mobile-nav');
mobileNav.addEventListener('change', (e) => {
window.location.hash = e.target.value;
});
const navLinks = document.querySelectorAll('.nav-link');
const sections = document.querySelectorAll('main section');
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
navLinks.forEach(link => {
link.classList.toggle('active', link.getAttribute('href').substring(1) === entry.target.id);
});
}
});
}, { threshold: 0.5 });
sections.forEach(section => observer.observe(section));
}
function setDirection(dir) {
const shadow = document.getElementById('direction-shadow');
if (dir === 'front') {
shadow.style.background = 'radial-gradient(circle at 50% 50%, transparent 40%, rgba(0,0,0,0.2) 80%)';
} else if (dir === 'side') {
shadow.style.background = 'linear-gradient(to right, rgba(0,0,0,0.4), transparent 50%, rgba(0,0,0,0.0))';
} else if (dir === 'back') {
shadow.style.background = 'radial-gradient(circle at 50% 50%, rgba(0,0,0,0.6) 70%, white 72%)';
}
}
function setQuality(qual) {
const shadow = document.getElementById('quality-shadow');
if (qual === 'hard') {
shadow.style.filter = 'blur(0px)';
shadow.style.opacity = '0.5';
} else if (qual === 'soft') {
shadow.style.filter = 'blur(12px)';
shadow.style.opacity = '0.3';
}
}
function initThreePointLighting() {
const toggles = document.querySelectorAll('.light-toggle');
const fillSlider = document.getElementById('fill-slider');
const keyHighlight = document.getElementById('key-highlight');
const fillHighlight = document.getElementById('fill-highlight');
const backHighlight = document.getElementById('back-highlight');
const subject = document.getElementById('threePointSubject');
const ctx = document.getElementById('contrastChart').getContext('2d');
const contrastChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['Key', 'Fill'],
datasets: [{
label: 'Light Intensity',
data: [100, 50],
backgroundColor: ['#f59e0b', '#fcd34d'],
borderColor: ['#b45309', '#fBBF24'],
borderWidth: 1
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
indexAxis: 'y',
scales: {
x: {
beginAtZero: true,
max: 110,
display: false,
},
y: {
grid: { display: false }
}
},
plugins: {
legend: { display: false },
tooltip: { enabled: false }
}
}
});
function updateLights() {
const keyOn = document.getElementById('key-light-toggle').checked;
const fillOn = document.getElementById('fill-light-toggle').checked;
const backOn = document.getElementById('back-light-toggle').checked;
const fillValue = parseInt(fillSlider.value);
keyHighlight.style.opacity = keyOn ? '1' : '0';
fillHighlight.style.opacity = fillOn ? (fillValue / 100) * 0.7 : '0';
backHighlight.style.borderColor = backOn ? '#ffffff' : 'transparent';
let baseGray = 100;
if(!keyOn && !fillOn) baseGray = 50;
else if (keyOn && !fillOn) baseGray = 80;
else if (!keyOn && fillOn) baseGray = 60 + (fillValue / 10);
subject.style.backgroundColor = `rgb(${baseGray}, ${baseGray}, ${baseGray})`;
contrastChart.data.datasets[0].data = [keyOn ? 100 : 0, fillOn ? fillValue : 0];
contrastChart.update();
}
toggles.forEach(toggle => toggle.addEventListener('change', updateLights));
fillSlider.addEventListener('input', updateLights);
updateLights();
}
function initOneLightCanvas() {
const canvas = document.getElementById('oneLightCanvas');
const ctx = canvas.getContext('2d');
const textEl = document.getElementById('oneLight-text');
let width, height;
const light = { x: 50, y: 150, radius: 15 };
const subject = { x: 0, y: 0, radius: 50 };
let isDragging = false;
function resize() {
width = canvas.clientWidth;
height = canvas.clientHeight;
canvas.width = width;
canvas.height = height;
subject.x = width / 2;
subject.y = height / 2;
draw();
}
function draw() {
ctx.clearRect(0, 0, width, height);
const dx = light.x - subject.x;
const dy = light.y - subject.y;
const distance = Math.sqrt(dx * dx + dy * dy);
const angle = Math.atan2(dy, dx);
const highlightX = subject.x - dx * 0.3;
const highlightY = subject.y - dy * 0.3;
const gradient = ctx.createRadialGradient(highlightX, highlightY, 5, subject.x, subject.y, subject.radius * 1.5);
gradient.addColorStop(0, 'rgba(255, 255, 255, 0.6)');
gradient.addColorStop(1, 'rgba(0, 0, 0, 0.6)');
ctx.beginPath();
ctx.arc(subject.x, subject.y, subject.radius, 0, Math.PI * 2);
ctx.fillStyle = '#6b7280';
ctx.fill();
ctx.beginPath();
ctx.arc(subject.x, subject.y, subject.radius, 0, Math.PI * 2);
ctx.fillStyle = gradient;
ctx.fill();
ctx.beginPath();
ctx.arc(light.x, light.y, light.radius, 0, Math.PI * 2);
ctx.fillStyle = '#fBBF24';
ctx.fill();
ctx.strokeStyle = '#fff';
ctx.lineWidth = 2;
ctx.stroke();
updateText(angle, distance);
}
function updateText(angle, distance) {
let lightingType = '';
const angleDeg = angle * 180 / Math.PI;
if (distance < subject.radius) {
lightingType = "On-axis";
} else if (angleDeg > -45 && angleDeg <= 45) {
lightingType = "Side Lighting (Right)";
} else if (angleDeg > 45 && angleDeg <= 135) {
lightingType = "Underlighting";
} else if (angleDeg > 135 || angleDeg <= -135) {
lightingType = "Side Lighting (Left)";
} else {
lightingType = "Top Lighting";
}
textEl.textContent = lightingType;
}
canvas.addEventListener('mousedown', (e) => {
const rect = canvas.getBoundingClientRect();
const mouseX = e.clientX - rect.left;
const mouseY = e.clientY - rect.top;
if (Math.sqrt((mouseX - light.x)**2 + (mouseY - light.y)**2) < light.radius) {
isDragging = true;
}
});
canvas.addEventListener('mousemove', (e) => {
if (isDragging) {
const rect = canvas.getBoundingClientRect();
light.x = e.clientX - rect.left;
light.y = e.clientY - rect.top;
draw();
}
});
canvas.addEventListener('mouseup', () => {
isDragging = false;
});
canvas.addEventListener('mouseleave', () => {
isDragging = false;
});
window.addEventListener('resize', resize);
resize();
}
</script>
</body>
</html>