cssAudio - Activefile-genericCSS - ActiveGeneric - ActiveHTML - ActiveImage - ActiveJS - ActiveSVG - ActiveText - Activefile-genericVideo - ActiveLovehtmlicon-new-collectionicon-personicon-teamlog-outoctocatpop-outspinnerstartv

Pen Settings

CSS Base

Vendor Prefixing

Add External CSS

These stylesheets will be added in this order and before the code you write in the CSS editor. You can also add another Pen here, and it will pull the CSS from it. Try typing "font" or "ribbon" below.

Quick-add: + add another resource

Add External JavaScript

These scripts will run in this order and before the code in the JavaScript editor. You can also link to another Pen here, and it will run the JavaScript from it. Also try typing the name of any popular library.

Quick-add: + add another resource

Code Indentation

     

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

            
              <head>
    <meta charset="utf-8">
    <title>Music Player 2nd</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="https://connect.soundcloud.com/sdk.js"></script>
</head>
<body>
  <div class="load-mask"></div>
  <header>
    <h1>Music Player</h1>
    <ul>
      <li id="genre-btn">Genre</li>
      <li id="query-box" ><input placeholder="Search"></li>
    </ul>
  </header>
    <nav id="genre-container" class="hidden">
      <svg class="close-btn">
        <line x1="7" y1="7" x2="33" y2="33" style="stroke:#222222;"/>
        <line x1="7" y1="33" x2="33" y2="7" style="stroke:#222222;"/>
      </svg>
      <ul>
        <li id="genre">
          <ul>
            <li>alternative rock</li>
            <li>ambient</li>
            <li>classical</li>
            <li>country</li>
            <li>dance</li>
            <li>deep house</li>
            <li>disco</li>
            <li>drum &amp; bass</li>
            <li>dubstep</li>
            <li>electro</li>
            <li>electronic</li>
            <li>folk</li>
            <li>hardcore techno</li>
            <li>hip hop</li>
            <li>house</li>
            <li>indie rock</li>
            <li>jazz</li>
            <li>latin</li>
            <li>metal</li>
            <li id="minimal techno">minimal techno</li>
            <li>piano</li>
            <li>pop</li>
            <li>progressive house</li>
            <li>punk</li>
            <li>r&amp;b</li>
            <li>rap</li>
            <li>reggae</li>
            <li>rock</li>
            <li>singer-songwriter</li>
            <li>soul</li>
            <li>tech house</li>
            <li>trance</li>
            <li>trip hop</li>
            <li>world</li>
            <li>audiobooks</li>
            <!-- <li>business</li> -->
            <li>comedy</li>
            <li>entertainment</li>
            <li>learning</li>
            <li>news&amp;politics</li>
            <li>religion&amp;Spirituality</li>
            <li>science</li>
            <li>sports</li>
            <li>storytelling</li>
            <li>technology</li>
          </ul>  
        </li>
      </ul>
    </nav>
    <div id="track-picker">
      <p>re-select genre</p>
      <svg class="close-btn">
        <line x1="7" y1="7" x2="33" y2="33" style="stroke:#222222;"/>
        <line x1="7" y1="33" x2="33" y2="7" style="stroke:#222222;"/>
      </svg>
      <svg id="left-arrow">
        <line x1="30"  y1="0" x2="10"   y2="20" style="stroke:#222222;"/>
        <line x1="10"  y1="20" x2="30"   y2="40" style="stroke:#222222;"/>
      </svg>
      <svg id="right-arrow">
        <line x1="10"  y1="0" x2="30"   y2="20" style="stroke:#222222;"/>
        <line x1="30"  y1="20" x2="10"   y2="40" style="stroke:#222222;"/>
      </svg>
      <ul></ul>
    </div>
    <div id="main-visual">
    </div>
    
    <section id="juke-box">
      <div id="play-btn"></div>
      <ul>
        <li>Track Title</li>
        <li>Artist Name</li>
      </ul>
      <div id="track-bar-container">
        <div id="track-bar">
          <div id="progress-bar"></div>
          <div id="fader"></div>
          <span id="playback-time">0:00</span>
          <span id="song-duration">4:54</span>
        </div>
      </div>
      <div id="volume-container">
        <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/164143/volume_loud.png" alt="play">
        <input type="range" min="0" max="100" value="100">
      </div>
    </section>


            
          
