You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, titleText = "Music Tracker & Recorder") {
// Container for everything
const container = document.createElement('div');
container.style.position = 'relative';
container.style.width = originalImg.width + 'px';
container.style.height = originalImg.height + 'px';
container.style.maxWidth = '100%';
container.style.minWidth = '320px';
container.style.minHeight = '350px';
container.style.overflow = 'hidden';
container.style.fontFamily = '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif';
container.style.backgroundColor = '#111';
container.style.margin = '0 auto';
// Canvas to display image and audio visualization overlay
const canvas = document.createElement('canvas');
canvas.width = originalImg.width;
canvas.height = originalImg.height;
canvas.style.display = 'block';
canvas.style.width = '100%';
canvas.style.height = '100%';
canvas.style.objectFit = 'contain';
const ctx = canvas.getContext('2d');
container.appendChild(canvas);
// UI Overlay Container
const ui = document.createElement('div');
ui.style.position = 'absolute';
ui.style.top = '15px';
ui.style.right = '15px';
ui.style.width = '300px';
ui.style.maxWidth = 'calc(100% - 30px)';
ui.style.maxHeight = 'calc(100% - 30px)';
ui.style.backgroundColor = 'rgba(255, 255, 255, 0.95)';
ui.style.padding = '15px';
ui.style.borderRadius = '10px';
ui.style.boxShadow = '0 8px 16px rgba(0,0,0,0.6)';
ui.style.display = 'flex';
ui.style.flexDirection = 'column';
ui.style.gap = '12px';
ui.style.zIndex = '10';
ui.style.boxSizing = 'border-box';
ui.style.overflowY = 'auto';
// Tool Title
const title = document.createElement('div');
title.innerText = titleText;
title.style.fontWeight = 'bold';
title.style.fontSize = '15px';
title.style.textAlign = 'center';
title.style.color = '#333';
ui.appendChild(title);
// Search Topic Music Input
const searchInput = document.createElement('input');
searchInput.type = 'text';
searchInput.placeholder = 'Search music (Press Enter)';
searchInput.style.padding = '8px';
searchInput.style.border = '1px solid #ccc';
searchInput.style.borderRadius = '6px';
searchInput.style.width = '100%';
searchInput.style.boxSizing = 'border-box';
searchInput.style.outline = 'none';
ui.appendChild(searchInput);
// Search Results Area
const searchResults = document.createElement('div');
searchResults.style.maxHeight = '150px';
searchResults.style.overflowY = 'auto';
searchResults.style.fontSize = '12px';
ui.appendChild(searchResults);
// Drag and Drop Zone
const dropZone = document.createElement('div');
dropZone.innerText = 'Drag & Drop Audio Track Here';
dropZone.style.border = '2px dashed #888';
dropZone.style.borderRadius = '6px';
dropZone.style.padding = '20px 10px';
dropZone.style.textAlign = 'center';
dropZone.style.fontSize = '13px';
dropZone.style.color = '#555';
dropZone.style.cursor = 'pointer';
dropZone.style.transition = 'background-color 0.2s';
ui.appendChild(dropZone);
// Audio Recorder Button
const recordBtn = document.createElement('button');
recordBtn.innerHTML = '⏺ Record Mic Track';
recordBtn.style.padding = '10px';
recordBtn.style.border = 'none';
recordBtn.style.borderRadius = '6px';
recordBtn.style.backgroundColor = '#e63946';
recordBtn.style.color = '#fff';
recordBtn.style.cursor = 'pointer';
recordBtn.style.fontWeight = 'bold';
recordBtn.style.transition = 'background-color 0.2s';
ui.appendChild(recordBtn);
// Track Now Playing Info
const nowPlaying = document.createElement('div');
nowPlaying.style.fontSize = '12px';
nowPlaying.style.color = '#666';
nowPlaying.style.textAlign = 'center';
nowPlaying.style.whiteSpace = 'nowrap';
nowPlaying.style.overflow = 'hidden';
nowPlaying.style.textOverflow = 'ellipsis';
nowPlaying.innerText = 'Not playing';
ui.appendChild(nowPlaying);
// Audio Element
const audioElement = document.createElement('audio');
audioElement.controls = true;
audioElement.style.width = '100%';
audioElement.style.height = '35px';
audioElement.style.outline = 'none';
ui.appendChild(audioElement);
container.appendChild(ui);
// Web Audio API Setup
let audioCtx = null;
let analyser = null;
let source = null;
let isVisualizing = true;
function initAudio() {
if (!audioCtx) {
const AudioContext = window.AudioContext || window.webkitAudioContext;
if(!AudioContext) return;
audioCtx = new AudioContext();
analyser = audioCtx.createAnalyser();
analyser.fftSize = 256;
source = audioCtx.createMediaElementSource(audioElement);
source.connect(analyser);
analyser.connect(audioCtx.destination);
}
if (audioCtx && audioCtx.state === 'suspended') {
audioCtx.resume();
}
}
audioElement.addEventListener('play', () => {
initAudio();
});
// Render loop for visualizer
function visualize() {
requestAnimationFrame(visualize);
// If not playing, draw image once to clear old bars and sleep renderer
if (!analyser || audioElement.paused || audioElement.ended) {
if (isVisualizing) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
isVisualizing = false;
}
return;
}
isVisualizing = true;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
const bufferLength = analyser.frequencyBinCount;
const dataArray = new Uint8Array(bufferLength);
analyser.getByteFrequencyData(dataArray);
const barWidth = canvas.width / bufferLength;
let x = 0;
for (let i = 0; i < bufferLength; i++) {
const val = dataArray[i];
const barHeight = Math.max(0, val * (canvas.height / 255.0) * 0.4);
const r = Math.min(255, val + (25 * (i/bufferLength)));
const g = Math.min(255, 250 * (i/bufferLength));
const b = 150;
ctx.fillStyle = `rgba(${r}, ${g}, ${b}, 0.8)`;
ctx.fillRect(x, canvas.height - barHeight, barWidth - 1, barHeight);
x += barWidth;
}
}
visualize(); // Start loop
// Search Topic logic via iTunes Free Search API
searchInput.addEventListener('keydown', async (e) => {
if (e.key === 'Enter' && searchInput.value.trim()) {
searchResults.innerHTML = '<div style="padding: 5px; color: #444;">Searching...</div>';
try {
const query = encodeURIComponent(searchInput.value.trim());
const res = await fetch(`https://itunes.apple.com/search?term=${query}&entity=song&limit=5`);
const data = await res.json();
searchResults.innerHTML = '';
if(data.results.length === 0) {
searchResults.innerHTML = '<div style="padding: 5px; color: #444;">No results found.</div>';
return;
}
data.results.forEach(track => {
const item = document.createElement('div');
item.innerText = `${track.trackName} - ${track.artistName}`;
item.style.cursor = 'pointer';
item.style.padding = '8px 5px';
item.style.borderBottom = '1px solid #eee';
item.style.color = '#1d3557';
item.style.whiteSpace = 'nowrap';
item.style.overflow = 'hidden';
item.style.textOverflow = 'ellipsis';
item.style.transition = 'background-color 0.2s';
item.onmouseover = () => item.style.backgroundColor = '#f1faee';
item.onmouseout = () => item.style.backgroundColor = 'transparent';
item.onclick = () => {
nowPlaying.innerText = `Search Result: ${track.trackName}`;
audioElement.src = track.previewUrl;
audioElement.play().catch(console.error);
initAudio();
};
searchResults.appendChild(item);
});
} catch (err) {
searchResults.innerHTML = '<div style="padding: 5px; color: red;">Search failed.</div>';
}
}
});
// Drag and Drop Audio File Logic
dropZone.addEventListener('dragover', (e) => {
e.preventDefault();
dropZone.style.backgroundColor = '#e8f4f8';
});
dropZone.addEventListener('dragleave', (e) => {
e.preventDefault();
dropZone.style.backgroundColor = 'transparent';
});
dropZone.addEventListener('drop', (e) => {
e.preventDefault();
dropZone.style.backgroundColor = 'transparent';
if (e.dataTransfer.files && e.dataTransfer.files[0]) {
const file = e.dataTransfer.files[0];
if (file.type.startsWith('audio/')) {
const url = URL.createObjectURL(file);
nowPlaying.innerText = `Dropped File: ${file.name}`;
audioElement.src = url;
audioElement.play().catch(console.error);
initAudio();
} else {
alert('Please drop a valid audio file.');
}
}
});
// Audio Recorder Logic
let mediaRecorder = null;
let audioChunks = [];
let isRecording = false;
let stream = null;
recordBtn.onclick = async () => {
if (!isRecording) {
try {
stream = await navigator.mediaDevices.getUserMedia({ audio: true });
mediaRecorder = new MediaRecorder(stream);
mediaRecorder.ondataavailable = e => {
if (e.data.size > 0) audioChunks.push(e.data);
};
mediaRecorder.onstop = () => {
const audioBlob = new Blob(audioChunks, { type: mediaRecorder.mimeType || 'audio/webm' });
const audioUrl = URL.createObjectURL(audioBlob);
nowPlaying.innerText = 'Recorded Track';
audioElement.src = audioUrl;
audioElement.play().catch(console.error);
initAudio();
if (stream) stream.getTracks().forEach(track => track.stop());
};
audioChunks = [];
mediaRecorder.start();
isRecording = true;
recordBtn.innerHTML = '⏹ Stop Recording';
recordBtn.style.backgroundColor = '#457b9d';
} catch (err) {
alert('Microphone recording error / access denied: ' + err.message);
}
} else {
mediaRecorder.stop();
isRecording = false;
recordBtn.innerHTML = '⏺ Record Mic Track';
recordBtn.style.backgroundColor = '#e63946';
}
};
return container;
}
Apply Changes