LOADING...

Preview

Pen ID
Unlock Campus Themeforest adv

 

Code
Select an audio file...
CSS
/* Default all same color */
* {
  box-sizing: border-box;
}

html, body {
  height: 100%;
}

body {
  background: #1e1e1e;
  font-family: 'Helvatica', sans-serif;
  color: #FFF;
  position: relative;
  perspective: 1000px;
  perspective-origin: 50% 50%;
}

.hide {
  display: none;
}

.prism {
  position: absolute;
  transform-style: preserve-3d;
  animation: rotate 8s linear infinite;
  display: none;
}

.side {
  width: 100%;
  height: 100%;
  border-top: 3px solid #4DA16F;
  border-bottom: 3px solid #4DA16F;
  border-color: currentColor;
  position: absolute;
}

.rectangle {
  border: 3px solid #4DA16F;
  border-color: currentColor;
}

.solid .rectangle {
  background: currentColor;
}

@keyframes rotate {
  from {
    transform: rotateY(0);
  }
  to {
    transform: rotateY(-360deg);
  }
}
.musicControls, i {
  position: absolute;
  border-radius: 5px;
  border: 1px solid rgba(255, 255, 255, 0.3);
  padding: 10px;
}

.musicControls {
  top: 20px;
  left: 20px;
}

i {
  left: 50%;
  top: 50%;
  transform: translateY(-50%) translateX(-50%);
}

body.loaded #loading {
  display: none;
}
body.loaded .prism {
  display: block;
}
JS
var maxSideNum = 24,
    maxRectangleNum = 24;

// Dat.gui setup
var Options = function() {
    this.height = 400;
    this.radius = 185;
    this.sideCount = 12;
    
    this.rectangleCount = 12;
    this.rectangleWidth = 80;
    this.vertMargin = 10;
    this.borderWidth = 3;
    
    this.color = 200;
    this.solidBG = false;
    this.rainbowMode = false;
    this.animateThroughSpectrum = false;
};