!
            
              /* reset5 © 2011 opensource.736cs.com MIT */
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,audio,canvas,details,figcaption,figure,footer,header,hgroup,mark,menu,meter,nav,output,progress,section,summary,time,video{border:0;outline:0;font-size:100%;vertical-align:baseline;background:transparent;margin:0;padding:0;}body{line-height:1;}article,aside,dialog,figure,footer,header,hgroup,nav,section,blockquote{display:block;}nav ul{list-style:none;}ol{list-style:decimal;}ul{list-style:disc;}ul ul{list-style:circle;}blockquote,q{quotes:none;}blockquote:before,blockquote:after,q:before,q:after{content:none;}ins{text-decoration:underline;}del{text-decoration:line-through;}mark{background:none;}abbr[title],dfn[title]{border-bottom:1px dotted #000;cursor:help;}table{border-collapse:collapse;border-spacing:0;}hr{display:block;height:1px;border:0;border-top:1px solid #ccc;margin:1em 0;padding:0;}input[type=submit],input[type=button],button{margin:0!important;padding:0!important;}input,select,a img{vertical-align:middle;}


@mixin vertical-centering {
    top: 50%;
    -webkit-transform: translateY(-50%);
    transform: translateY(-50%);
}

@charset "UTF-8";

@font-face {
  font-family: GeoSans;
  src:url(//s3-us-west-2.amazonaws.com/s.cdpn.io/164143/GeosansLight.ttf);
}

/*cascade starts*/
body {
    font-family: GeoSans;
    /*font-size: 62.5%;*/
    background-color: #FFFFFF;;
    background-size: cover;
    -webkit-animation: hue 30s infinite linear;
    
    background-blend-mode: screen;
}
@-webkit-keyframes hue {
  from {
    -webkit-filter: hue-rotate(0deg);
  }

  to {
    -webkit-filter: hue-rotate(-360deg);
  }
}

@-webkit-keyframes goTopZero {
    from {transform: translateY(0px)}
    to { transform: translateY(700px)}
}
h1 {
    font-size: 32px;
}
li {
    list-style: none;
}

svg {
    width: 40px;
    height: 40px;
}

.load-mask {
    //display:none;
    position: fixed;
    width: 100%;
    height: 100%;
    background: rgba(70, 70, 70, 0.4);
    text-align: center;
    z-index: 1000;
    top: 0;
    &:after {
        content: "";
        position: absolute;
        width: 40px;
        height: 40px;
        top: calc(50% - 25px);
        left: calc(50% - 25px);
        border-bottom: 5px solid rgba(0, 0, 0, .1);
        border-left: 5px solid rgba(0, 0, 0, .1);
        border-right: 5px solid rgba(0, 0, 0, .1);
        border-top: 5px solid rgba(0, 0, 0, .4);
        border-radius: 100%;
        -webkit-animation: rot .6s infinite linear;
        animation: rot .6s infinite linear;
    }
}

@-webkit-keyframes rot {
    from {transform: rotate(0deg);}
    to {transform: rotate(359deg);}
}

@keyframes rot {
    from {transform: rotate(0deg);}
    to {transform: rotate(359deg);}
}

.alert {
    position: fixed;
    width: 100%;
    height: 100%;
    top: 0;
    background: rgba(70, 70, 70, 0.4);
    z-index: 1000;
    color: #FFFFFF;
    line-height: 100vh;
    text-align: center;
}

.visible {
    // transform: translateY(700px);
    // -webkit-animation: goTopZero 300ms linear;
    -webkit-transition: top 500ms;
    top: 0px;
}

.hidden {
    -webkit-transition: top 500ms;
    top: -700px;
}

/*
header
*/
header {
    width: 100%;
    height: 100px;
    background-color: rgba(150, 150, 150, 0.6);
    >h1 {
        padding-top: 34px;
        margin-left: 100px;
        display: inline-block;
        float: left;
    }
    >ul {
        width: 400px;
        float: right;
        padding-top: 34px;
        li {
            display: block;
            width: 160px;
            height: 50px;
            float: left;
            line-height: 50px;
            &:nth-child(1) {
                text-align: center;
                &:hover {
                    cursor: pointer;
                }
            }
            &:nth-child(2) {
                input {
                    border-radius: 5px;
                    height: 20px;
                    padding: 0 10px;
                    outline-width: 0;
                    font-family: GeoSans;
                    font-size: 11px;
                    width: 150px;
                }

            }
        }
    }
}


/*
nav
*/
#genre-container {
    position: absolute;
    width: 100%;
    //top: -700px;
    display: block;
    background-color: rgba(255, 255, 255, 0.6);
    ul {
        li {
            h2 {
                margin: 10px;
                font-size: 20px;
                text-align: center;
            }
        }
    }
}

.close-btn {
    position: absolute;
    top: 10px;
    right: 10px; 
    cursor: pointer;
}

#genre>ul {
    margin: 10px auto;
    >li {
        &:hover {
            cursor: pointer;
        }
    }
}

#track-picker {
    width: 100%;
    height: 220px;
    position: absolute;
    top: 0;
    background-color: rgba(255, 255, 255, 0.6);
    display: none;
    p {
        display: block;
        width: 120px;
        margin: 15px auto 0;
        text-align: center;
        text-decoration: underline;
        cursor: pointer;
    }
    svg {
        width: 40px;
        height: 40px;
        position: absolute;
        top: 90px;
        z-index: 100;
        &.close-btn {
            top:   10px;
            right: 10px;
        }
        &:hover {
            cursor: pointer;
        }
        &#left-arrow {
            left: 10px;
        }
        &#right-arrow {
            right: 10px;
        }
    }
    ul {
        margin: 0 auto;
        width: 100%;
        position: relative;
        li {
            display: block;
            width: 150px;
            height: 150px;
            margin: 20px 20px;
            background-color: #959595;
            float: left;
            figure {
                    filter: grayscale(1);
                    -webkit-filter: grayscale(1);
                    transition: -webkit-filter 1s;
                    cursor: pointer;
                    &:hover {
                        -webkit-filter: grayscale(0);
                        transition: -webkit-filter 1s;
                    }
                position: relative;
                img {
                    width: 150px;
                    height: 150px;
                    display: block;
                }
                figcaption {
                    font-size: 11px;
                    color: #FFFFFF;
                    position: absolute;
                    background-color: rgba(0, 0, 0, 0.3);
                    @include vertical-centering;
                    text-align: center;
                    width: 150px;
                    padding: 10px 0;

                    span {
                        display: block;
                        width: 150px;
                        &.track-title {

                        }
                        &.track-duration {
                            margin-top: 15px;
                        }
                        &.artist-name {
                            display: none;
                        }
                    }

                }
            }
        }
    }
}



$genre-list-width: 160;
@for $i from 2 through 8 {
    @media (min-width: $genre-list-width * $i + px) and (max-width: $genre-list-width * ($i + 1) + px){
        #genre>ul{
            width: $genre-list-width * ($i - 1) + px;
        }
    }
}


