UNPKG

amelie

Version:

HTML5 audio visualiser experiment using D3 with a curious Amelie theme.

1 lines 3.69 kB
!function(t,e,i){"use strict";var n=e.createClass({componentDidMount:function(){this.getAudioElement().addEventListener("canplay",this.configureAudioContext)},getInitialState:function(){return{analyser:null}},getAudioElement:function(){return this.getDOMNode().querySelector("audio")},configureAudioContext:function(){var t=AudioContext||mozAudioContext||webkitAudioContext||oAudioContext||msAudioContext;if(!t)throw"Amelie: AudioContext API unavailable in current browser. Please try another!";var e=new t,i=e.createAnalyser(),n=e.createMediaElementSource(this.getAudioElement());n.connect(i),i.connect(e.destination),i.fftSize=128,this.setState({analyser:i})},render:function(){return React.DOM("section",{className:"amelie"},[React.DOM("audio",{controls:"controls",autoPlay:"autoplay",src:this.props.audio}),r({analyser:this.state.analyser})])}}),r=e.createClass({componentWillReceiveProps:function(t){t.analyser&&this.analyseAudioStream(t.analyser)},getInitialState:function(){return{cursor:{x:0,y:0},frequencyData:[]}},analyseAudioStream:function o(t){(requestAnimationFrame||mozRequestAnimationFrame||webkitRequestAnimationFrame)(function(){o.call(this,t)}.bind(this));var e=new Uint8Array(t.frequencyBinCount);t.getByteFrequencyData(e),this.setState({frequencyData:e,fftSize:t.fftSize})},setCursorPosition:function(t){this.setState({cursor:{x:t.clientX,y:t.clientY}})},render:function(){return React.DOM("section",{className:"visualiser",onMouseMove:this.setCursorPosition},[s({frequencyData:this.state.frequencyData,cursor:this.state.cursor,fftSize:this.state.fftSize})])}}),s=e.createClass({componentDidMount:function(){var t=i.select(this.getDOMNode()).append("svg").attr("width",this.state.size[0]).attr("height",this.state.size[1]).append("g");this.getDOMNode().style.width=this.state.size[0]+"px",this.getDOMNode().style.height=this.state.size[1]+"px";var e=function(){var t=[];return function(e){if(!t[e]){var i=Math.round(255*Math.random());t[e]="rgb("+i+", "+i+", "+i+")"}return t[e]}};this.setState({d3:t,colours:new e})},componentWillReceiveProps:function(t){0===this.state.circles.length&&t.fftSize&&this.setState({circles:this.createCircles(t.fftSize)})},createCircles:function(t){for(var e=[],i=0;t>i;i++)e.push(this.state.d3.append("circle"));return e},getInitialState:function(){return{circles:[],colours:function(){},size:[400,400]}},renderCircles:function(t){if(0!==this.state.circles.length){for(var e=this.state.colours,i=this.computeCxCy(),n=0,r=t.length;r>n;n++)this.state.circles[n].attr("cx",i.cx).attr("cy",i.cy).attr("r",t[n]/2.5).style("fill",e(n));this.renderSplodges(t)}},computeCxCy:function(){return{cx:this.state.size[0]-110,cy:this.state.size[1]-110}},renderSplodges:function(t){var e=this.computeCxCy(),i=t.length,n=i-i/4,r=Array.prototype.slice.call(t).splice(i-n),s=r.reduce(function(t,e){return t+e},0);if(0!==s){e.cx+=190*Math.random()-95,e.cy+=190*Math.random()-95;var a=this.state.d3.append("circle").attr("cx",e.cx).attr("cy",e.cy).attr("r",s/40).style("fill",this.getRandomColour());a.transition().attr("r",0).duration(500).remove()}},getRandomColour:function(){var t=["267831","B1B541","FFCD36","D60404","1F0404"];return"#"+t[Math.floor(Math.random()*t.length)]},positionDOMElement:function(t){this.getDOMNode().style.left=t.x-this.state.size[0]/2+"px",this.getDOMNode().style.top=t.y-this.state.size[1]/2+"px"},render:function(){return this.props.frequencyData&&(this.renderCircles(this.props.frequencyData),this.state.d3&&this.positionDOMElement(this.props.cursor)),React.DOM("div",{className:"canvas-container"})}}),a=t.querySelector("amelie");e.render(n({audio:a.getAttribute("data-audio")}),a)}(window.document,window.React,window.d3);