audiolet实现雷达式音调点添加编写音乐效果代码
代码语言:html
所属分类:多媒体
代码描述:audiolet实现雷达式音调点添加编写音乐效果代码,点击选择不同的音调在雷达中添加,就会有随着雷达波播放声音。
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <style> /********************************************* * GLOBAL *********************************************/ body, html { overflow: hidden; font-family: Helvetica, Arial, sans-serif; color: #fff; font-size: 11px; background: #111; height: 100%; } .main-container { background: #111; } * { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } /********************************************* * HEADER *********************************************/ header { position: relative; width: 100%; height: 36px; margin: 0; padding: 0 8px 8px 8px; overflow: hidden; z-index: 5; background: #1e2121; color: #eee; -webkit-transition: height .22s ease-out; -moz-transition: height .22s ease-out; -o-transition: height .22s ease-out; transition: height .22s ease-out; } header.open { height: 165px; } header h1 { font-family: Molengo, Helvetica, Arial, sans-serif; float: left; margin-top: 1px; } header .header-instruction { float: left; margin: 12px 0 0 15px; font-size: 10px; font-style: italic; color: #999; -webkit-transition: opacity .18s linear; -moz-transition: opacity .18s linear; -o-transition: opacity .18s linear; transition: opacity .18s linear; } header.open .header-instruction { opacity: 0; } header div.extra { margin: 45px 0 0 20px; clear: both; -webkit-transition: opacity .18s linear; -moz-transition: opacity .18s linear; -o-transition: opacity .18s linear; transition: opacity .18s linear; } header div.extra h3 { margin-bottom: 10px; } header a { color: #19d75a; text-decoration: underline; -webkit-transition: all .1s ease-out; -moz-transition: all .1s ease-out; -o-transition: all .1s ease-out; transition: all .1s ease-in; } header a:hover { color: #67f38f; } header section { height: 120px; padding: 0 25px; float: left; border-left: 1px #333 solid; } header p { margin-bottom: 5px; font-size: 12px; letter-spacing: 0.05em; } #about { padding-left: 0; border: none; } #about p.credits { margin: 15px 0 2px 0; font-style: italic; color: #666; font-size: 11px; line-height: 1.4em; } #share iframe, #share div { display: inline-block; } #retweet-button { margin-right: 6px; } .no-canvas { color: #999999; font-size: 24px; text-align: center; margin-top: 150px; } /********************************************* * EXPERIMENT STYLES *********************************************/ #wrapper { position: absolute; font-size: 12px; color: #f4f4f4; cursor: default; } #wrapper canvas { float: left; background: #000; background: url('../images/background.png') no-repeat; border: 1px solid #222; border-radius: 2px; box-shadow: 0px 0px 20px rgba(0,0,0,0.5); } #wrapper .instructions { display: block; position: absolute; left: 0px; top: -22px; opacity: 0; -webkit-transition: all .12s ease; -moz-transition: all .12s ease; -ms-transition: all .12s ease; -o-transition: all .12s ease; transition: all .12s ease; } #wrapper.empty .instructions { opacity: 1; } #wrapper .sidebar { position: absolute; right: 0; top: 0; width: 100px; color: #fff; opacity: 1; font-size: 12px; -webkit-transition: all .12s ease; -moz-transition: all .12s ease; -ms-transition: all .12s ease; -o-transition: all .12s ease; transition: all .12s ease; } #wrapper.empty .sidebar { opacity: 0; visibility: hidden; } #wrapper .sidebar button { display: inline-block; width: 48%; padding: 6px; margin-bottom: 14px; color: #bbb; background: rgba( 255, 255, 255, 0.05 ); opacity: 1; border: none; border-radius: 2px; cursor: pointer; font-size: 12px; text-align: center; -webkit-transition: all .12s ease; -moz-transition: all .12s ease; -ms-transition: all .12s ease; -o-transition: all .12s ease; transition: all .12s ease; } #wrapper .sidebar button:hover { opacity: 1; color: #fff; background: rgba( 255, 255, 255, 0.2 ); } /* SEQUENCER */ #wrapper .sidebar .sequencer { padding-top: 14px; border-top: 1px dotted rgba( 255, 255, 255, 0.08 ); } #wrapper .sidebar .sequencer li { display: block; position: relative; padding: 10px 6px; margin-bottom: 4px; width: 100%; cursor: pointer; background: #222; box-shadow: 0px 0px 20px rgba(0,0,0,0.5); border-radius: 2px; -webkit-transition: all .12s ease; -moz-transition: all .12s ease; -ms-transition: all .12s ease; -o-transition: all .12s ease; transition: all .12s ease; } #wrapper .sidebar .sequencer li:hover { background: #333; } #wrapper .sidebar .sequencer li .index { opacity: 0.5; } #wrapper .sidebar .sequencer li .delete { position: absolute; right: 7px; top: 3px; font-family: Helvetica; font-size: 20px; opacity: 0.1; } #wrapper .sidebar .sequencer li:hover .delete { opacity: 0.6; } #wrapper .sidebar .sequencer li .delete:hover { opacity: 1; } #wrapper .sidebar .sequencer li .background { position: absolute; top: 0; left: 0; width: 100%; height: 100%; opacity: 0; -webkit-transition: opacity 1.5s linear; -moz-transition: opacity 1.5s linear; -ms-transition: opacity 1.5s linear; -o-transition: opacity 1.5s linear; transition: opacity 1.5s linear; } #wrapper .sidebar .sequencer li .background.instant { -webkit-transition: none; -moz-transition: none; -ms-transition: none; -o-transition: none; transition: none; } #wrapper .sidebar .sequencer li.add-key { background: #111; color: #fff; border: 1px solid rgba( 255, 255, 255, 0.05 ); } #wrapper .sidebar .sequencer li.add-key:hover { background: #222; } #wrapper .sidebar .sequencer-input { visibility: hidden; position: absolute; width: 100px; left: 0; border-radius: 2px; background: #222; } #wrapper .sidebar .sequencer-input:before { content: '\2023'; position: absolute; margin: 76px 0 0 100%; left: -4px; color: #222; font-size: 50px; } #wrapper .sidebar .sequencer-input li { padding: 10px 6px; background: #222; cursor: pointer; -webkit-transition: all .12s ease; -moz-transition: all .12s ease; -ms-transition: all .12s ease; -o-transition: all .12s ease; transition: all .12s ease; } #wrapper .sidebar .sequencer-input li:hover { background: #333; } #wrapper .sidebar .sequencer-input li+li { border-top: 1px solid #333; } </style> <link href='https://fonts.googleapis.com/css?family=Molengo' rel='stylesheet' type='text/css'> </head> <body> <div class="main-container"> <div id="wrapper" class="empty"> <canvas></canvas> <div class="sidebar"> <button class="save">Save</button> <button class="reset">Reset</button> <ul class="sequencer-input"> <li data-key="a" data-scale="min">A minor</li> <li data-key="a" data-scale="maj">A major</li> <li data-key="d" data-scale="min">D minor</li> <li data-key="d" data-scale="maj">D major</li> <li data-key="e" data-scale="min">E minor</li> <li data-key="e" data-scale="maj">E major</li> </ul> <ul class="sequencer"> <li class="add-key">Add Key</li> </ul> </div> <span class="instructions">Click on a pin to generate sound</span> </div> </div> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/audiolet.js"></script> <script> /** * */ var Capabilities = { isOnline: function() { return navigator.onLine; }, isTouchDevice: function() { return navigator.userAgent.match( /(iphone|ipad|ipod|android)/gi ); }, suportsLocalStorage: function() { return ('localStorage' in window) && window['localStorage'] !== null; } }; /** * Defines a 2D position. */ function Point( x, y ) { this.x = x || 0; this.y = y || 0; } Point.prototype.distanceTo = function( x, y ) { var dx = x-this.x; var dy = y-this.y; return Math.sqrt(dx*dx + dy*dy); }; Point.prototype.clonePosition = function() { return { x: this.x, y: this.y }; }; Point.prototype.interpolate = function( x, y, amp ) { this.x += ( x - this.x ) * amp; this.y += ( y - this.y ) * amp; }; /** * Defines of a rectangular region. */ function Region() { this.left = 999999; this.top = 999999; this.right = 0; this.bottom = 0; } Region.prototype.reset = function() { this.left = 999999; this.top = 999999; this.right = 0; this.bottom = 0; }; Region.prototype.inflate = function( x, y ) { this.left = Math.min(this.left, x); this.top = Math.min(this.top, y); this.right = Math.max(this.right, x); this.bottom = Math.max(this.bottom, y); }; Region.prototype.expand = function( x, y ) { this.left -= x; this.top -= y; this.right += x; this.bottom += y; }; Region.prototype.contains = function( x, y ) { return x > this.left && x < this.right && y > this.top && y < this.bottom; }; Region.prototype.size = function() { return ( ( this.right - this.left ) + ( this.bottom - this.top ) ) / 2; }; Region.prototype.center = function() { return new Point( this.left + (this.right - this.left) / 2, this.top + (this.bottom - this.top) / 2 ); }; Region.prototype.toRectangle = function() { return { x: this.left, y: this.top, width: this.right - this.left, height: this.bottom - this.top }; }; // shim layer with setTimeout fallback from http://paulirish.com/2011/requestanimationframe-for-smart-animating/ window.requestAnimFrame = (function(){ return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(/* function */ callback, /* DOMElement */ element){ window.setTimeout(callback, 1000 / 60); }; })(); </script> <script> /** * @author Hakim El Hattab */ var Radar = (function(){ var NODES_X = 12, NODES_Y = 12, BEAT_VELOCITY = 0.01, BEAT_FREQUENCY = 2, BEAT_LIMIT = 10, // Distance threshold between active node and beat ACTIVATION_DISTANCE = 20, // Number of neighboring nodes to push aside on impact WAVE_RADIUS = 3; // The world dimensions var world = { width: 600, height: 500, center: new Point( 300, 250 ) }; // Mouse input tracking var mouse = { // The current position x: 0, y: 0, // The position previous to the current previousX: 0, previousY: 0, // The velocity, based on the difference between // the current and next positions velocityX: 0, velocityY: 0, // Flags if the mouse is currently pressed down down: false, // When dragging the action is defined by the first nodes // reaction (activate/deactivate) action: null, // A list of node ID's for which action should not be // taken until the next time the mouse is pressed down exclude: [] }; var id = 0, container, canvas, context, sidebar, sequencer, sequencerInput, sequencerInputElements, sequencerAddButton, saveButton, resetButton, query = {}, currentBeat = null, defaultBeats = [ [ 'a', 'min' ], [ 'a', 'min' ] ], activateNodeDistance = 0, // Seed is used to generate the note field so that random // one persons's grid can be saved & replicated // Some patterns to try: // ?8643+d+maj+8+30+43+55+66+69 // ?8643+a+min+30+43+44+55+58+93+106+141 seed = Math.floor( Math.random() * 10000 ), nodes = [], savedNodes = [], beats = []; // Generate some scales (a, d & e) // Frequencies from http://www.seventhstring.com/resources/notefrequencies.html // Delta ratios are musical harmonies, like http://modularscale.com/ var notes = {}; notes.a = { min: [ 220.0,246.9,261.6,293.7,329.6,349.2,415.3,440.0,493.9,523.3 ], maj: [ 220.0,246.9,277.2,293.7,329.6,370.0,415.3,440.0,493.9,554.4 ], minColor: 'hsl(180, 90%, 50%)', majColor: 'hsl(160, 90%, 50%)' }; notes.d = { min: generateScaleFrom( notes.a.min, 4/3 ), maj: generateScaleFrom( notes.a.maj, 4/3 ), minColor: 'hsl(140, 90%, 50%)', majColor: 'hsl(120, 90%, 50%)' }; notes.e = { min: generateScaleFrom( notes.a.min, 3/2 ), maj: generateScaleFrom( notes.a.maj, 3/2 ), minColor: 'hsl(100, 90%, 50%)', majColor: 'hsl(80, 90%, 50%)' }; /** * */ function initialize() { // Run selectors and cache element references container = document.getElementById( 'wrapper' ); canvas = document.querySelector( '#wrapper canvas' ); sidebar = document.querySelector( '#wrapper .sidebar' ); resetButton = document.querySelector( '#wrapper .sidebar .reset' ); saveButton = document.querySelector( '#wrapper .sidebar .save' ); sequencer = document.querySelector( '#wrapper .sequencer' ); sequencerInput = document.querySelector( '#wrapper .sequencer-input' ); sequencerInputElements = sequencerInput.querySelectorAll( 'li' ); sequencerAddButton = document.querySelector( '#wrapper .sequencer .add-key' ); if ( canvas && canvas.getContext ) { context = canvas.getContext('2d'); context.globalCompositeOperation = 'lighter'; // Split the query values into a key/value object location.search.replace( /[A-Z0-9]+?=([\w|\-|\+]*)/gi, function(a) { query[ a.split( '=' ).shift() ] = a.split( '=' ).pop(); } ); if( query.seed ) { seed = parseInt( query.seed ); } addEventListeners(); // Force an initial layout onWindowResize(); setup(); load(); update(); } else { alert( 'Doesn\'t seem like your browser supports the HTML5 canvas element :(' ); } } function addEventListeners() { resetButton.addEventListener('click', onResetButtonClicked, false); saveButton.addEventListener('click', onSaveButtonClicked, false); sequencerAddButton.addEventListener('click', onSequencerAddButtonClick, false); canvas.addEventListener('mousedown', onCanvasMouseDown, false); document.addEventListener('mousemove', onDocumentMouseMove, false); document.addEventListener('mouseup', onDocumentMouseUp, false); canvas.addEventListener('touchstart', onCanvasTouchStart, false); canvas.addEventListener('touchmove', onCanvasTouchMove, false); canvas.addEventListener('touchend', onCanvasTouchEnd, false); window.addEventListener('resize', onWindowResize, false); for( var i = 0, len = sequencerInputElements.length; i < len; i++ ) { sequencerInputElements[i].addEventListener( 'click', onSequencerInputElementClick, false ); } } function setup() { // Distance between nodes var cx = world.width / ( NODES_X + 1 ), cy = world.height / ( NODES_Y + 1 ); activateNodeDistance = Math.min( cx, cy ) * 0.5; var i, j, x = 0, y = 0, len = NODES_X * NODES_Y, length; // Generate nodes for( y = 0; y < NODES_Y; y++ ) { for( x = 0; x < NODES_X; x++ ) { nodes.push( new Node( cx + x * cx, cy + y * cy, x, y ) ); } } // Determine node neighbors for( i = 0; i < len; i++ ) { var nodeA = nodes[i]; for( j = 0; j < len; j++ ) { var nodeB = nodes[j]; if( nodeA !== nodeB && nodeB.distanceToNode( nodeA ) < WAVE_RADIUS ) { nodeA.neighbors.push( nodeB ); } } } } function load() { // Restore grid from query string if( document.location.search.length > 0 ) { var isRunning = false; if( query.beats ) { var beatData = query.beats.split( '+' ); for( var i = 0, len = beatData.length; i < len; i++ ) { var key = beatData[i].split( '-' )[0], scale = beatData[i].split( '-' )[1]; addBeat( key, scale ); isRunning = true; } } if( query.nodes ) { var nodeData = query.nodes.split( '+' ); for( var i = 0, len = nodeData.length; i < len; i++ ) { var index = parseInt( nodeData[i], 10 ); if( nodes[ index ] ) { nodes[ index ].activate(); isRunning = true; } } } if( isRunning ) { container.className = container.className.replace( 'empty', '' ); } } else { for( var i = 0, len = defaultBeats.length; i < len; i++ ) { addBeat( defaultBeats[i][0], defaultBeats[i][1] ); } } } function reset() { var i; for( i = 0, len = nodes.length; i < len; i++ ) { nodes[i].deactivate(); } while( beats.length ) { beats.pop().destroy(); } for( i = 0, len = defaultBeats.length; i < len; i++ ) { addBeat( defaultBeats[i][0], defaultBeats[i][1] ); } currentBeat = null; } function addBeat() { var element; if( arguments.length === 2 ) { element = document.createElement( 'li' ); element.setAttribute( 'data-key', arguments[0] ); element.setAttribute( 'data-scale', arguments[1] ); sequencer.insertBefore( element, sequencerAddButton ); } else { element = argu.........完整代码请登录后点击上方下载按钮下载查看
网友评论0