You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, tempoScale = 1.1) {
const tempo = parseFloat(tempoScale) || 1.1;
// Create the main container div
const container = document.createElement('div');
container.style.display = 'flex';
container.style.flexDirection = 'column';
container.style.alignItems = 'center';
container.style.justifyContent = 'center';
container.style.padding = '30px';
container.style.fontFamily = 'Arial, sans-serif';
container.style.background = 'linear-gradient(135deg, #0a0a0a, #1a2a3a)';
container.style.color = '#ffffff';
container.style.borderRadius = '12px';
container.style.boxShadow = '0 8px 20px rgba(0,0,0,0.5)';
container.style.width = '100%';
container.style.maxWidth = '500px';
container.style.boxSizing = 'border-box';
container.style.margin = '0 auto';
// Create a decorative canvas mixing the original image into a "Universal" style globe
const canvas = document.createElement('canvas');
canvas.width = 200;
canvas.height = 200;
const ctx = canvas.getContext('2d');
const cx = 100, cy = 100, r = 75;
// Draw the image clipped to a sphere
ctx.save();
ctx.beginPath();
ctx.arc(cx, cy, r, 0, 2 * Math.PI);
ctx.closePath();
ctx.clip();
if (originalImg && originalImg.width) {
// Scale and draw image to fill the circle
const scale = Math.max((r * 2) / originalImg.width, (r * 2) / originalImg.height);
const w = originalImg.width * scale;
const h = originalImg.height * scale;
const dx = cx - w / 2;
const dy = cy - h / 2;
ctx.drawImage(originalImg, dx, dy, w, h);
} else {
// Fallback globe gradient if image isn't valid
const grad = ctx.createRadialGradient(cx - 25, cy - 25, 10, cx, cy, r);
grad.addColorStop(0, '#4aa8ff');
grad.addColorStop(1, '#002244');
ctx.fillStyle = grad;
ctx.fill();
}
// Add a dark overlay to make text readable
ctx.fillStyle = 'rgba(0, 15, 30, 0.4)';
ctx.fill();
ctx.restore();
// Draw the planetary rings common to the logo
ctx.beginPath();
ctx.ellipse(cx, cy, r + 15, 25, 15 * Math.PI / 180, 0, 2 * Math.PI);
ctx.strokeStyle = 'rgba(255, 215, 0, 0.8)';
ctx.lineWidth = 4;
ctx.stroke();
// Draw logo text
ctx.beginPath();
ctx.font = 'bold 22px Arial, sans-serif';
ctx.fillStyle = '#FFD700';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.shadowColor = '#000000';
ctx.shadowBlur = 5;
ctx.shadowOffsetX = 1;
ctx.shadowOffsetY = 1;
ctx.fillText('UNIVERSAL', cx, cy);
container.appendChild(canvas);
// Titles
const title = document.createElement('h3');
title.innerText = 'Audio File: Major Motion Picture Fanfare';
title.style.margin = '20px 0 5px 0';
title.style.textAlign = 'center';
container.appendChild(title);
const subtitle = document.createElement('p');
subtitle.innerText = '(Produced via Web Audio Synth)';
subtitle.style.margin = '0 0 25px 0';
subtitle.style.fontSize = '13px';
subtitle.style.color = '#aaaaaa';
container.appendChild(subtitle);
// Play Button
const playBtn = document.createElement('button');
playBtn.innerText = '▶ Play Fanfare Synthesis';
playBtn.style.padding = '12px 24px';
playBtn.style.fontSize = '16px';
playBtn.style.fontWeight = 'bold';
playBtn.style.cursor = 'pointer';
playBtn.style.background = 'linear-gradient(to bottom, #f9d423, #ff4e50)';
playBtn.style.border = 'none';
playBtn.style.borderRadius = '25px';
playBtn.style.color = '#ffffff';
playBtn.style.boxShadow = '0 4px 10px rgba(0,0,0,0.3)';
playBtn.style.transition = 'transform 0.1s ease';
playBtn.onmousedown = () => playBtn.style.transform = 'scale(0.95)';
playBtn.onmouseup = () => playBtn.style.transform = 'scale(1)';
playBtn.onmouseleave = () => playBtn.style.transform = 'scale(1)';
let audioCtx = null;
// Web Audio Synthesizer logic for the fanfare sound
playBtn.onclick = () => {
if (!audioCtx) {
const AudioContext = window.AudioContext || window.webkitAudioContext;
audioCtx = new AudioContext();
}
// Browsers require resuming after user gesture if in suspended state
if (audioCtx.state === 'suspended') {
audioCtx.resume();
}
const now = audioCtx.currentTime;
// Factory function for a synthetic brass ensemble
function playBrassNote(freq, startTime, duration) {
// Setup multiple oscillators for a thicker sound
const osc1 = audioCtx.createOscillator();
const osc2 = audioCtx.createOscillator();
const osc3 = audioCtx.createOscillator();
osc1.type = 'sawtooth';
osc2.type = 'sawtooth';
osc3.type = 'square';
osc1.frequency.value = freq;
osc2.frequency.value = freq * 1.003; // Slight detune right
osc3.frequency.value = freq * 0.997; // Slight detune left
const filter = audioCtx.createBiquadFilter();
filter.type = 'lowpass';
// Envelope for filter to create a brass "swell"
filter.frequency.setValueAtTime(500, startTime);
filter.frequency.linearRampToValueAtTime(3500, startTime + 0.1);
filter.frequency.exponentialRampToValueAtTime(800, startTime + duration);
const gainNode = audioCtx.createGain();
// Amplitude envelope
gainNode.gain.setValueAtTime(0, startTime);
gainNode.gain.linearRampToValueAtTime(0.35, startTime + 0.05);
gainNode.gain.exponentialRampToValueAtTime(0.2, startTime + 0.2);
gainNode.gain.linearRampToValueAtTime(0.0001, startTime + duration - 0.05);
osc1.connect(filter);
osc2.connect(filter);
osc3.connect(filter);
filter.connect(gainNode);
gainNode.connect(audioCtx.destination);
osc1.start(startTime);
osc2.start(startTime);
osc3.start(startTime);
osc1.stop(startTime + duration);
osc2.stop(startTime + duration);
osc3.stop(startTime + duration);
}
// Setup a majestic fanfare melody approximation
const melody = [
{ note: 392.00, t: 0.0, d: 0.5 }, // G4
{ note: 261.63, t: 0.5, d: 0.5 }, // C4
{ note: 392.00, t: 1.0, d: 0.25 }, // G4
{ note: 523.25, t: 1.25, d: 0.25 }, // C5
{ note: 659.25, t: 1.5, d: 0.25 }, // E5
{ note: 783.99, t: 1.75, d: 0.75 }, // G5
{ note: 659.25, t: 2.5, d: 0.25 }, // E5
{ note: 523.25, t: 2.75, d: 0.25 }, // C5
{ note: 392.00, t: 3.0, d: 0.5 }, // G4
{ note: 261.63, t: 3.5, d: 0.5 }, // C4
{ note: 392.00, t: 4.0, d: 0.25 }, // G4
{ note: 523.25, t: 4.25, d: 0.25 }, // C5
{ note: 659.25, t: 4.5, d: 0.25 }, // E5
{ note: 1046.50, t: 4.75, d: 2.0 }, // C6
];
melody.forEach(item => {
playBrassNote(item.note, now + item.t * tempo, item.d * tempo);
});
// Factory function for orchestral drum/timpani hits
function playDrum(startTime) {
const osc = audioCtx.createOscillator();
const gainNode = audioCtx.createGain();
osc.frequency.setValueAtTime(80, startTime);
osc.frequency.exponentialRampToValueAtTime(30, startTime + 0.4);
gainNode.gain.setValueAtTime(0, startTime);
gainNode.gain.linearRampToValueAtTime(0.8, startTime + 0.02);
gainNode.gain.exponentialRampToValueAtTime(0.001, startTime + 0.5);
osc.connect(gainNode);
gainNode.connect(audioCtx.destination);
osc.start(startTime);
osc.stop(startTime + 0.6);
}
// Rhythmic accompaniment
const drums = [0.0, 0.5, 1.0, 1.75, 2.5, 3.0, 3.5, 4.0, 4.75];
drums.forEach(beat => playDrum(now + beat * tempo));
// Prevent stacking the audio if users spam click the button
playBtn.disabled = true;
playBtn.innerText = 'Playing...';
playBtn.style.opacity = '0.6';
setTimeout(() => {
playBtn.disabled = false;
playBtn.innerText = '▶ Play Fanfare Synthesis';
playBtn.style.opacity = '1';
}, (4.75 * tempo + 2.0 * tempo) * 1000);
};
container.appendChild(playBtn);
return container;
}
Apply Changes