Please bookmark this page to avoid losing your image tool!

Photo Xylophone With 8 Notes Maker

(Free & Supports Bulk Upload)

Drag & drop your images here or

The result will appear here...
You can edit the below JavaScript code to customize the image tool.
function processImage(originalImg, barGap = "6", cornerRadius = "8") {
    const gap = parseInt(barGap, 10) || 6;
    const radius = parseInt(cornerRadius, 10) || 8;

    // We constrain the layout to maximum dimensions for consistent styling
    const maxTotalWidth = 800;
    const maxTotalHeight = 400;
    
    // Calculate final drawing dimensions while preserving aspect ratio if possible
    const scale = Math.min(maxTotalWidth / originalImg.width, maxTotalHeight / originalImg.height, 1) || 1;
    const finalImgWidth = Math.max(originalImg.width * scale, 320); // enforce min width
    const finalImgHeight = Math.max(originalImg.height * scale, 150); // enforce min height
    
    const numNotes = 8;
    const sliceWidth = originalImg.width / numNotes;
    const finalSliceWidth = finalImgWidth / numNotes;

    // Frequencies for a C-major scale starting at C4
    const frequencies = [261.63, 293.66, 329.63, 349.23, 392.00, 440.00, 493.88, 523.25];
    let audioCtx = null;

    // Helper Web Audio API function to play a synthesized xylophone sound
    function playNote(freq) {
        if (!audioCtx) {
            audioCtx = new (window.AudioContext || window.webkitAudioContext)();
        }
        if (audioCtx.state === 'suspended') {
            audioCtx.resume();
        }

        const t = audioCtx.currentTime;

        // Primary tone
        const osc = audioCtx.createOscillator();
        const gain = audioCtx.createGain();
        osc.type = 'sine';
        osc.frequency.setValueAtTime(freq, t);
        
        gain.gain.setValueAtTime(0, t);
        gain.gain.linearRampToValueAtTime(1, t + 0.01);
        gain.gain.exponentialRampToValueAtTime(0.001, t + 0.5);
        
        osc.connect(gain);
        gain.connect(audioCtx.destination);
        osc.start(t);
        osc.stop(t + 0.6);

        // Harmonic tone for wooden "strike" characteristic
        const osc2 = audioCtx.createOscillator();
        const gain2 = audioCtx.createGain();
        osc2.type = 'triangle';
        osc2.frequency.setValueAtTime(freq * 2.5, t);
        
        gain2.gain.setValueAtTime(0, t);
        gain2.gain.linearRampToValueAtTime(0.4, t + 0.01);
        gain2.gain.exponentialRampToValueAtTime(0.001, t + 0.15);
        
        osc2.connect(gain2);
        gain2.connect(audioCtx.destination);
        osc2.start(t);
        osc2.stop(t + 0.2);
    }

    // Creating the main container
    const container = document.createElement('div');
    container.style.position = 'relative';
    container.style.display = 'flex';
    container.style.justifyContent = 'center';
    container.style.alignItems = 'center';
    container.style.padding = '40px 20px';
    container.style.background = 'linear-gradient(135deg, #8B5A2B, #5C3A21)';
    container.style.borderRadius = '16px';
    container.style.boxShadow = 'inset 0 0 30px rgba(0,0,0,0.6), 0 10px 20px rgba(0,0,0,0.3)';
    container.style.userSelect = 'none';

    // Decorative background wooden rails
    const topRail = document.createElement('div');
    topRail.style.position = 'absolute';
    topRail.style.top = '30%';
    topRail.style.left = '4%';
    topRail.style.right = '4%';
    topRail.style.height = '14px';
    topRail.style.background = '#3e2723';
    topRail.style.boxShadow = '2px 2px 6px rgba(0,0,0,0.7)';
    container.appendChild(topRail);

    const bottomRail = document.createElement('div');
    bottomRail.style.position = 'absolute';
    bottomRail.style.bottom = '30%';
    bottomRail.style.left = '4%';
    bottomRail.style.right = '4%';
    bottomRail.style.height = '14px';
    bottomRail.style.background = '#3e2723';
    bottomRail.style.boxShadow = '2px 2px 6px rgba(0,0,0,0.7)';
    container.appendChild(bottomRail);

    const notesContainer = document.createElement('div');
    notesContainer.style.display = 'flex';
    notesContainer.style.gap = `${gap}px`;
    notesContainer.style.zIndex = '1';
    notesContainer.style.alignItems = 'center';

    // Build the xylophone bars
    for (let i = 0; i < numNotes; i++) {
        const barWrapper = document.createElement('div');
        
        // Bars get progressively shorter corresponding to pitch
        const heightMultiplier = 1 - (i * 0.045);
        const currentHeight = finalImgHeight * heightMultiplier;
        
        barWrapper.style.width = `${finalSliceWidth}px`;
        barWrapper.style.height = `${currentHeight}px`;
        barWrapper.style.borderRadius = `${radius}px`;
        barWrapper.style.overflow = 'hidden';
        barWrapper.style.cursor = 'pointer';
        barWrapper.style.position = 'relative';
        barWrapper.style.boxShadow = '3px 3px 8px rgba(0,0,0,0.7), inset -2px -2px 5px rgba(0,0,0,0.4), inset 2px 2px 5px rgba(255,255,255,0.4)';
        barWrapper.style.transition = 'transform 0.05s, box-shadow 0.05s';
        barWrapper.style.background = '#333';

        const canvas = document.createElement('canvas');
        canvas.width = finalSliceWidth;
        canvas.height = currentHeight;
        canvas.style.display = 'block';
        canvas.style.width = '100%';
        canvas.style.height = '100%';
        canvas.style.pointerEvents = 'none';

        const ctx = canvas.getContext('2d');
        
        // Draw the respective image slice, adapting it to the current bar's height constraint
        ctx.drawImage(
            originalImg, 
            i * sliceWidth, 0, sliceWidth, originalImg.height, 
            0, 0, finalSliceWidth, currentHeight
        );

        // Draw structural metallic "screws" on the top and bottom of each bar
        const screwRadius = Math.max(2, Math.min(4, finalSliceWidth * 0.1));
        const screwYOffset = Math.min(20, Math.max(10, currentHeight * 0.1));

        ctx.fillStyle = '#111';
        
        // Top screw
        ctx.beginPath();
        ctx.arc(finalSliceWidth / 2, screwYOffset, screwRadius, 0, Math.PI * 2);
        ctx.fill();
        
        // Bottom screw
        ctx.beginPath();
        ctx.arc(finalSliceWidth / 2, currentHeight - screwYOffset, screwRadius, 0, Math.PI * 2);
        ctx.fill();

        // Adding interaction event listeners to simulate playing notes
        const pressNote = (e) => {
            e.preventDefault();
            playNote(frequencies[i]);
            barWrapper.style.transform = 'translateY(4px) scale(0.97)';
            barWrapper.style.boxShadow = '1px 1px 3px rgba(0,0,0,0.7), inset -1px -1px 3px rgba(0,0,0,0.4), inset 1px 1px 3px rgba(255,255,255,0.4)';
        };

        const releaseNote = () => {
            barWrapper.style.transform = 'translateY(0) scale(1)';
            barWrapper.style.boxShadow = '3px 3px 8px rgba(0,0,0,0.7), inset -2px -2px 5px rgba(0,0,0,0.4), inset 2px 2px 5px rgba(255,255,255,0.4)';
        };

        barWrapper.addEventListener('mousedown', pressNote);
        barWrapper.addEventListener('touchstart', pressNote, { passive: false });
        
        barWrapper.addEventListener('mouseup', releaseNote);
        barWrapper.addEventListener('mouseleave', releaseNote);
        barWrapper.addEventListener('touchend', releaseNote);

        barWrapper.appendChild(canvas);
        notesContainer.appendChild(barWrapper);
    }

    container.appendChild(notesContainer);
    
    return container;
}

Free Image Tool Creator

Can't find the image tool you're looking for?
Create one based on your own needs now!

Description

The Photo Xylophone With 8 Notes Maker is a creative tool that transforms any uploaded image into an interactive, musical xylophone. The tool slices your image into eight distinct bars of varying heights, each representing a different note in a C-major scale. Users can click or tap on the image slices to trigger synthesized xylophone sounds, creating a multisensory experience that combines visual art with audio. This tool is ideal for creating engaging social media content, digital art projects, or interactive educational tools for music and visual learning.

Leave a Reply

Your email address will not be published. Required fields are marked *