Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/JustADev1024/threejs-car/llms.txt

Use this file to discover all available pages before exploring further.

Dream Car ships with a fully functional in-browser music player. Sixteen royalty-free tracks are pre-loaded into a <select> dropdown the moment the page opens, and you can extend the playlist at any time by pasting a direct MP3 URL into the text field and clicking Add. Playback is handled by the native Web Audio API — no external player library is needed.

Built-in Tracks

The 16 preset tracks are generated programmatically from a single array expression:
const presetUrls = Array.from({ length: 16 }, (_, i) =>
    `https://www.soundhelix.com/examples/mp3/SoundHelix-Song-${i+1}.mp3`
);
This produces URLs SoundHelix-Song-1.mp3 through SoundHelix-Song-16.mp3. All tracks are provided by SoundHelix and are licensed under the Creative Commons Attribution-ShareAlike 4.0 licence, making them safe to use in browser-based projects.

Track List Data Structure

Each entry in trackList is a plain object. Preset tracks and user-added tracks share the same array but carry slightly different shapes:
// Preset track (built-in)
{ url: string, isCustom: false, index: number }

// User-added track
{ url: string, isCustom: true, customLabel: string, index: number }
The array is initialised from the preset URLs at startup:
let trackList = presetUrls.map((url, idx) => ({ url, isCustom: false, index: idx }));
buildTrackOptions() iterates trackList to populate the <select> element. For preset tracks it labels each option "Track N" (or "Трек N" in Russian); for custom tracks it uses customLabel, which is the first 40 characters of the URL followed by an ellipsis.

Playback Functions

playTrack(url)

Stops any currently playing audio, creates a fresh Audio object, and begins playback:
function playTrack(url) {
    if (currentAudio) {
        currentAudio.pause();
        currentAudio = null;
    }
    currentAudio = new Audio(url);
    currentAudio.loop = true;
    currentAudio.volume = 0.5;
    currentAudio.play().then(() => {
        musicPlaying = true;
        updateMusicButton();
    }).catch(e => {
        console.error('Play error:', e);
        musicPlaying = false;
        currentAudio = null;
        alert(t('alertPlayError'));
        updateMusicButton();
    });
}
Key behaviours:
  • loop = true — the track repeats indefinitely until stopped.
  • volume = 0.5 — starts at 50% volume.
  • Promise-based error handling — if the browser rejects the play request (bad URL, CORS block, autoplay policy), a localised alert is shown and musicPlaying is reset to false.

stopMusic()

Pauses playback and discards the Audio object:
function stopMusic() {
    if (currentAudio) {
        currentAudio.pause();
        currentAudio = null;
    }
    musicPlaying = false;
    updateMusicButton();
}

toggleMusic()

The Play/Stop button’s handler. If music is playing it calls stopMusic(); otherwise it reads the currently selected URL from the dropdown and calls playTrack():
function toggleMusic() {
    if (musicPlaying) {
        stopMusic();
    } else {
        const selectedUrl = trackSelect.value;
        if (!selectedUrl) {
            alert(t('alertNoTrack'));
            return;
        }
        playTrack(selectedUrl);
    }
}

Adding Custom Tracks

addCustomTrack() is called when the user clicks the Add button:
function addCustomTrack() {
    let url = customUrlInput.value.trim();
    if (!url) {
        alert(t('alertEnterUrl'));
        return;
    }
    if (!url.match(/\.mp3($|\?)/i)) {
        alert(t('alertInvalidUrl'));
        return;
    }
    // If the URL already exists, select it instead of duplicating
    if (trackList.some(t => t.url === url)) {
        trackSelect.value = url;
        customUrlInput.value = '';
        if (musicPlaying) {
            stopMusic();
            playTrack(url);
        } else {
            alert(t('alertTrackAdded'));
        }
        return;
    }
    const newTrack = {
        url: url,
        isCustom: true,
        customLabel: url.substring(0, 40) + (url.length > 40 ? '…' : ''),
        index: trackList.length
    };
    trackList.push(newTrack);
    buildTrackOptions();        // rebuild the <select> with the new entry
    trackSelect.value = url;    // auto-select the new track
    customUrlInput.value = '';
    if (musicPlaying) {
        stopMusic();
        playTrack(url);         // immediately switch to the new track if playing
    } else {
        alert(t('alertTrackAdded'));
    }
}
1

Enter a URL

Paste a direct .mp3 link into the text field labelled ”➕ Direct MP3 link”.
2

Validate

The function checks that the URL contains .mp3 at the end or before a query string (/\.mp3($|\?)/i). If it doesn’t, a localised alert is shown and nothing is added.
3

Deduplicate

If the URL is already in trackList, the existing entry is selected in the dropdown rather than creating a duplicate.
4

Add and select

A new { url, isCustom: true, customLabel, index } object is pushed onto trackList. buildTrackOptions() rebuilds the <select> and the new entry is auto-selected.
5

Immediate playback

If music is already playing, stopMusic() is called and playTrack(url) begins the new track immediately.

Track Switching

Changing the dropdown selection while music is playing automatically switches to the new track — no need to stop and restart manually:
trackSelect.addEventListener('change', () => {
    if (musicPlaying) {
        const newUrl = trackSelect.value;
        if (newUrl) {
            stopMusic();
            playTrack(newUrl);
        } else {
            stopMusic();
        }
    }
});
Custom MP3 URLs must be direct links that resolve to a raw .mp3 file and must permit cross-origin requests (CORS). The server hosting the file must include an Access-Control-Allow-Origin header. Links copied from streaming services (Spotify, SoundCloud), file-sharing platforms (Dropbox public pages, Google Drive viewer URLs), or social media will almost always fail — either because the URL resolves to an HTML page rather than an audio file, or because the server blocks cross-origin requests from browser contexts.
The Newgrounds Audio Portal is an excellent source of CORS-friendly MP3 files. Many tracks on Newgrounds expose a direct .mp3 download URL that the browser can fetch without CORS errors. The placeholder text in the custom URL input field even calls this out: "➕ Direct MP3 link (from Newgrounds or other site)".

Build docs developers (and LLMs) love