window.onload = function() {
    // dat.gui setup
    var myOptions = new Options(),
        gui = new dat.GUI(),
        f1 = gui.addFolder('Prism Controls'),
        f2 = gui.addFolder('Rectangle Controls'),
        f3 = gui.addFolder('Color Controls'),
        
        mySideCount = f1.add(myOptions, 'sideCount', 3, maxSideNum).step(1),
        myRadius = f1.add(myOptions, 'radius', 30, 600).step(15),
        myHeight = f1.add(myOptions, 'height', 50, 750).step(50),
        
        myRectangleCount = f2.add(myOptions, 'rectangleCount', 3, maxRectangleNum).step(1),
        myRectangleWidth = f2.add(myOptions, 'rectangleWidth', 1, 100).step(5),
        myVertMargin = f2.add(myOptions, 'vertMargin', 0, 15).step(1),
        myBorderWidth = f2.add(myOptions, 'borderWidth', 0, 15).step(1),
        
        myColor = f3.add(myOptions, 'color', 0, 360).step(1),
        mySolidBG = f3.add(myOptions, 'solidBG'),
        myRainbow = f3.add(myOptions, 'rainbowMode'),
        myAnimateThroughSpectrum = f3.add(myOptions, 'animateThroughSpectrum');
    
    f2.open();
    
    var audio,
        analyser,
        audioctx,
        sourceNode,
        stream;

    var audioInput = document.querySelector('.audiofile'),
        listenButton = document.querySelector(".listenButton"),
        playPauseButton = document.querySelector(".playPauseButton");

    var c = 0, // Used to change color over time
        paused = true;
  
    /*var myMusic = [
        "https://zachsaucier.com/music/Initiation.mp3",
        "https://zachsaucier.com/music/High%20Tide.mp3",
        "https://zachsaucier.com/music/Dolphin%20Style.mp3",
        "https://zachsaucier.com/music/King.mp3"
    ];*/
    
    var prism = document.querySelector(".prism"),
        sides = document.querySelectorAll(".side"),
        rectangleArray = [maxSideNum],
        lastTime = Date.now(),
        timeGap = 50;
    
    function rectangleSetup() {
        for(var i = 0; i < maxSideNum; i++) {
            rectangleArray[i] = sides[i].querySelectorAll(".rectangle");
        }
    }
    rectangleSetup();
    
    
    
    // dat.gui listeners
    
    // f1 listeners
    function sideCountChange(newCount) {
        [].forEach.call(sides, function(elem, i) {
            if(i < myOptions.sideCount) {
                // The circle is inscribed inside of the prism, so we can use this formula to calculate the side length
                var sideLength = 2 * (myOptions.radius) * Math.tan(Math.PI / newCount);
                prism.style.width = sideLength + "px";
                prism.style.left = "calc(50% - " + sideLength / 2 + "px)";
                
                sides[i].style.transform = "rotateY(" + i * (360 / newCount) + "deg) translateZ(" + myOptions.radius + "px) rotateX(180deg)";
                sides[i].classList.remove("hide");
            } else {
                sides[i].classList.add("hide");
            }
        });
    }
    mySideCount.onFinishChange(sideCountChange);
    sideCountChange(myOptions.sideCount);
    
    function radiusChange(newRadius) {
        sideCountChange(myOptions.sideCount);
    }
    myRadius.onFinishChange(radiusChange);
    radiusChange(myOptions.radius);
    
    function heightChange(newHeight) {
        prism.style.height = newHeight + "px";
        prism.style.top = "calc(50% - " + newHeight / 2 + "px)"
        rectangleCountChange(myOptions.rectangleCount);
    }
    myHeight.onFinishChange(heightChange);
    heightChange(myOptions.height);
    
    // f2 listeners 
    function rectangleCountChange(newCount) {
        [].forEach.call(rectangleArray, function(side, i) {
            [].forEach.call(side, function(rect, i) {
                if(i < myOptions.rectangleCount) {
                    rect.style.height = (myOptions.height - myOptions.vertMargin) / newCount - myOptions.vertMargin + "px";
                    rect.classList.remove("hide");
                } else {
                    rect.classList.add("hide");
                }
            });
        });
    }
    myRectangleCount.onFinishChange(rectangleCountChange);
    rectangleCountChange(myOptions.rectangleCount);
    
    function rectangleWidthChange(newWidth) {
        [].forEach.call(rectangleArray, function(side, i) {
            [].forEach.call(side, function(rect, i) {
                rect.style.width = newWidth + "%";
            });
        });
    }
    myRectangleWidth.onFinishChange(rectangleWidthChange);
    rectangleWidthChange(myOptions.rectangleWidth);
    
    function vertMarginChange(newMargin) {
        [].forEach.call(rectangleArray, function(side, i) {
            [].forEach.call(side, function(rect, i) {
                rect.style.margin = newMargin + "px auto";
            });
        });
        rectangleCountChange(myOptions.rectangleCount);
    }
    myVertMargin.onFinishChange(vertMarginChange);
    vertMarginChange(myOptions.vertMargin);
    
    function borderWidthChange(newWidth) {
        [].forEach.call(rectangleArray, function(side, i) {
            [].forEach.call(side, function(rect, i) {
                rect.style.borderWidth = newWidth + "px";
            });
        });
    }
    myBorderWidth.onFinishChange(borderWidthChange);
    borderWidthChange(myOptions.borderWidthChange);
    
    // f3 listeners
    function colorChange(value) {
        if(!myOptions.rainbowMode)
            [].forEach.call(sides, function(elem, i) {
                sides[i].style.color = "hsl(" + value + ", 55%, " + (20 + (i / myOptions.sideCount) * 40) + "%)";
            });
    }
    myColor.onFinishChange(colorChange);
    colorChange(myOptions.color);
    
    mySolidBG.onFinishChange(function(value) {
        if(value === true)
            prism.classList.add("solid");
        else
            prism.classList.remove("solid");
    });
    
    function goRainbowMode(value) {
        [].forEach.call(sides, function(elem, i) {
            if(value === true)
                sides[i].style.color = "hsl(" + 360 * (i / myOptions.sideCount) + ", 80%, 55%)";
            else
                colorChange(myOptions.color);
        });
    }
    myRainbow.onFinishChange(goRainbowMode);
    
    function checkAnimateThroughSpectrum() {
        if(myOptions.animateThroughSpectrum)
            [].forEach.call(sides, function(elem, i) {
                sides[i].style.color = "hsl(" + c + ", 80%, " + (20 + (i / myOptions.sideCount) * 40) + "%)";
            });
        else if(myOptions.rainbowMode)
            goRainbowMode(true);
        else
            colorChange(myOptions.color);
    }
    
    
    
    // The music player listeners
    audioInput.addEventListener('change', function(event) {
        if(event.target.files[0]) {
            // No error checking of file here, could be added
            stream = URL.createObjectURL(event.target.files[0]);
            
            loadSong(stream);
        }
    }, false);
    
    if(listenButton)
        listenButton.addEventListener('click', chooseOneOfMine, false);
    
    playPauseButton.addEventListener('click', togglePlayPause, false);
    
    
    // The music functions
    function setup() {
        // Stop the previous song if there is one
        if(audio)
            togglePlayPause();
        
        audio = new Audio();
        audioctx = new AudioContext();
        analyser = audioctx.createAnalyser();
        analyser.smoothingTimeConstant = 0.75;
        analyser.fftSize = 512;
        
        audio.addEventListener('ended', songEnded, false);
        
        sourceNode = audioctx.createMediaElementSource(audio);
        sourceNode.connect(analyser);
        sourceNode.connect(audioctx.destination);
    }
    
    function loadSong(stream) {
        setup();

        audio.src = stream;

        togglePlayPause();
        document.body.classList.add('loaded');
        update();
    }
    
    function songEnded() {
        document.body.classList.remove('loaded');
        togglePlayPause();
    }
    
    function togglePlayPause() {
        if(paused) {
            document.body.classList.add('loaded');
            audio.play();
            playPauseButton.innerText = "▮▮";
        } else if(!audio.paused && !audio.ended) {
            audio.pause();
            playPauseButton.innerText = "▶";
        }
        
        paused = !paused;
    }
    
    function chooseOneOfMine() {
        var num = Math.round(Math.random() * (myMusic.length - 1)) + 1;
        loadSong(myMusic[num]);
    }

    
    
    // The drawing functions 
    function drawSide(freqSequence, freqPercent) {   
        // Get the number of rectangles based on the freqValue
        drawRectangles(freqSequence, Math.floor(freqPercent * myOptions.rectangleCount / 100))
    }
    
    function drawRectangles(sideNum, numRectanglesShowing) {
        for(var i = 0; i < myOptions.rectangleCount; i++) {
            if(i <= numRectanglesShowing) {
                rectangleArray[sideNum][i].classList.remove("hide");
            } else {
                rectangleArray[sideNum][i].classList.add("hide");
            }
        }
    }

    var sectionsAveraged = [maxSideNum],
        countSinceLast = [maxSideNum];
    
    function update() {
        var currTime = Date.now();
        
        var freqArray = new Uint8Array(analyser.frequencyBinCount);
        analyser.getByteTimeDomainData(freqArray);

        // Find the average of the values near to each other (grouping)
        var average = 0,
            count = 0,
            numPerSection = 256 / (myOptions.sideCount + 1),
            nextSection = numPerSection;

        for (var i = 0; i < freqArray.length; i++) {
            var v = freqArray[i];
            average += Math.abs(128 - v); // 128 is essentially 0
            count++;
            
            if(i > nextSection) {
                var currentSection = Math.floor(i / numPerSection - 1);
                
                sectionsAveraged[currentSection] += average / count;
                countSinceLast[currentSection]++;
                
                average = 0;
                count = 0;
                nextSection += numPerSection;
            }
        }
        
        // Find the average of the values since the last time checked per section (smoothing)
        if(currTime - lastTime > timeGap) {  
            for (var i = 0; i < myOptions.sideCount; i++) {
                drawSide(i, (sectionsAveraged[i] / countSinceLast[i]), c);
                sectionsAveraged[i] = 0;
                countSinceLast[i] = 0;
            }
            
            lastTime = currTime;
        } 
        
        checkAnimateThroughSpectrum();
            
        c += 0.5;
        requestAnimationFrame(update);
    }
};
Host Instantly Drag and Drop Website Builder

 

Description

Self Code a music player for users by laivanduc.com
Term
Mon, 11/27/2017 - 21:36

Related Codes

Pen ID
Pen ID
Pen ID