@media (min-width: 1440px)  {
    #genre>ul{
        width: 1300px;
    }
}
#genre>ul>li {
    line-height: 2em;
}
/*
jukebox
*/
#juke-box {
    position: fixed;
    // position: relative;
    width: 100%;
    height: 120px;
    border: 1px solid #D2D2D2;
    z-index: 100;
    bottom: 0;
    background-color: rgba(150, 150, 150, 0.6);
    /*text-align: center;*/
    >ul {
        >li {
            list-style: none;
            text-align: center;
            line-height: 2em;
            margin: 0 auto;
            overflow-y: hidden;
            &:nth-of-type(1) {
                font-size: 22px;
                height: 44px;
                width: 95%;
            }
            &:nth-of-type(2) {
                font-size: 18px;
                height: 36px;
                width: 70%;
                line-height: 24px;
            }
        }
    }
}

/*
track-bar
*/
#track-bar-container {
    height: 20px;
    width: 60%;
    position: relative;
    left: 20%;
    padding-top: 15px;
    cursor: pointer;
    #track-bar {
        height: 5px;
        background-color: #000000;
        position: relative;
        >span {
            position: absolute;
            top: -5px;
            &:nth-of-type(1) {
                left: calc(0% - 50px);
            }
            &:nth-of-type(2) {
                right: calc(0% - 50px);
            }
        }
    }
}


/*
progress bar
*/
#progress-bar {
    width: 200px;
    background-color: #FFFFFF;
    height: 5px;
}

#fader {
    width: 10px;
    height: 25px;
    position: relative;
    left: 200px;
    top: -15px;
    background-color: #ffffff;
}

#search-bar {
    float: right;
    margin-right: 100px;
}

li#genre>ul>li {
    float: left;
    width: 160px;
    text-align: center;
}

#history {
    clear: left;
}
/*
main-visual
*/
#main-visual {
    width: 50vh;
    height: 50vh;
    background: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/164143/irememberyou-vs.jpg) center center no-repeat;
    background-size: cover;
    position: absolute;
    left: 50%;
    margin-left: -25vh;
    @include vertical-centering;
    z-index: -1;
}

/*
play-btn
*/
#play-btn {
    background: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/164143/play.png)5px 5px no-repeat;
    background-size: 30px 30px;
    width: 40px;
    height: 40px;
    position: absolute;
    top: 45px;
    left: 100px;
    cursor: pointer;
}

/*
volume container
*/
#volume-container {
    float: right;
    margin-top: -67px;
    margin-right: 100px;
    width: 40px;
    height: 40px;
    cursor: pointer;
    -webkit-transition: margin-top 1s;
    &:hover{
        margin-top: -130px;
        height: 140px;
        cursor: pointer;
        -webkit-transition: margin-top 1s;
        >input[type=range] {
            display: block;
            margin-top: 5px;
            cursor: pointer;
        }
    }
    >img {
        width: 26px;
        height: auto;
        left: 8px;
        top: 5px;
        position: relative;
        z-index: 30;
    }
    >input[type=range] {
        display: none;
        -webkit-appearance: none;
        -webkit-transform: rotate(-90deg);
        outline: 0;
        position: relative;
        top: 47px;
        left: -32px;
        background-color: #EBEBEB;
        height: 8px;
        width: 100px;
        border-radius: 6px;
        &::-webkit-slider-thumb {
            -webkit-appearance: none;
            width: 10px;
            height: 10px;
            border-radius: 50%;
            background:#FFFFFF;
        }
    }
}


/*
media query
*/
@media (max-width: 1024px)  {
    #play-btn{
        left: 50px;
    }
    #volume-container{
        margin-right: 50px;
    }
    #main-visual {
        width: 719px;
    }
}
@media (max-width: 719px) {
    #main-visual {
        width: 100%;
        height: 300px;
    }
}
@media (max-width: 700px)  {
    #play-btn{
        left: 20px;
    }
    #volume-container{
        margin-right: 20px;
    }
}

            
          
!
            
              /*

Copyright (c) 2014 Yuma Yanagisawa

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

*/

