Video Editing Shot Log Template
Footage Indexing and Post-Production Worksheet
Total Shots Logged: 0
Untitled Project
Roll/Media ID: A001 | Date: ---
Camera/Format: RED Komodo 6K | Editor: Editor Name
Footage Log & Notes
| ID | Start TC | Duration | Content Description | Status/Tag |
|---|
Generated by Video Editing Shot Log Template
Project & Source Media
Log a Shot
Enter the timecode data for each clip segment.
Current Log Entries
Log is empty.
"; return; } vslData.shots.forEach(shot => { const item = document.createElement('div'); item.className = 'vsl-log-item'; item.innerHTML = `
TC: ${shot.start} (${shot.duration}) - ${shot.description}
`;
outputs.shotListEditor.appendChild(item);
});
}
// --- 5. EVENT LISTENERS & ACTIONS ---
function attachListeners() {
// Meta Inputs
const metaInputs = Object.values(inputs).filter(i => !i.id.includes('inp-'));
metaInputs.forEach(inp => inp.addEventListener('input', renderAll));
// Add Shot Button
document.getElementById('btn-add-shot').addEventListener('click', addShot);
}
function addShot() {
const start = inputs.startTc.value.trim();
const end = inputs.endTc.value.trim();
const duration = inputs.duration.value.trim();
const description = inputs.description.value.trim();
const status = inputs.status.value;
if (!start || !end || !description) {
alert("Please enter Start TC, End TC, and Description.");
return;
}
const newShot = {
id: Date.now(),
start: start,
end: end,
duration: duration || "N/A",
description: description,
status: status
};
vslData.shots.push(newShot);
// Clear entry form for next shot
inputs.startTc.value = "";
inputs.endTc.value = "";
inputs.duration.value = "";
inputs.description.value = "";
renderAll();
}
window.removeShot = function(id) {
if(confirm("Remove this shot entry?")) {
vslData.shots = vslData.shots.filter(s => s.id !== id);
renderAll();
}
};
// --- 6. TAB NAVIGATION ---
window.vslSwitchTab = function(tabId) {
document.querySelectorAll('.vsl-tab-pane').forEach(p => p.classList.remove('active'));
document.querySelectorAll('.vsl-tab-btn').forEach(b => b.classList.remove('active'));
document.getElementById(tabId).classList.add('active');
document.querySelector(`.vsl-tab-btn[data-tab="${tabId}"]`).classList.add('active');
document.getElementById('shot-log-tool').scrollIntoView({behavior: 'smooth'});
};
document.querySelectorAll('.vsl-tab-btn').forEach(btn => {
btn.addEventListener('click', function() { vslSwitchTab(this.dataset.tab); });
});
// --- 7. PDF EXPORT ---
const btnDown = document.getElementById('vsl-download-btn');
if(btnDown) {
btnDown.addEventListener('click', function() {
renderAll();
const element = document.getElementById('vsl-render-area');
const filename = (inputs.projectTitle.value || 'Shot_Log').replace(/\s+/g,'_');
const opt = {
margin: 0.4,
filename: `${filename}_Roll_${inputs.rollId.value}.pdf`,
image: { type: 'jpeg', quality: 0.98 },
html2canvas: { scale: 2, useCORS: true },
jsPDF: { unit: 'in', format: 'letter', orientation: 'portrait' }
};
const origText = btnDown.innerText;
btnDown.innerText = "Generating Log...";
html2pdf().set(opt).from(element).save().then(() => {
btnDown.innerText = origText;
});
});
}
// Start
init();
});