;(function(window, document, $) {

    ///////////
    // data //
    /////////

    // audio data
    var audioCtx;
    if('webkitAudioContext' in window) {
        audioCtx = new webkitAudioContext();
    } else {
        audioCtx = new window.AudioContext();
    }
    var buf;
    var sound;
    var gainNode;

    // interval
    var progressTimer;

    // time
    var initialTimestamp = 0;
    var pausedTimestamp = 0;
    var pausedDuration = 0;
    var now = 0;
    var trackDuration = 0;
    
    // physical
    var trackBarWidth = null;
    var leftPositionOfContainer = null;

    // id for songs
    var testId = 128843605;
    var CLIENT_ID = '8f474de4d1dedd5a6a4f4cbb60f4e6b8';


    $(function() {
        main();
    });

    ///////////
    // main //
    /////////
    function main() {
        // authorize SoundCloud API access
        SC.initialize({
        client_id: CLIENT_ID
        });
        // set nav view
        setViewEventListeners();

        // get global variables
        trackBarWidth = getTrackBarWidth();
        leftPositionOfContainer = getLeftPositionOfContainer();

        removeMask();
    }

    function init(isAudioDataReady) {
        // check whether or not the request successed
        if(!isAudioDataReady) {
            if (isAfterFirstTrack) {
                resetTrackData();
            }
            removeMask();
            // reset main visual
            resetMainVisual();
            showAlert();
            return;
        } else {
            // start init
            if (isAfterFirstTrack) {
                resetAudioData();
                resetTrackData();
                swapBtn();
                resetAudioEventListers();
            } else {
                changeUserState();
                resetTrackData();
            }

            setAudio();
            setAudioDuration();

            setGain();
            connectGain();
            connectAudio();

            setAudioEventListeners();

            setTrackDuration();

            // tell initial setting done
            removeMask();
        }

    }


    /////////////---------------------------------------------------------
    /// CONTROLLER
    ///////////-----------------------------------------------------------


    //--------------------------------------------------------------------
    // controll transition related methods
    //--------------------------------------------------------------------

    function setViewEventListeners() {
        $('#genre-btn').on('click', function() {
            swapGenreContainerView('visible');

            setGenrePicker();
        });

        $('#left-arrow').on('click', function() {
            setSlideAnimationManager('backward');
        });

        $('#right-arrow').on('click', function() {
            setSlideAnimationManager('forward');
        });

        $('#genre-container>svg.close-btn').on('click', function() {
            detachSetGenrePickerEventListener();
            swapGenreContainerView('hidden');
        });

        $('#track-picker>svg.close-btn').on('click', function() {
            detachSelectingTrackEevntLister();
            resetTrackPickerView();
            resetTrackData();
        });

        $('#track-picker>p').on('click', function() {
            detachSetGenrePickerEventListener();
            resetTrackPickerView();
            swapGenreContainerView('visible');
            resetTrackData();
            setGenrePicker();
        });

        $('#query-box>input').on('keypress', function(event) {
            if(event.keyCode === 13) {
                var query = $(this).val();
                setTrackPickerByQuery(query);
            }
        });

    }

    function setGenrePicker() {
        $('#genre').on('click', 'li', function() {
            var target = $(this);
            setTrackPickerByGenre(target);
            $('#genre').off('click', 'li');
        });
    }

    function detachSetGenrePickerEventListener() {
        $('#genre').off('click', 'li');
    }

    function setSelectingTrackEventListerner() {
        $('#track-picker>ul>li>figure').on('click', function() {
            setPlayer($(this));
        });
    }

    function detachSelectingTrackEevntLister() {
        $('#track-picker>ul>li>figure').off('click');
    }

    function setPlayer(aTarget) {

        var target = aTarget.find('img');
        var trackId = getElementId(target);
        var streamUrl = getStreamUrl(trackId);
        var targetSrc = getElementSrc(target);

        var titleDom = aTarget.find('figcaption>span.track-title');
        var artistNameDom = aTarget.find('figcaption>span.artist-name');
        // hide
        resetTrackPickerView();

        // loading starts
        addMask();


        setMainVisualDataManager();

        // main visual
        var mainVisualUrl = getMainVisualUrl(targetSrc);
        // convert attr to css format
        mainVisualUrl = convertAttrToCss(mainVisualUrl);
        var trackTitle = getElementText(titleDom);
        var artistName = getElementText(artistNameDom);

        changeMainVisual(mainVisualUrl, trackTitle, artistName);


        // artist name
        changeTitieOnProgressBar();
        // asynchronous method
        var promise = getAudio(streamUrl);
        promise
        .then(init);
    }

    function setMainVisualDataManager() {
        // store img src of main visual to show it again when the xhr fails
        var lastMainVisualImgSrc = getElementBackground($('#main-visual'));
        console.log(lastMainVisualImgSrc);
        // and set
        setMainVisualImgSrc(lastMainVisualImgSrc);

        var lastTitle = getElementText($('#juke-box>ul>li:first-child'));
        setLastTitle(lastTitle);

        var lastArtistName = getElementText($('#juke-box>ul>li:last-child'));
        setLastArtistName(lastArtistName);
    }

    function setTrackPickerByGenre(aTarget) {
        var targetGenre = getElementText(aTarget);
        swapGenreContainerView('hidden');
        var promise = getDataOfSelectedGenre(targetGenre);
        promise
        .then(setTrackPickerManager);
    }

    function setTrackPickerByQuery(aQuery) {
        var promise = getDataOfQuery(aQuery);
        promise
        .then(setTrackPickerManager);
    }

    // manage whole functions of picker
    function setTrackPickerManager(aDataOfSongs) {
        console.log(aDataOfSongs);
        setPickerViewManager(arrayOfSongsData);

        setPickerDataManager(aDataOfSongs);
        var visibleFigure = getVisibleTrackFigure();
        var index = getCurrentIndexOfTrackOnTheLeft();
        var remainedTracksFromIndex = calcDisplayableNumber(index);
        if (remainedTracksFromIndex < visibleFigure) {
            visibleFigure = remainedTracksFromIndex;
        }

        displayTrackPicker(visibleFigure, arrayOfSongsData, index);
        setSelectingTrackEventListerner();
    }

    function setPickerDataManager(aDataOfSongs) {

        for (var i = 0; i < aDataOfSongs.length; i++) {
            var trackData = extractInfo(aDataOfSongs[i]);
            if (
                (trackData.artwork !== null) &&
                (trackData.streamable === true)
                ) {
                organizeStoringData(true, trackData);
            }
        }
    }


    function organizeStoringData(aIsLoadable, aTrackData) {
        if (aIsLoadable) {
            aTrackData.artwork = replaceArtworkUrl(aTrackData.artwork);
            addInfo(aTrackData);
            incrementTotalSongsFigure();
        }
    }

    // dom of track picker
    function setPickerViewManager(aArrayOfSongs) {
        var windowSize = getWindowSize();
        var figureOfVisibleTracks = getDisplayingTracksFigure(windowSize);
        setVisibleTrackFigure(figureOfVisibleTracks);
        var pickerWidth = getModifiedPickerWidth(figureOfVisibleTracks);
        changeStyle($('#track-picker>ul'), 'width', pickerWidth);
    }

    // manage slide animation
    function setSlideAnimationManager(aDirection) {
        var promise = slidePicker(aDirection, false);
        promise
        .then(organizePickerListContents);
    }

    // manage DOM of picker
    function organizePickerListContents(aDirection) {
        // reset array
        makeListContentsEmpty();
        
        // decide which songs to be displayed
        var currentIndex = getCurrentIndexOfTrackOnTheLeft();
        var numOfTracksOnScreen = getVisibleTrackFigure();
        var newIndex =  calcCurrentIndexOfTrackOnTheLeft(currentIndex, numOfTracksOnScreen, aDirection);
        setCurrentIndexOfTrackOnTheLeft(newIndex);

        var index = getCurrentIndexOfTrackOnTheLeft();
        console.log(index);
        var remainedTracksFromIndex = calcDisplayableNumber(index);
        if (remainedTracksFromIndex < numOfTracksOnScreen) {
            numOfTracksOnScreen = remainedTracksFromIndex;
        }

        // display it again
        displayTrackPicker(numOfTracksOnScreen, arrayOfSongsData, newIndex);

        // animation
        changePickerPositionX(aDirection);
        slidePicker(aDirection, true);

        //set eventlisterners
        setSelectingTrackEventListerner();

    }

    function resetMainVisual() {
        var imgSrc = getMainVisualImgSrc();
        var trackTitle = getLastTitle();
        var artistName = getLastArtistName();

        changeMainVisual(imgSrc, trackTitle, artistName);

    }

    //-------------------------------------------------------------
    // controll audio related methods
    //-------------------------------------------------------------

    function setAudioEventListeners() {

        $('#play-btn').on('click', function() {
            setStreamController();
        });

        $('#track-bar-container').on('click', function(event) {
            faderMoveByClick(event);
        });

        $('#track-bar-container').on('mousedown', '#fader', function(event) {
            setFaderDrag(event);
        });

        $('#volume-container>input').on('click', function(event) {
            var volume =  getVolume(event);
            changeVolume(volume);
        });

    }

    function resetAudioEventListers() {
        $('#play-btn').off('click');
        $('#track-bar-container').off('click');
        $('#track-bar-container').off('mousedown', '#fader');
        $('#volume-container>input').off('click');
    }

    function faderMoveByClick(event) {
        // change positions of fader, progressbar
        var cursorX =  getCursorPos(event);
        if (cursorX < 0) {
            cursorX = 0;
        }
        changeStyle($('#fader'), 'left', cursorX);
        changeStyle($('#progress-bar'), 'width', cursorX);

        setModifiedPlaybackTimeStatus(true);
        // display possible playback time
        var playbackTime = calcPlaybackTime(cursorX);
        // playbacktime in seconds & minutes
        playbackTime = convertPlaybackTime(playbackTime);
        displayPlaybackTime($('#playback-time'), playbackTime);

        resetData();
        // prepare audio buffer again
        disconnectAudio();
        setAudio();
        connectGain();

        // play it immediately
        if (isStreaming) {
            clearInterval(progressTimer);
            setStream();
        }
    }

    function setFaderDrag(event) {
        if (isStreaming) {
            pause();
        }
        resetData();
        clearInterval(progressTimer);
        var $jukeBox = $('#juke-box');

        $jukeBox.on('mousemove', setFaderMoveController);

        $jukeBox.on('mouseleave mouseup', detachFaderMoveController);
    }

    function setFaderMoveController(event) {

        var faderPosX = getCursorPos(event);
        var barWidth = getTrackBarWidth();
        if (faderPosX < 0) {
            faderPosX = 0;
        }
        if (barWidth < faderPosX) {
            faderPosX = barWidth;
        }
        
        // view >> fader, progress-bar
        changeStyle($('#fader'), 'left', faderPosX);
        changeStyle($('#progress-bar'), 'width', faderPosX);

        // view >> playback time
        var playbackTime = convertLengthToTime(faderPosX);
        var htmlOfTime = convertPlaybackTime(playbackTime);
        displayPlaybackTime($('#playback-time'), htmlOfTime);

    }

    function detachFaderMoveController() {
        // prevent events from being called multiple times
        var $jukeBox = $('#juke-box');
        $jukeBox.off('mousemove', setFaderMoveController);
        $jukeBox.off('mouseleave mouseup');

        // if cursor outside container
        var isCursorInsideContainer = checkCursor(event);
        if (!isCursorInsideContainer) {
            faderMoveByClick(event);
        }
    }

    function setVolumeFaderDrag(event) {
        var $volumeContainer = $('#volume-container');
        $volumeContainer.on('mousemove', setVolumeController);

        $volumeContainer.on('mousemove mouseup', detachVolumeController);
    }

    function setVolumeController(event) {
        var faderPosY = getCursorPos;
    }

    function detachVolumeController() {

    }

    function checkCursor(event) {
        // absolute positions of cursor
        var posX = event.pageX;
        var posY = event.pageY;

        /* 
        container info:calc values of width height top left,
        judge whether cursor is outside or inside
        */
        var $target = $('#track-bar-container');
        var targetTop = $target.offset().top;
        var targetLeft = $target.offset().left;
        var targetWidth = trackBarWidth;
        var targetHeight = $target.outerHeight();

        if (
            (targetLeft <= posX) && 
            (posX <= (targetLeft + targetWidth)) &&
            (targetTop <= posY) &&
            (posY <= (targetTop + targetHeight))
        )

        {
            return true;
        }
        else {
            return false;
        }
    }

    // get volume from scale input
    function getVolume(event) {
        console.log(event);
        console.log(event.offsetX);
        var volume = event.offsetX/100;
        return volume;
    }

    function changeVolume(aVolume) {
        console.log(gainNode);
        gainNode.gain.value = aVolume;
    }

    function setTrackDuration() {
        var html = convertPlaybackTime(trackDuration);
        displayPlaybackTime($('#song-duration'), html);
    }

    // controll stream methods
    function setStreamController() {
        // get boolean
        var streamingStatus = getStreamingStatus();

        if (streamingStatus) {
            setPause();
        } else {
            setStream();
        }
    }

    function setPause() {
        pause();
        pausedTimestamp = getCurrentTime();
        setStreamingState(false);
        setInitialPauseState(false);
        clearInterval(progressTimer);

        // view >> play-btn
        swapBtn();
    }

    function setStream() {

        var pausedStatus = getPausedStatus();

        // if never paused
        if (pausedStatus) {
            initialTimestamp = getCurrentTime();

            now = initialTimestamp;
            // if user changed playbacktime..
            if (isplaybackTimeChanged) {
                faderPosition = getFaderPosition();
            }
        // if not, calculate the stop time & create audio src again
        } else {
            var clickedTime = getCurrentTime();
            now = clickedTime;
            pausedDuration += ( clickedTime - pausedTimestamp );
            disconnectAudio();
            setAudio();
            connectGain();
        }

        var playbackTime = calcPlaybackTime(faderPosition);
        stream(playbackTime);

        // progress bar interval
        startInterval(playbackTime);

        setStreamingState(true);

        // view >> play-btn
        swapBtn();
    }

    // play
    function stream(aPlaybackTime) {
        sound.start(0, aPlaybackTime);
    }

    // pause
    function pause() {
        sound.stop(0);
    }


    /////////////---------------------------------------------------------
    /// VIEW
    ///////////-----------------------------------------------------------


    // view Nav
    function swapGenreContainerView(aValue) {
        var classes = ['visible', 'hidden'];
        if (aValue === 'hidden') {
            classes.reverse();
        }

        $('#genre-container').addClass(classes[0]);
        $('#genre-container').removeClass(classes[1]);
    }

    function displayTrackPicker(aNumber, aSongData, aIndex) {
        console.log(aIndex);
        console.log(aNumber);

        var length = aSongData.length;

        // if index is 0, hide backward button
        if (aIndex === 0) {
            hideElement($('#left-arrow'));
        } else {
            displayArrow($('#left-arrow'));
        }

        if ((aNumber + aIndex) === length) {
            hideElement($('#right-arrow'));
        } else {
            displayArrow($('#right-arrow'));
        }
        var $trackPicker = $('#track-picker');
        $trackPicker.css({
            display: 'block',
        });
        var html = '';
        var elm = '<li></li>';


        for (var i = aIndex; i < (aIndex + aNumber); i++) {
            //test
            var imgElm = $('<img>');
            imgElm.attr('src', aSongData[i].artwork);

            var url = aSongData[i].artwork;
            var id = aSongData[i].id;
            var title = aSongData[i].title;
            var duration = aSongData[i].duration;
            var artistName = aSongData[i].artistName;
          
            html += '<li><figure><img src="' + url + '" id="' + id +
             '"><figcaption><span class="track-title">' + title + '</span><span class="track-duration">' + duration + 
             '</span><span class="artist-name">' + artistName + '</span></figcaption></figure></li>';
        }

        // reset ul position
        var pickerUl = $trackPicker.find('ul');
        pickerUl
        .css({
            left: 0
        });

        // fadeIn img after loading finished
        $(html)
        .appendTo(pickerUl)
        .find('img')
        .css({opacity: 0})
        .load(function() {
            $(this)
            .animate({opacity: 1}, 400);
        });

    }

    function hideElement(aDom) {
        aDom.css({
            display: 'none'
        });
    }

    function displayArrow(aDom) {
        aDom.css({
            display: 'block'
        });
    }

    function testLoad(aElm) {
        var deferred = $.Deferred();
        aElm.error(function() {

        });
    }

    function showAlert() {
        var msg = $('<div></div>');
        msg.html('Not streamable. Try another song.');
        msg.addClass('alert');
        msg.appendTo('body')
        .hide()
        .fadeIn(400)
        .fadeOut(700, function() {
            $(this).remove();
        });
    }

    function slidePicker(aDirection, isLeftZero) {
        var deferred = $.Deferred();

        var windowSiz = $(window).width();
        var scrollValue = (aDirection === 'backward') ? windowSiz : -windowSiz;

        var currentLeftPosition = getPickerPositionX();
        if (isLeftZero) {
            currentLeftPosition = 0;
            scrollValue = 0;
        }
        $('#track-picker>ul').animate({
            left: (currentLeftPosition + scrollValue) + 'px'
            //transform: translateX(scrollValue + 'px')
        }, 300, function() {
            return deferred.resolve(aDirection);
        });

        return deferred.promise();
    }

    function changePickerPositionX(aDirection) {
        var windowSiz = $(window).width();
        var posX = (aDirection === 'forward') ? windowSiz : -windowSiz;
        $('#track-picker>ul').css({
            left: posX + 'px'
        });

    }

    // hide picker
    function resetTrackPickerView() {
        var $trackPicker = $('#track-picker');
        $trackPicker.animate({
            opacity: 0
        }, 300, function() {
            $trackPicker.css({
                display: 'none',
                opacity: 1
            });
        });

        makeListContentsEmpty();
    }

    function makeListContentsEmpty() {
        $('#track-picker').find('ul').empty();
    }

    function changeMainVisual(aUrl, aTrackTitle, aArtistName) {
        $('#main-visual').css({
            background: aUrl + ' center center no-repeat',
            backgroundSize: 'cover',
            width: '50vh',
            height: '50vh'
        });

        $('#juke-box>ul>li:first-child').html(aTrackTitle);

        $('#juke-box>ul>li:last-child').html(aArtistName);
    }

    function convertAttrToCss(aUrl) {
        return 'url(' + aUrl + ')';
    }

    function changeTitieOnProgressBar() {

    }
    // loading finishes
    function removeMask() {
        $('.load-mask').fadeOut(500, function() {
            $(this).remove();
        });
    }

    // loading
    function addMask() {
        var mask = $('<div></div>');
        mask.addClass('load-mask');
        $('body').append(mask).hide().fadeIn(300);
    }

    // close nav by clicking on close-button
    function closeNav() {
        swapGenreContainerView('hidden');
    }

    /*
        view of progress bar & music player
    */
    function startInterval(aPlaybackTime) {
        var $fader = $('#fader');
        var $progressBar = $('#progress-bar');

        var $playback = $('#playback-time');

        progressTimer = setInterval(function() {

            var length = convertTimeToLength(aPlaybackTime);
            
            // view >> progress bar
            changeStyle($fader, 'left', length);
            changeStyle($progressBar, 'width', length);

            // view >> playback time
            var playbackTimeHtml = convertPlaybackTime(aPlaybackTime);
            displayPlaybackTime($playback, playbackTimeHtml);

            // interval time
            aPlaybackTime += 0.03;

            if (aPlaybackTime >= trackDuration) {
                resetInterval();
            }
        }, 30);
    }

    function resetInterval() {
        clearInterval(progressTimer);
        resetData();
        setStreamingState(false);
        swapBtn();
        // possible to start the song again
        disconnectAudio();
        setAudio();
        connectGain();
        // start at 0
        setModifiedPlaybackTimeStatus(false);
        resetFaderPosition();
    }

    function displayPlaybackTime(aDom, aPlaybackTimeHtml) {
        aDom.html(aPlaybackTimeHtml);
    }


    function changeStyle(aDom, aProperty, aValue) {
        aDom.css(aProperty, aValue);
    }

    function changeHtml(aDom, aValue) {
        aDom.html(aValue);
    }

    // pause or play icon
    function swapBtn() {
        var image = (isStreaming) ? 'pause' : 'play';
        $('#play-btn').css({
            background: 'url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/164143/' + image + '.png) 5px 5px no-repeat',
            backgroundSize: '30px 30px'
        });
    }

    /////////////---------------------------------------------------------
    /// MODEL
    ///////////-----------------------------------------------------------

    // nav
    var arrayOfSongsData = [];
    var visibleTrackFigure;
    var currentIndexOfTrackOnTheLeft = 0;
    var totalSongsFigure = 0;

    // main visual manager
    var lastMainVisualSrc;
    var lastTitle = '';
    var lastArtistName = '';

    function getArrSongsLength() {
        return arrayOfSongsData.length();
    }
    function changeUserState() {
        isAfterFirstTrack = true;
    }

    function getElementId(aTarget) {
        return aTarget.attr('id');
    }

    function getElementText(aTarget) {
        return aTarget.text();
    }

    function getDataOfSelectedGenre(aGenre) {
        var deferred = $.Deferred();
        SC.get('/tracks', {genres: aGenre}, function(tracks) {
            console.log(tracks);

            // return
            return deferred.resolve(tracks);
        });
        return deferred.promise();
    }

    function getDataOfQuery(aQuery) {
        var deferred = $.Deferred();
        SC.get('/tracks', {q: aQuery}, function(tracks) {
            console.log(tracks);

            // return
            return deferred.resolve(tracks);
        });
        return deferred.promise();
    }

    // make trackdata object
    function extractInfo(aTrackData) {
        var trackDataObj = {};
        trackDataObj.artwork = aTrackData.artwork_url;
        trackDataObj.title = aTrackData.title;
        trackDataObj.artistName = aTrackData.user.username;
        trackDataObj.id = aTrackData.id;
        trackDataObj.streamable = aTrackData.streamable;
        var convertedTrackDuration = convertMillisecondsToSeconds(aTrackData.duration);
        trackDataObj.duration = convertPlaybackTime(convertedTrackDuration);

        return trackDataObj;
    }

    // store each track data to an array
    function addInfo(aTrackData) {
        if (aTrackData.artwork !== null) {
            arrayOfSongsData.push(aTrackData);
        }
    }

    function incrementTotalSongsFigure() {
        totalSongsFigure++;
    }

    // for animation
    function getPickerPositionX() {
        return $('#track-picker>ul').offset().left;
    }

    // for function underneath
    function getWindowSize() {
        return $(window).width();
    }

    // calc how many artworks are displayed
    function getDisplayingTracksFigure(aWindowSize) {
        var eachElementWidth = 190;
        var figure = Math.floor((aWindowSize - 100) / eachElementWidth);
        return figure;
    }

    function setVisibleTrackFigure(aVisibleFigure) {
        visibleTrackFigure = aVisibleFigure;
    }

    function getVisibleTrackFigure() {
        return visibleTrackFigure;
    }

    // milliseconds to seconds
    function convertMillisecondsToSeconds(aMilliseconds) {
        var durationInSeconds = Math.floor(aMilliseconds / 1000);
        return durationInSeconds;
    }

    function getModifiedPickerWidth(aFigure) {
        return 190 * aFigure;
    }

    // default:100x100px >> change path to get a bigger one:300x300px
    function replaceArtworkUrl(aUrl) {
        return aUrl.replace('large.jpg', 't300x300.jpg');
    }

    function getStreamUrl(aId) {
        return 'https://api.soundcloud.com/tracks/' + aId + '/stream?client_id=' + CLIENT_ID;
    }

    function getElementSrc(aTarget) {
        return aTarget.attr('src');
    }

    function getElementBackground(aTarget) {
        var bg = aTarget.css('backgroundImage');
        bg.replace(/.*\s?url\([\'\"]?/, '').replace(/[\'\"]?\).*/, '');
        console.log(bg);
        return bg;
    }

    function setMainVisualImgSrc(aLastMainVisualSrc) {
        lastMainVisualSrc = aLastMainVisualSrc;
    }

    function getMainVisualImgSrc() {
        return lastMainVisualSrc;
    }

    function getMainVisualUrl(aSrc) {
        return aSrc.replace('t300x300.jpg', 't500x500.jpg');
    }

    // initially 0 | the value fluctuates when slider animation is triggered
    function getCurrentIndexOfTrackOnTheLeft() {
        return currentIndexOfTrackOnTheLeft;
    }

    function setCurrentIndexOfTrackOnTheLeft(aValue) {
        currentIndexOfTrackOnTheLeft = aValue;
    }

    function calcCurrentIndexOfTrackOnTheLeft(aCurrentIndex, aSumOnScreen, aDirection) {
        var value = (aDirection === 'forward') ? aSumOnScreen : (-1 * aSumOnScreen);
        return aCurrentIndex + value;
    }

    function resetTrackData() {
        // fastest solution
        arrayOfSongsData = [];
        currentIndexOfTrackOnTheLeft = 0;
        totalSongsFigure = 0;
    }

    function calcDisplayableNumber(aIndex) {
        return totalSongsFigure - aIndex;
    }

    function setLastTitle(aLastTitle) {
        lastTitle = aLastTitle;
    }

    function getLastTitle() {
        return lastTitle;
    }

    function setLastArtistName(aLastArtistName) {
        lastArtistName = aLastArtistName;
    }

    function getLastArtistName() {
        return lastArtistName;
    }

    //-----------------------------------------------------------------------
    // data model member variables
    //-----------------------------------------------------------------------

    // boolean
    var isStreaming = false;
    var isNeverPaused = true;
    var isplaybackTimeChanged = false;

    // only used for the firstclick
    var isAfterFirstTrack = false;

    // numerical
    var faderPosition = 0;


    function getTrackBarWidth() {
        return $('#track-bar').width();
    }

    function getLeftPositionOfContainer() {
        return $('#track-bar-container').offset().left;
    }


    function getAudio(aUrl) {
        var deferred = $.Deferred();
        // ajax is not capable of "array buffer"
        var xhr = new XMLHttpRequest();
        xhr.open('GET', aUrl, true);
        xhr.responseType = 'arraybuffer';
        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4 && xhr.status === 200 && (xhr.status !== 404)) {
                audioCtx.decodeAudioData(xhr.response, function(buffer) {
                    buf = buffer;
                    return deferred.resolve(true);
                });
            } 
        };
        xhr.onerror = function() {
            return deferred.resolve(false);
        };
        xhr.send();
        return deferred.promise();
    }

    function setAudio() {
        sound = audioCtx.createBufferSource();
        sound.buffer = buf;
    }

    function setAudioDuration() {
        trackDuration = sound.buffer.duration;
    }

    function setGain() {
        gainNode = audioCtx.createGain();
    }

    function connectGain() {
        sound.connect(gainNode);
    }

    function connectAudio() {
        gainNode.connect(audioCtx.destination);
    }

    function disconnectAudio() {
        sound.disconnect(0);
    }

    function getCurrentTime() {
        return audioCtx.currentTime;
    }

    function getFaderPosition() {
        // get relative position to #track-bar
        return $('#fader').position().left;
    }

    // calc playback time with initial fader position and progress time
    function calcPlaybackTime(aFaderPosition) {
        return (aFaderPosition / trackBarWidth) * trackDuration + (now - initialTimestamp - pausedDuration); 
    }

    function getCursorPos(event) {
        var cursorX = event.pageX;
        return cursorX - leftPositionOfContainer;
    }


    function resetData() {
        setInitialPauseState(true);
        pausedDuration = 0;
    }

    function convertPlaybackTime(aPlaybackTime) {
        // duration | ex) playbackTime = 360.3452 |
        var minutes = Math.floor(aPlaybackTime / 60);
        var seconds = Math.floor(aPlaybackTime % 60);

        // add 0 for layout
        seconds = (seconds < 10) ? '0' + seconds : seconds;

        return minutes + ':' + seconds;
    }

    function convertLengthToTime(aLength) {
        return trackDuration * (aLength / trackBarWidth);
    }

    function convertTimeToLength(aPlaybackTime) {
        return aPlaybackTime / trackDuration * trackBarWidth;
    }

    function getStreamingStatus() {
        return isStreaming;
    }

    function getPausedStatus() {
        return isNeverPaused;
    }

    function resetFaderPosition() {
        faderPosition = 0;
    }

    function setStreamingState(aCondition) {
        isStreaming = aCondition;
    }

    function setInitialPauseState(aCondition) {
        isNeverPaused = aCondition;
    }

    function setModifiedPlaybackTimeStatus(aCondition) {
        isplaybackTimeChanged = aCondition;
    }

    function resetAudioData() {
        resetData();
        resetFaderPosition();
        clearInterval(progressTimer);
        disconnectAudio();
        setStreamingState(false);
        setModifiedPlaybackTimeStatus(false);
    }


})(window, document, window.jQuery);
            
          
!
999px
Close

Asset uploading is a PRO feature.

As a PRO member, you can drag-and-drop upload files here to use as resources. Images, Libraries, JSON data... anything you want. You can even edit them anytime, like any other code on CodePen.

Go PRO

Loading ..................

Console