Version 0.2b :
- Intro Screen - Share buttons (Twitter/Facebook) - SoundManager - Add audio files - Some CleanUp
BIN
audio/18979__bebeto__Loop008_acid.wav
Normal file
BIN
audio/35684__jobro__Laser7.wav
Normal file
BIN
audio/39023__wildweasel__Dual_Neutron_Disruptor.wav
Normal file
BIN
audio/41525__Jamius__BigLaser.wav
Normal file
BIN
audio/87045__RunnerPack__weapGone.wav
Normal file
|
@ -1,4 +1,4 @@
|
|||
/* BASICS */
|
||||
/* GOOGLE FONT */
|
||||
.orbitron {
|
||||
font-family: 'Orbitron', serif;
|
||||
font-style: normal;
|
||||
|
@ -11,6 +11,7 @@
|
|||
line-height: 1.2;
|
||||
}
|
||||
|
||||
/* Global Container */
|
||||
.container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
@ -110,14 +111,8 @@
|
|||
height: 68px;
|
||||
}
|
||||
|
||||
/* Ennemies */
|
||||
/*#game .ennemy { border: 1px solid blue; } */
|
||||
|
||||
|
||||
/* The HUD */
|
||||
#hud {
|
||||
z-index: 90;
|
||||
}
|
||||
#hud { z-index: 90; display: none; }
|
||||
|
||||
#hud #score {
|
||||
font-size:36px;
|
||||
|
@ -138,7 +133,7 @@
|
|||
font-weight: bold;
|
||||
text-shadow: 0 0 5px rgba(115, 171, 255, 0.4) ;
|
||||
position: absolute;
|
||||
display: block;
|
||||
display: none;
|
||||
top:100px;
|
||||
right: 30px;
|
||||
}
|
||||
|
@ -155,13 +150,53 @@
|
|||
right: 30px;
|
||||
}
|
||||
|
||||
/* Debug Panel */
|
||||
/* GameIntro Panel */
|
||||
#game-intro {
|
||||
position: absolute;
|
||||
display: block;
|
||||
left: 0px;
|
||||
top: 50%;
|
||||
margin-top: -150px;
|
||||
color:#fff;
|
||||
z-index: 1000;
|
||||
width:100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#game-intro .text {
|
||||
position: relative;
|
||||
display: block;
|
||||
font-size: 64px;
|
||||
}
|
||||
|
||||
#game-intro #start-game {
|
||||
position: relative;
|
||||
display: block;
|
||||
margin: 20px auto;
|
||||
width: 300px;
|
||||
-moz-border-radius: 10px;
|
||||
-webkit-border-radius: 10px;
|
||||
border-radius: 10px;
|
||||
border: 5px solid rgba(0,0,0, 0.3);
|
||||
padding: 15px 0 10px;
|
||||
font-size: 24px;
|
||||
background: rgba(0,0,0, 0.1);
|
||||
}
|
||||
|
||||
#game-intro #start-game.hover {
|
||||
cursor: pointer;
|
||||
background: rgba(0,0,0, 0.2);
|
||||
box-shadow: 0 0 20px rgba(27, 161, 255, 0.5) ;
|
||||
-moz-box-shadow: 0 0 20px rgba(27, 161, 255, 0.5) ;
|
||||
}
|
||||
|
||||
/* GameOver Panel */
|
||||
#game-over {
|
||||
position: absolute;
|
||||
display: none;
|
||||
left: 0px;
|
||||
top: 50%;
|
||||
margin-top: -100px;
|
||||
margin-top: -150px;
|
||||
color:#fff;
|
||||
z-index: 1000;
|
||||
width:100%;
|
||||
|
@ -191,9 +226,34 @@
|
|||
#game-over #restart-game.hover {
|
||||
cursor: pointer;
|
||||
background: rgba(0,0,0, 0.2);
|
||||
box-shadow: 0 0 10px rgba(27, 161, 255, 0.5) ;
|
||||
box-shadow: 0 0 20px rgba(27, 161, 255, 0.5) ;
|
||||
-moz-box-shadow: 0 0 20px rgba(27, 161, 255, 0.5) ;
|
||||
}
|
||||
|
||||
#game-over #share-buttons {
|
||||
position: relative;
|
||||
display: block;
|
||||
text-align: center;
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
#game-over #share-buttons div {
|
||||
display: inline-block;
|
||||
margin: 0 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#game-over #share-buttons a {
|
||||
position: relative;
|
||||
display: block;
|
||||
opacity: 0.1;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
#game-over #share-buttons a img { border:none; outline: none; }
|
||||
#game-over #share-buttons a:hover { opacity: 0.9; cursor: pointer; }
|
||||
|
||||
|
||||
/* Credits */
|
||||
#credits {
|
||||
position: absolute;
|
||||
|
@ -207,11 +267,7 @@
|
|||
font-family: "Lucida Grande", Verdana;
|
||||
}
|
||||
|
||||
#credits a {
|
||||
text-decoration: none;
|
||||
color: #1ba1ff;
|
||||
}
|
||||
|
||||
#credits a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
#credits a { text-decoration: none; color: #1ba1ff; }
|
||||
#credits a:hover { text-decoration: underline; }
|
||||
#credits a.author { color: #baff58; }
|
||||
#credits a.quote { color: #fa8100; }
|
BIN
images/facebook_button.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
images/twitter_button.png
Normal file
After Width: | Height: | Size: 3 KiB |
72
index.html
|
@ -4,30 +4,48 @@
|
|||
xmlns:fb="http://www.facebook.com/2008/fbml">
|
||||
<head>
|
||||
|
||||
<meta http-equiv="X-UA-Compatible" content="chrome=1" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<!-- Google Chrome Frame Compatibility -->
|
||||
<meta http-equiv="X-UA-Compatible" content="chrome=1" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
|
||||
<!-- Facebook Meta Tags -->
|
||||
<title>Wyrian - A clone Game of Tyrian in HTML5</title>
|
||||
<meta property="og:type" content="game" />
|
||||
<meta property="og:title" content="Wyrian - A clone Game of Tyrian in HTML5" />
|
||||
<meta property="og:site_name" content="Wyrian" />
|
||||
<meta property='og:url' content='http://www.html5place.com/lab/wyrian/' />
|
||||
<meta property="fb:admins" content="100001668966106,582526084,100001643794747"/>
|
||||
<meta property="og:description" content="An alpha version clone of the Tyrian Game. Developed during the HTML5 Game Jam 2011 at Paris."/>
|
||||
<!-- SEO Friendly -->
|
||||
<title>Wyrian - A clone Game of Tyrian in HTML5</title>
|
||||
<meta name="description" content="Wyrian : An awesome clone Game of Tyrian. Developed during the HTML5 Game Jam 2011 at Paris by Guillaume DE LA RUE." />
|
||||
|
||||
<!-- Facebook Meta Tags -->
|
||||
<meta property="og:type" content="game" />
|
||||
<meta property="og:title" content="Wyrian - An awesome clone Game of Tyrian in HTML5" />
|
||||
<meta property="og:site_name" content="Wyrian" />
|
||||
<meta property="og:url" content="http://www.html5place.com/lab/wyrian/" />
|
||||
<meta property="og:description" content="Wyrian : An awesome clone Game of Tyrian. Developed during the HTML5 Game Jam 2011 at Paris."/>
|
||||
|
||||
<!-- Stylesheets -->
|
||||
<link rel="stylesheet" media="all" href="css/style.css" />
|
||||
<link href="http://fonts.googleapis.com/css?family=Orbitron:400,500,700,900" rel="stylesheet" type="text/css" >
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- Game Intro -->
|
||||
<div id="game-intro">
|
||||
<div class="text orbitron">Wyrian</div>
|
||||
<div id="start-game" class="orbitron">Play</div>
|
||||
</div>
|
||||
|
||||
<!-- Game Over -->
|
||||
<div id="game-over">
|
||||
<div class="text orbitron">GAME OVER</div>
|
||||
<div id="restart-game" class="orbitron">Restart</div>
|
||||
<div id="share-buttons">
|
||||
<div class="twitter">
|
||||
<a href="http://twitter.com/?status=RT%20%40html5place%20%3A%20Wyrian%20-%20An%20awesome%20clone%20Game%20of%20Tyrian%20in%20%23html5%20http%3A%2F%2Fbit.ly%2FgpObfX%20%23pgj2011%20%23game" target="_blank" title="Share on Twitter"><img src="images/twitter_button.png" width="122" height="42"></a>
|
||||
</div>
|
||||
<div class="facebook">
|
||||
<a href="http://www.facebook.com/sharer.php?u=http://www.html5place.com/lab/wyrian/" target="_blank" title="Share on Facebook"><img src="images/facebook_button.png" width="122" height="42"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="credits" class="">
|
||||
<strong>HTML5 Game Jam 2011</strong><br>
|
||||
<strong><a href="https://github.com/glenux/wyrian" target="_blank" title="View Project on GitHub">Wyrian</a> v0.2a</strong> | <a href="http://www.html5place.com/" title="View my Website">Guillaume DE LA RUE</a><br>Thanks to <a href="https://github.com/glenux" target="_blank" title="View profile of Glenux on GitHub">Glenux</a> for design and Matthieu Bosquet and all people presents :)
|
||||
</div>
|
||||
|
||||
<!-- Scene -->
|
||||
<div class="container" id="GameContainer">
|
||||
<div id="background" class="layout"></div>
|
||||
<div id="ground" class="layout"></div>
|
||||
|
@ -50,10 +68,30 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- The footer... -->
|
||||
<footer id="credits" class="">
|
||||
<strong>HTML5 Game Jam 2011</strong><br>
|
||||
<strong><a href="https://github.com/glenux/wyrian" target="_blank" title="View Project on GitHub" class="game">..:: Wyrian v<span id="version">0.2a</span> ::..</a></strong> | <a href="http://www.html5place.com/" title="View my Website" class="author">Guillaume DE LA RUE</a><br>Thanks to <a href="https://github.com/glenux" target="_blank" title="View profile of Glenux on GitHub" class="quote">Glenux</a> for design and Matthieu Bosquet<br>And everyone present at the HTML5 Game Jam :)
|
||||
</footer>
|
||||
|
||||
<script type="text/javascript" src="js/jquery-1.5.js"></script>
|
||||
<script type="text/javascript" src="js/require.js"></script>
|
||||
<!-- Main JS Libs -->
|
||||
<script type="text/javascript" src="js/libs/jquery-1.5.js"></script>
|
||||
<script type="text/javascript" src="js/libs/require.js"></script>
|
||||
<script type="text/javascript" src="js/GameClass.js"></script>
|
||||
<script type="text/javascript" src="js/Wyrian.js"></script>
|
||||
<script type="text/javascript" src="js/main.js"></script>
|
||||
|
||||
<!-- ANalytics Tracking -->
|
||||
<script type="text/javascript">
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-12891268-4']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
|
||||
(function() {
|
||||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
BIN
js/.DS_Store
vendored
Normal file
|
@ -68,7 +68,7 @@ app.prototype.log = function(txt) {
|
|||
app.prototype.loopAnimation = function() {
|
||||
|
||||
// -- Search for elements that have to be updated
|
||||
Wyrian.activeElements = 0 ;
|
||||
Game.activeElements = 0 ;
|
||||
for ( var i in Layouts ) {
|
||||
var _layout = Layouts[i] ;
|
||||
if ( _layout && _layout.running ) {
|
||||
|
@ -77,7 +77,7 @@ app.prototype.loopAnimation = function() {
|
|||
}
|
||||
|
||||
// -- Get level
|
||||
Level = Math.floor((Wyrian.score||0)/1000) ;
|
||||
Level = Math.floor((Game.score||0)/1000) ;
|
||||
|
||||
// -- Create ennemies if needed
|
||||
var numEnnemies = 0 ;
|
||||
|
@ -90,10 +90,10 @@ app.prototype.loopAnimation = function() {
|
|||
}
|
||||
|
||||
// -- Init loops counter
|
||||
Wyrian.loops = Wyrian.loops||0 ;
|
||||
Game.loops = Game.loops||0 ;
|
||||
|
||||
// -- Init vars
|
||||
if ( Wyrian.loops == 0 ) {
|
||||
if ( Game.loops == 0 ) {
|
||||
this.frameCount = 0;
|
||||
this.fps = 0;
|
||||
this.maxfps = 1 / (FPS / 1000);
|
||||
|
@ -111,11 +111,11 @@ app.prototype.loopAnimation = function() {
|
|||
this.frameCount++;
|
||||
|
||||
// -- Increase loop counter
|
||||
Wyrian.loops++ ;
|
||||
Game.loops++ ;
|
||||
|
||||
// -- Refresh Scores and HUD informations
|
||||
$('#score span').html(Wyrian.score) ;
|
||||
$('#activeElements span').html(Wyrian.activeElements) ;
|
||||
$('#score span').html(Game.score) ;
|
||||
$('#activeElements span').html(Game.activeElements) ;
|
||||
$('#fpsCounter span').html(this.fps) ;
|
||||
}
|
||||
|
||||
|
|
112
js/Wyrian.js
|
@ -1,112 +0,0 @@
|
|||
/**************************************************************************
|
||||
* Init Game Bootstrap
|
||||
***************************************************************************/
|
||||
Wyrian = new app({
|
||||
'libs': [
|
||||
'order!jquery.transform-0.9.3.min',
|
||||
'order!LayoutClass'
|
||||
],
|
||||
'layers': [
|
||||
'order!layouts/BgLayer',
|
||||
'order!layouts/PlayerLayer',
|
||||
'order!layouts/Ennemies'
|
||||
],
|
||||
'wrapper': $('#GameContainer')
|
||||
}) ;
|
||||
|
||||
|
||||
// Init Application and bind all games events
|
||||
jQuery(document).ready(function() {
|
||||
|
||||
/**************************************************************************
|
||||
* Load Dependencies & Create Application
|
||||
***************************************************************************/
|
||||
require({
|
||||
baseUrl: "js/",
|
||||
urlArgs: "bust=" + Wyrian.version
|
||||
}, Wyrian.settings.libs,
|
||||
|
||||
// -- All objects are loaded => can run
|
||||
function() {
|
||||
|
||||
// -- Init Stage or show IE popup
|
||||
if ( ! $.browser.msie ) {
|
||||
Wyrian.init() ;
|
||||
} else {
|
||||
$.facebox.settings.opacity = 0.8 ;
|
||||
$.facebox.settings.closeImage = '/common/img/facebox/apple-close.png' ;
|
||||
$(document).unbind('close.facebox') ;
|
||||
$.facebox({ajax: '/popup-ie/'}, 'popup-ie' ) ;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Game Controls Events
|
||||
***************************************************************************/
|
||||
|
||||
// -- Game is loaded
|
||||
$(document).bind('gameLoaded', function(e, res) {
|
||||
if ( timers.loopGame ) clearInterval(timers.loopGame) ;
|
||||
timers.loopGame = setInterval(Wyrian.loopAnimation, 1000/FPS) ;
|
||||
});
|
||||
|
||||
// -- Init Game
|
||||
$(document).bind('gameInit', function(e, res) {
|
||||
$(document).trigger('gameReset') ;
|
||||
}) ;
|
||||
|
||||
// -- Game Reset
|
||||
$(document).bind('gameReset', function(e, res) {
|
||||
Wyrian.score = 0 ;
|
||||
Wyrian.loops = 0 ;
|
||||
Layouts.Ennemies.els = [] ;
|
||||
$('.sprite').remove() ;
|
||||
$.each(Layouts, function(key, val){
|
||||
Layouts[key].running = true ;
|
||||
$.each(val.els, function(key2, val2){
|
||||
if ( Layouts[key].els.length && Layouts[key].els[key2] ) {
|
||||
Layouts[key].els[key2].x = Layouts[key].els[key2].settings.origin.x ;
|
||||
Layouts[key].els[key2].y = Layouts[key].els[key2].settings.origin.y ;
|
||||
}
|
||||
}) ;
|
||||
}) ;
|
||||
|
||||
if ( timers.loopGame ) clearInterval(timers.loopGame) ;
|
||||
timers.loopGame = setInterval(Wyrian.loopAnimation, 1000/FPS) ;
|
||||
}) ;
|
||||
|
||||
// -- Start Animation
|
||||
$(document).bind('gameStart', function(e, res) {
|
||||
|
||||
}) ;
|
||||
|
||||
// -- On Complete Launch
|
||||
$(document).bind('gameComplete', function(e, res) {
|
||||
|
||||
// -- Stop layouts running
|
||||
$('.sprite').not('.explosion').remove() ;
|
||||
Layouts.Ennemies.running = false ;
|
||||
Layouts.Background.running = false ;
|
||||
|
||||
// -- Show game over overlay
|
||||
$('#game-over:hidden').fadeIn(500) ;
|
||||
|
||||
// -- Stop loopAnimation
|
||||
if ( timers.loopGame ) clearInterval(timers.loopGame) ;
|
||||
|
||||
}) ;
|
||||
|
||||
// -- Bind Restart Screen controls
|
||||
$('#game-over #restart-game').click(function() {
|
||||
$('#game-over:visible').fadeOut(500, function() {
|
||||
$(document).trigger('gameReset') ;
|
||||
}) ;
|
||||
}).hover(function() {
|
||||
$(this).addClass('hover') ;
|
||||
}, function() {
|
||||
$(this).removeClass('hover') ;
|
||||
}) ;
|
||||
|
||||
}) ;
|
|
@ -4,13 +4,14 @@ Layouts.Ennemies = new Layout({
|
|||
|
||||
// -- Define elements to draw with options
|
||||
el: [],
|
||||
images: ['images/sprites/alien_1.png?_=1', 'images/sprites/alien_2.png?_=1', 'images/sprites/explosion-sprite.png' ],
|
||||
|
||||
// -- Define current Speed
|
||||
speed: 7,
|
||||
direction: 1,
|
||||
|
||||
// -- Define canvas parent
|
||||
dom: $('div#game')
|
||||
dom: $('div#ground')
|
||||
|
||||
}) ;
|
||||
|
||||
|
@ -32,13 +33,13 @@ Layouts.Ennemies.createRandom = function(opts) {
|
|||
{
|
||||
width: 80,
|
||||
height: 80,
|
||||
imageSrc: 'images/sprites/alien_1.png?_=1',
|
||||
imageSrc: self.settings.images[0],
|
||||
sprites: [0,1,2,3]
|
||||
},
|
||||
{
|
||||
width: 80,
|
||||
height: 80,
|
||||
imageSrc: 'images/sprites/alien_2.png?_=1',
|
||||
imageSrc: self.settings.images[1],
|
||||
sprites: [0]
|
||||
}
|
||||
] ;
|
||||
|
@ -60,8 +61,8 @@ Layouts.Ennemies.createRandom = function(opts) {
|
|||
obj.box.hide(0);
|
||||
obj = self.reinitObj(obj);
|
||||
|
||||
Wyrian.score = Wyrian.score || 0 ;
|
||||
Wyrian.score += obj.settings.power ;
|
||||
Game.score = Game.score || 0 ;
|
||||
Game.score += obj.settings.power ;
|
||||
} ;
|
||||
alien.animate = function (obj) {
|
||||
if ( obj.explosing ) {
|
||||
|
@ -87,7 +88,7 @@ Layouts.Ennemies.createExplosion = function(object) {
|
|||
type: 'neutral',
|
||||
width:330,
|
||||
height:330,
|
||||
imageSrc: 'images/sprites/explosion-sprite.png',
|
||||
imageSrc: self.settings.images[2],
|
||||
sprites: [0,1,2],
|
||||
origin: {x: object.x-330/2+object.width/2, y: object.y-330/2+object.height/2},
|
||||
animate: function(obj) {
|
||||
|
|
|
@ -34,34 +34,6 @@ var Layout = function(opts) {
|
|||
return this;
|
||||
};
|
||||
|
||||
// -- Return or set settings
|
||||
Layout.prototype.option = function(optName, optValue) {
|
||||
|
||||
// No params => return all settings
|
||||
if ( typeof optName == 'undefined' ) return this.settings;
|
||||
|
||||
// If optName and optValue set => modify it
|
||||
else if ( typeof optValue != 'undefined' ) this.settings[optName] = this.settings ;
|
||||
|
||||
// In other cases, simply return the setting value
|
||||
else return this.settings[optName] ;
|
||||
|
||||
};
|
||||
|
||||
// -- Return an object by name
|
||||
Layout.prototype.getObj = function(name) {
|
||||
this.cache = this.cache || {} ;
|
||||
|
||||
if ( this.cache[name] ) return this.cache[name] ;
|
||||
|
||||
for ( var i in this.els ) {
|
||||
if ( this.els[i].settings.name == name ) {
|
||||
this.cache[name] = this.els[i] ;
|
||||
return this.cache[name] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -- Update elements into layout
|
||||
Layout.prototype.update = function() {
|
||||
for ( var j in this.els ) {
|
||||
|
@ -100,7 +72,7 @@ Layout.prototype.createObj = function(opts) {
|
|||
// -- Store options
|
||||
this.parent = self ;
|
||||
this.name = settingsObj.name || 'default' ;
|
||||
this.id = settingsObj.id || 'element_'+Wyrian.uniqId++ ;
|
||||
this.id = settingsObj.id || 'element_'+Game.uniqId++ ;
|
||||
this.width = settingsObj.width ? settingsObj.width : self.width ;
|
||||
this.height = settingsObj.height ? settingsObj.height : self.height ;
|
||||
this.settings = settingsObj ;
|
||||
|
@ -118,36 +90,42 @@ Layout.prototype.createObj = function(opts) {
|
|||
|
||||
// -- Create a DOM object
|
||||
this.box = $('#'+this.id) ;
|
||||
this.dynamic = false ;
|
||||
this.cssObj = {} ;
|
||||
if ( ! this.box.length ) {
|
||||
|
||||
this.box = $('<div>', {
|
||||
class:'sprite '+this.name,
|
||||
id: this.id,
|
||||
css:{
|
||||
position: 'absolute',
|
||||
display: 'block',
|
||||
top: 0,
|
||||
left: 0,
|
||||
backgroundColor: settingsObj.backgroundColor,
|
||||
backgroundRepeat: settingsObj.backgroundRepeat,
|
||||
backgroundPosition: settingsObj.backgroundPosition,
|
||||
backgroundImage: settingsObj.imageSrc ? 'url('+settingsObj.imageSrc+')' : ''
|
||||
}
|
||||
}).appendTo(self.dom) ;
|
||||
} else {
|
||||
this.box.show(0) ;
|
||||
id: this.id
|
||||
}) ;
|
||||
|
||||
this.cssObj = {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
display: 'block',
|
||||
backgroundColor: settingsObj.backgroundColor,
|
||||
backgroundRepeat: settingsObj.backgroundRepeat,
|
||||
backgroundPosition: settingsObj.backgroundPosition,
|
||||
backgroundImage: settingsObj.imageSrc ? 'url('+settingsObj.imageSrc+')' : ''
|
||||
} ;
|
||||
|
||||
this.dynamic = true ;
|
||||
}
|
||||
|
||||
// -- Apply CSS
|
||||
this.box.css({
|
||||
width: this.width,
|
||||
height: this.height
|
||||
}) ;
|
||||
this.cssObj.width = this.width ;
|
||||
this.cssObj.height = this.height ;
|
||||
|
||||
// -- Move
|
||||
if ( ! this.settings.nomove ) {
|
||||
this.box.transform({'translate': this.x+'px, '+this.y+'px'}) ;
|
||||
this.cssObj.translate = this.x+'px, '+this.y+'px' ;
|
||||
}
|
||||
|
||||
// -- Apply CSS Append and display
|
||||
this.box.css(this.cssObj) ;
|
||||
if ( this.dynamic ) this.box.appendTo(self.dom) ;
|
||||
|
||||
} ;
|
||||
|
||||
// -- Init
|
||||
|
@ -163,14 +141,14 @@ Layout.prototype.createObj = function(opts) {
|
|||
|
||||
// -- Draw object into scene
|
||||
Obj.prototype.draw = function() {
|
||||
if ( (this.y >= -2*this.height) && (this.y <= (Wyrian.height+this.height)) && this.x >= -this.width && this.x <= (Wyrian.width+this.width) ) {
|
||||
if ( (this.y >= -2*this.height) && (this.y <= (Game.height+this.height)) && this.x >= -this.width && this.x <= (Game.width+this.width) ) {
|
||||
|
||||
Wyrian.activeElements++ ;
|
||||
Game.activeElements++ ;
|
||||
|
||||
// -- Set sprite to display
|
||||
if ( this.settings.sprites ) {
|
||||
this.lastSprite = this.lastSprite || 0 ;
|
||||
if ( (Wyrian.loops%(this.settings.spriteMod||1)) == 0 ) this.lastSprite++ ;
|
||||
if ( (Game.loops%(this.settings.spriteMod||1)) == 0 ) this.lastSprite++ ;
|
||||
if ( typeof this.settings.sprites[this.lastSprite] == 'undefined' ) this.lastSprite = 0 ;
|
||||
this.box.css({'backgroundPosition': -1*this.settings.sprites[this.lastSprite]*this.settings.width+'px 0'}) ;
|
||||
}
|
||||
|
@ -270,7 +248,7 @@ Layout.prototype.createObj = function(opts) {
|
|||
this.settings.explode(this) ;
|
||||
}
|
||||
|
||||
Wyrian.log('█▬█ █ ▀█▀') ;
|
||||
Game.log('█▬█ █ ▀█▀') ;
|
||||
}
|
||||
}
|
||||
|
|
@ -11,8 +11,8 @@ Layouts.Player = new Layout({
|
|||
type: 'human',
|
||||
sprites: [0,1],
|
||||
origin: {
|
||||
x: Wyrian.width/2 - 80,
|
||||
y: Wyrian.height-220
|
||||
x: Game.width/2 - 80,
|
||||
y: Game.height-220
|
||||
},
|
||||
fireInterval: 300,
|
||||
explode: function(obj) {
|
||||
|
@ -24,23 +24,23 @@ Layouts.Player = new Layout({
|
|||
animate: function(obj) {
|
||||
|
||||
// -- KEY up /down
|
||||
if ( Wyrian.input.keyboard.up ) {
|
||||
if ( Game.input.keyboard.up ) {
|
||||
if ( obj.y > 0 ) obj.y -= obj.parent.settings.speed ;
|
||||
}
|
||||
if ( Wyrian.input.keyboard.down && (obj.y < (Wyrian.height-obj.height) ) ) {
|
||||
if ( Game.input.keyboard.down && (obj.y < (Game.height-obj.height) ) ) {
|
||||
obj.y += obj.parent.settings.speed;
|
||||
}
|
||||
|
||||
// -- Left/Right move : choose sprite sequence to display
|
||||
if ( Wyrian.input.keyboard.left && (obj.x > 0)) {
|
||||
if ( Game.input.keyboard.left && (obj.x > 0)) {
|
||||
obj.x -= obj.parent.settings.speed;
|
||||
}
|
||||
if ( Wyrian.input.keyboard.right && (obj.x < Wyrian.width-obj.width) ) {
|
||||
if ( Game.input.keyboard.right && (obj.x < Game.width-obj.width) ) {
|
||||
obj.x += obj.parent.settings.speed;
|
||||
}
|
||||
|
||||
// -- Press Space : fire
|
||||
if ( Wyrian.input.keyboard.space ) {
|
||||
if ( Game.input.keyboard.space ) {
|
||||
obj.parent.fire(obj) ;
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ Layouts.Player = new Layout({
|
|||
animate: function(obj) {
|
||||
obj.settings.spriteMod = 3 ;
|
||||
obj.settings.sprites = [0,1] ;
|
||||
if ( Wyrian.input.keyboard.up ) {
|
||||
if ( Game.input.keyboard.up ) {
|
||||
obj.settings.sprites = [2,3,4] ;
|
||||
}
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ Layouts.Player.bulletLib = function(obj, bulletType) {
|
|||
if ( obj.deleteAfter ) return false;
|
||||
if ( obj.explosing ) {
|
||||
|
||||
Wyrian.log(obj) ;
|
||||
Game.log(obj) ;
|
||||
return false ;
|
||||
}
|
||||
obj.y += obj.settings.speed*obj.settings.direction ;
|
||||
|
|
0
js/jquery-1.5.js → js/libs/jquery-1.5.js
vendored
98
js/libs/soundmanager/README.rdoc
Normal file
|
@ -0,0 +1,98 @@
|
|||
== SoundManager 2: JavaScript Sound for the Web
|
||||
|
||||
By wrapping and extending HTML5 and Flash Audio APIs, SoundManager 2 brings reliable cross-platform audio to JavaScript.
|
||||
|
||||
== HTML5 Audio() Support (Beta-ish)
|
||||
|
||||
* 100% Flash-free MP3 + MP4/AAC where supported, compatible with Apple iPad 3.2, iPhone/iOS 4
|
||||
* Fallback to Flash for MP3/MP4 support, as needed
|
||||
* SM2 API is unchanged, transparent; HTML5/flash switching handled internally
|
||||
* HTML5 API support approximates Flash 8 API features, minus ID3, plus buffering
|
||||
* Some other formats (WAV/OGG) supported via HTML5, depending on browser
|
||||
* See soundManager.useHTML5Audio for implementation details.
|
||||
|
||||
== Basic API Features (Flash 8)
|
||||
|
||||
* Load, stop, play, pause, mute, seek, pan and volume control of sounds from Javascript
|
||||
* Events: onload, whileloading, whileplaying, onfinish and more
|
||||
* ID3V1 and ID3V2 tag support for MP3s (title, artist, genre etc.)
|
||||
|
||||
== Shiny Flash 9 Features
|
||||
|
||||
* RTMP / Flash Media Server streaming support (new, experimental)
|
||||
* MPEG-4 (AAC, HE-AAC, H.264) audio support
|
||||
* "MultiShot" play (layered/chorusing effects)
|
||||
* Waveform/frequency spectrum data
|
||||
* Peak (L/R channel volume) data
|
||||
* Audio buffering state/event handling
|
||||
|
||||
== General Tech Stuff
|
||||
|
||||
* Full API Documentation with examples and notes
|
||||
* console.log()-style debug output and troubleshooting tools
|
||||
* Community-based discussion/support
|
||||
|
||||
== As heard on The Internets
|
||||
|
||||
A few nifty sites that have implemented SM2 for driving audio:
|
||||
|
||||
* Muxtape
|
||||
* SoundCloud / The Cloud Player
|
||||
* 8tracks
|
||||
* Last.fm
|
||||
* Opera (media player component)
|
||||
* Discogs
|
||||
* Mixcrate
|
||||
|
||||
== Project home, documentation, live demos etc.:
|
||||
|
||||
http://www.schillmania.com/projects/soundmanager2/
|
||||
|
||||
|
||||
== Merged fork ( kjvarga: http://github.com/kjvarga/SoundManager2/ )
|
||||
|
||||
This SM2 fork contains the SoundManager2 implementation that is used on http://www.kazaa.com.
|
||||
|
||||
We added RTMP support to SM2 which is now part of the SM2 (experimental) branch as of V2.96a.20100606.
|
||||
|
||||
Downloads: http://www.schillmania.com/projects/soundmanager2/doc/download/
|
||||
|
||||
For more background on the addition of RTMP check out http://getsatisfaction.com/schillmania/topics/soundmanager_doesnt_support_rtmp
|
||||
|
||||
Our old branch of development has been moved to http://github.com/kjvarga/SoundManager2/tree/pre_merge.
|
||||
|
||||
== Changes
|
||||
|
||||
In addition to the documented SM2 options, we have added the following.
|
||||
|
||||
New options to SM2:
|
||||
|
||||
* <tt>ondebuglog</tt> callback called with every debugging message. Useful if you need to programatically have access to the debug logs. We use this in our automated reporting of stream failures for QA.
|
||||
|
||||
New options to createSound:
|
||||
|
||||
* <tt>bufferTimes</tt> optional array of buffer times for double/multiple-buffering. Just specify an array of incrementing buffer sizes (in seconds) e.g. [0.5, 2, 8] for a half-second, then 2 second, then 8 second buffer. Buffers increment when full and reset to the smallest buffer when empty, or when starting to play an unbuffered portion of the stream.
|
||||
* <tt>onstats</tt> callback called with statistics including how long it took to connect to the server, and how long it took to play (useful for QA).
|
||||
|
||||
Our FMS server has some peculiarities that we have to deal with:
|
||||
* bytesLoaded is always 0 for a streaming sound
|
||||
* NetStream.Play.Stop is sent when it shouldn't
|
||||
* We cannot get the stream length using a typical <tt>getStreamLength</tt> call
|
||||
* We cannot get bandwidth information
|
||||
|
||||
== Debugging
|
||||
|
||||
1. Set <tt>soundManager.debugFlash = true;</tt>
|
||||
2. Use a debug version of the SWF e.g. soundmanager2_flash9_debug.swf
|
||||
3. Open the Flash IDE. Open the SM2 source code files. Start a remote debugging session.
|
||||
4. Refresh the application in the browser (make sure caching is off).
|
||||
5. The SWF should connect to Flash and allow you to step through the source.
|
||||
|
||||
If it doesn't:
|
||||
1. Make sure that the Flash version you have installed supports debugging
|
||||
2. Make sure that the Flash debugger application is using the same version of Flash.
|
||||
|
||||
== SM2
|
||||
|
||||
Project home, documentation, live demos etc.:
|
||||
http://www.schillmania.com/projects/soundmanager2/
|
BIN
js/libs/soundmanager/demo/360-player/360 button.psd
Normal file
BIN
js/libs/soundmanager/demo/360-player/360-button-pause-light.gif
Normal file
After Width: | Height: | Size: 333 B |
BIN
js/libs/soundmanager/demo/360-player/360-button-pause-light.png
Normal file
After Width: | Height: | Size: 445 B |
BIN
js/libs/soundmanager/demo/360-player/360-button-pause.gif
Normal file
After Width: | Height: | Size: 333 B |
BIN
js/libs/soundmanager/demo/360-player/360-button-pause.png
Normal file
After Width: | Height: | Size: 440 B |
BIN
js/libs/soundmanager/demo/360-player/360-button-play-light.gif
Normal file
After Width: | Height: | Size: 442 B |
BIN
js/libs/soundmanager/demo/360-player/360-button-play-light.png
Normal file
After Width: | Height: | Size: 501 B |
BIN
js/libs/soundmanager/demo/360-player/360-button-play.gif
Normal file
After Width: | Height: | Size: 442 B |
BIN
js/libs/soundmanager/demo/360-player/360-button-play.png
Normal file
After Width: | Height: | Size: 487 B |
100
js/libs/soundmanager/demo/360-player/360player-visualization.css
Normal file
|
@ -0,0 +1,100 @@
|
|||
/* larger canvas, spectrum + EQ visualization and other items */
|
||||
|
||||
.ui360,
|
||||
.sm2-360ui {
|
||||
/* size of the container for the circle, etc. */
|
||||
width:256px;
|
||||
height:256px;
|
||||
}
|
||||
|
||||
.ui360 {
|
||||
position:relative;
|
||||
/* a little extra spacing */
|
||||
padding-top:1px;
|
||||
padding-bottom:1px;
|
||||
margin-bottom:-18px; /* approximate "line height" we want */
|
||||
padding-left:248px;
|
||||
margin-left:0px;
|
||||
background-position:22.6% 50%; /* (~109px) initial play button position */
|
||||
}
|
||||
|
||||
.ui360 a {
|
||||
font:14px "helvetica neue",helvetica,monaco,lucida,terminal,monospace;
|
||||
white-space:nowrap;
|
||||
line-height:256px;
|
||||
}
|
||||
|
||||
.sm2-360ui {
|
||||
margin-left:-256px;
|
||||
}
|
||||
|
||||
.ui360 .sm2-timing {
|
||||
line-height:256px;
|
||||
}
|
||||
|
||||
.ui360 .sm2-timing {
|
||||
font:bold 24px "helvetica neue",helvetica,monaco,lucida,terminal,monospace;
|
||||
color:#333;
|
||||
text-align:center;
|
||||
line-height:256px;
|
||||
text-indent:0px;
|
||||
}
|
||||
|
||||
.sm2-inline-list .ui360,
|
||||
.sm2-inline-list .sm2-360ui {
|
||||
margin-left:0px;
|
||||
}
|
||||
|
||||
.sm2-inline-list .ui360 {
|
||||
margin:8px 13px 7px 0px;
|
||||
padding-left:0px;
|
||||
background-position:50% 50%; /* initial play button position */
|
||||
}
|
||||
|
||||
.sm2-inline-list .sm2-360ui {
|
||||
border:1px solid #eee;
|
||||
/* offset the border */
|
||||
margin-left:-1px;
|
||||
margin-top:-1px;
|
||||
}
|
||||
|
||||
.sm2-inline-list .ui360 a {
|
||||
position:absolute;
|
||||
display:inline;
|
||||
left:0px;
|
||||
bottom:0px;
|
||||
width:100%; /* 2px padding in box */
|
||||
height:100%;
|
||||
*height:256px; /* IE is dumb. */
|
||||
overflow:hidden;
|
||||
font-size:small;
|
||||
font-weight:300;
|
||||
color:#333;
|
||||
margin:0px;
|
||||
padding:0px;
|
||||
line-height:488px; /* bottom vertical alignment for text */
|
||||
*line-height:480px; /* IE again */
|
||||
text-align:center;
|
||||
-moz-border-radius:0px;
|
||||
-khtml-border-radius:0px;
|
||||
border-radius:0px;
|
||||
}
|
||||
|
||||
.sm2-inline-list .ui360:hover {
|
||||
background-color:#fbfbfb;
|
||||
}
|
||||
|
||||
.sm2-inline-list .ui360 a.sm2_link:hover,
|
||||
.sm2-inline-list .ui360 a:focus,
|
||||
.sm2-inline-list .ui360 a:active {
|
||||
background-color:transparent;
|
||||
}
|
||||
|
||||
/* Use a bigger loading image for this layout */
|
||||
|
||||
|
||||
.ui360:hover .sm2-360btn-default {
|
||||
background:transparent url(360-button-play-light.png) no-repeat 50% 50%;
|
||||
_background:transparent url(360-button-play.gif) no-repeat 50% 50%;
|
||||
cursor:pointer;
|
||||
}
|
251
js/libs/soundmanager/demo/360-player/360player.css
Normal file
|
@ -0,0 +1,251 @@
|
|||
/* General warning: Beta-ish. Code could be a bit cleaner. */
|
||||
|
||||
.ui360,
|
||||
.sm2-360ui {
|
||||
/* size of the container for the circle, etc. */
|
||||
width:50px;
|
||||
height:50px;
|
||||
}
|
||||
|
||||
.ui360 {
|
||||
position:relative;
|
||||
/* a little extra spacing */
|
||||
padding-top:1px;
|
||||
padding-bottom:1px;
|
||||
margin-bottom:-18px; /* approximate "line height" we want */
|
||||
padding-left:42px; /* 50px, with a few off - margin used for visualization UI */
|
||||
width:auto;
|
||||
}
|
||||
|
||||
.ui360,
|
||||
.ui360 * {
|
||||
position:relative;
|
||||
vertical-align:middle;
|
||||
}
|
||||
|
||||
|
||||
.ui360 a {
|
||||
line-height:50px;
|
||||
}
|
||||
|
||||
.sm2-360ui {
|
||||
position:relative;
|
||||
display:inline-block; /* firefox 3 et al */
|
||||
float:left; /* firefox 2 needs this, inline-block would work with fx3 and others */
|
||||
*float:left; /* IE 6+7 */
|
||||
*display:inline;
|
||||
*clear:left;
|
||||
margin-left:-50px;
|
||||
}
|
||||
|
||||
.sm2-360ui.sm2_playing,
|
||||
.sm2-360ui.sm2_paused {
|
||||
/* bump on top when active */
|
||||
z-index:10;
|
||||
}
|
||||
|
||||
.ui360 a.sm2_link { /* this class added to playable links by SM2 */
|
||||
position:relative;
|
||||
}
|
||||
|
||||
.ui360 a {
|
||||
color:#000;
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
.ui360 a,
|
||||
.ui360 a:hover,
|
||||
.ui360 a:focus {
|
||||
padding:2px;
|
||||
margin-left:-2px;
|
||||
margin-top:-2px;
|
||||
}
|
||||
|
||||
.ui360 a:hover,
|
||||
.ui360 a:focus {
|
||||
background:#eee;
|
||||
-moz-border-radius:3px;
|
||||
-webkit-border-radius:3px;
|
||||
-khtml-border-radius:3px;
|
||||
border-radius:3px;
|
||||
outline:none;
|
||||
}
|
||||
|
||||
.ui360 .sm2-canvas {
|
||||
position:absolute;
|
||||
left:0px;
|
||||
top:0px;
|
||||
}
|
||||
|
||||
.ui360 .sm2-timing {
|
||||
position:absolute;
|
||||
display:block;
|
||||
left:0px;
|
||||
top:0px;
|
||||
width:100%;
|
||||
height:100%;
|
||||
margin:0px;
|
||||
font:11px "helvetica neue",helvetica,monaco,lucida,terminal,monospace;
|
||||
color:#666;
|
||||
text-align:center;
|
||||
line-height:50px;
|
||||
}
|
||||
|
||||
.ui360 .sm2-timing.alignTweak {
|
||||
text-indent:1px; /* devious center-alignment tweak for Safari (might break things for others.) */
|
||||
}
|
||||
|
||||
.ui360 .sm2-cover {
|
||||
position:absolute;
|
||||
left:0px;
|
||||
top:0px;
|
||||
width:100%;
|
||||
height:100%;
|
||||
z-index:2;
|
||||
display:none;
|
||||
}
|
||||
|
||||
.ui360 .sm2-360btn {
|
||||
position:absolute;
|
||||
top:50%;
|
||||
left:50%;
|
||||
width:22px;
|
||||
height:22px;
|
||||
margin-left:-11px;
|
||||
margin-top:-11px;
|
||||
cursor:pointer;
|
||||
z-index:3;
|
||||
}
|
||||
|
||||
.ui360 .sm2-360btn-default {
|
||||
}
|
||||
|
||||
.ui360 .sm2-360data {
|
||||
display:inline-block;
|
||||
font-family:helvetica;
|
||||
}
|
||||
|
||||
.ui360 .sm2-360ui.sm2_playing .sm2-cover,
|
||||
.ui360 .sm2-360ui.sm2_paused .sm2-cover {
|
||||
display:block;
|
||||
}
|
||||
|
||||
/* this could be optimized a fair bit. */
|
||||
|
||||
.ui360,
|
||||
.ui360 .sm2-360btn-default {
|
||||
background:transparent url(360-button-play.png) no-repeat 50% 50%;
|
||||
_background:transparent url(360-button-play.gif) no-repeat 50% 50%; /* IE 6-only: special crap GIF */
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.ui360 {
|
||||
/*
|
||||
"fake" button shown before SM2 has started, non-JS/non-SM2 case etc.
|
||||
background image will be removed via JS, in threeSixyPlayer.init()
|
||||
*/
|
||||
background-position:6px 50%;
|
||||
}
|
||||
|
||||
.ui360 .sm2-360ui.sm2_paused .sm2-360btn {
|
||||
background:transparent url(360-button-play.png) no-repeat 50% 50%;
|
||||
_background:transparent url(360-button-play.gif) no-repeat 50% 50%;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.ui360 .sm2-360btn-default:hover,
|
||||
.ui360 .sm2-360ui.sm2_paused .sm2-360btn:hover {
|
||||
background:transparent url(360-button-play-light.png) no-repeat 50% 50%;
|
||||
_background:transparent url(360-button-play.gif) no-repeat 50% 50%;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.ui360 .sm2-360ui.sm2_playing .sm2-360btn:hover,
|
||||
.ui360 .sm2-360btn-playing:hover {
|
||||
background:transparent url(360-button-pause-light.png) no-repeat 50% 50%;
|
||||
_background:transparent url(360-button-pause-light.gif) no-repeat 50% 50%;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
|
||||
.ui360 .sm2-360ui.sm2_playing .sm2-timing {
|
||||
visibility:visible;
|
||||
}
|
||||
|
||||
.ui360 .sm2-360ui.sm2_buffering .sm2-timing {
|
||||
visibility:hidden;
|
||||
}
|
||||
|
||||
.ui360 .sm2-360ui .sm2-timing,
|
||||
.ui360 .sm2-360ui .sm2-360btn:hover + .sm2-timing,
|
||||
.ui360 .sm2-360ui.sm2_paused .sm2-timing {
|
||||
visibility:hidden;
|
||||
}
|
||||
|
||||
.ui360 .sm2-360ui.sm2_dragging .sm2-timing,
|
||||
.ui360 .sm2-360ui.sm2_dragging .sm2-360btn:hover + .sm2-timing {
|
||||
/* paused + dragging */
|
||||
visibility:visible;
|
||||
}
|
||||
|
||||
.ui360 .sm2-360ui.sm2_playing .sm2-360btn,
|
||||
x.ui360 .sm2-360btn-playing,
|
||||
.ui360 .sm2-360ui.sm2_dragging .sm2-360btn,
|
||||
.ui360 .sm2-360ui.sm2_dragging .sm2-360btn:hover,
|
||||
.ui360 .sm2-360ui.sm2_dragging .sm2-360btn-playing:hover {
|
||||
/* don't let pause button show on hover when dragging (or paused and dragging) */
|
||||
background:transparent;
|
||||
cursor:auto;
|
||||
}
|
||||
|
||||
.ui360 .sm2-360ui.sm2_buffering .sm2-360btn,
|
||||
.ui360 .sm2-360ui.sm2_buffering .sm2-360btn:hover {
|
||||
background:transparent url(icon_loading_spinner.gif) no-repeat 50% 50%;
|
||||
opacity:0.5;
|
||||
visibility:visible;
|
||||
}
|
||||
|
||||
/* inline list style */
|
||||
|
||||
.sm2-inline-list .ui360,
|
||||
.sm2-inline-block .ui360 {
|
||||
position:relative;
|
||||
display:inline-block;
|
||||
float:left;
|
||||
_display:inline;
|
||||
margin-bottom:-15px;
|
||||
}
|
||||
|
||||
.sm2-inline-list .ui360 {
|
||||
margin-bottom:0px;
|
||||
}
|
||||
|
||||
.sm2-inline-block .ui360 {
|
||||
margin-right:8px;
|
||||
}
|
||||
|
||||
.sm2-inline-list .ui360 a {
|
||||
display:none;
|
||||
}
|
||||
|
||||
/* annotations */
|
||||
|
||||
ul.ui360playlist {
|
||||
list-style-type:none;
|
||||
}
|
||||
|
||||
ul.ui360playlist,
|
||||
ul.ui360playlist li {
|
||||
margin:0px;
|
||||
padding:0px;
|
||||
}
|
||||
|
||||
div.ui360 div.metadata {
|
||||
display:none;
|
||||
}
|
||||
|
||||
div.ui360 a span.metadata,
|
||||
div.ui360 a span.metadata * {
|
||||
/* name of track, note etc. */
|
||||
vertical-align:baseline;
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<title>360° MP3 player UI demo (SoundManager 2): Javascript + Canvas Visualization, basic example</title>
|
||||
<meta name="description" content="Basic example of 360-degree circular control for MP3 links, with EQ and spectrum visualization options" />
|
||||
<!-- demo: make the fonts nicer etc. -->
|
||||
<link rel="stylesheet" type="text/css" href="../index.css" />
|
||||
|
||||
<!-- soundManager.useFlashBlock: related CSS -->
|
||||
<link rel="stylesheet" type="text/css" href="../flashblock/flashblock.css" />
|
||||
|
||||
<!-- required -->
|
||||
<link rel="stylesheet" type="text/css" href="360player.css" />
|
||||
<link rel="stylesheet" type="text/css" href="360player-visualization.css" />
|
||||
|
||||
<!-- special IE-only canvas fix -->
|
||||
<!--[if IE]><script type="text/javascript" src="script/excanvas.js"></script><![endif]-->
|
||||
|
||||
<!-- Apache-licensed animation library -->
|
||||
<script type="text/javascript" src="script/berniecode-animator.js"></script>
|
||||
|
||||
<!-- the core stuff -->
|
||||
<script type="text/javascript" src="../../script/soundmanager2.js"></script>
|
||||
<script type="text/javascript" src="script/360player.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
soundManager.url = '../../swf/'; // path to directory containing SM2 SWF
|
||||
|
||||
soundManager.useFastPolling = true; // increased JS callback frequency, combined with useHighPerformance = true
|
||||
|
||||
threeSixtyPlayer.config.scaleFont = (navigator.userAgent.match(/msie/i)?false:true);
|
||||
threeSixtyPlayer.config.showHMSTime = true;
|
||||
|
||||
// enable some spectrum stuffs
|
||||
|
||||
threeSixtyPlayer.config.useWaveformData = true;
|
||||
threeSixtyPlayer.config.useEQData = true;
|
||||
|
||||
// enable this in SM2 as well, as needed
|
||||
|
||||
if (threeSixtyPlayer.config.useWaveformData) {
|
||||
soundManager.flash9Options.useWaveformData = true;
|
||||
}
|
||||
if (threeSixtyPlayer.config.useEQData) {
|
||||
soundManager.flash9Options.useEQData = true;
|
||||
}
|
||||
if (threeSixtyPlayer.config.usePeakData) {
|
||||
soundManager.flash9Options.usePeakData = true;
|
||||
}
|
||||
|
||||
// favicon is expensive CPU-wise, but can be enabled.
|
||||
threeSixtyPlayer.config.useFavIcon = false;
|
||||
|
||||
</script>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="demo.css" />
|
||||
<style type="text/css">
|
||||
|
||||
#left h2 {
|
||||
padding-top:0px;
|
||||
margin-bottom:0.25em;
|
||||
color:#666;
|
||||
}
|
||||
|
||||
pre.block {
|
||||
margin-top:0.5em;
|
||||
}
|
||||
|
||||
/* special case */
|
||||
|
||||
#left {
|
||||
width:auto;
|
||||
max-width:100%;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="left">
|
||||
|
||||
<h1><a href="http://schillmania.com/projects/soundmanager2/demo/360-player/">360° Player Demo</a> - Visualization Example, Basic Template</h1>
|
||||
|
||||
<p class="note" style="color:#666;margin-bottom:0.5em">Canvas-based UI with visualization options. <b>Note: No EQ/spectrum support for IE (too slow.) Data not available in HTML5.</b></p>
|
||||
|
||||
<div style="clear:left"></div>
|
||||
|
||||
<div id="sm2-container">
|
||||
<!-- sm2 flash goes here -->
|
||||
</div>
|
||||
|
||||
<!-- here are the MP3 links, which are decorated with the 360 canvas element/UI etc. -->
|
||||
|
||||
<h2 style="margin-top:1em">Inline list</h2>
|
||||
|
||||
<div class="sm2-inline-list"> <!-- remove this class to have one item per line -->
|
||||
|
||||
<div class="ui360"><a href="../../demo/mpc/audio/CRASH_1.mp3">Crash 1</a></div>
|
||||
<div class="ui360"><a href="../../demo/mpc/audio/CRASH_5.mp3">Crash 5</a></div>
|
||||
<div class="ui360"><a href="../../demo/mpc/audio/CRASH_6.mp3">Crash 6</a></div>
|
||||
<div class="ui360"><a href="../../demo/mpc/audio/CHINA_1.mp3">China 1</a></div>
|
||||
|
||||
</div>
|
||||
|
||||
<h2 style="clear:both;padding-top:1em">Block list</h2>
|
||||
|
||||
<div>
|
||||
<div class="ui360"><a href="../../demo/_mp3/sine,%20square,%20sawtooth,%20rando.mp3">Sine, Square, Sawtooth, Wave (Warning: LOUD)</a></div>
|
||||
<div class="ui360"><a href="../../demo/_mp3/1hz-10khz-sweep.mp3">1-10 Khz Sweep (Warning: LOUD)</a></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<p style="margin-left:1em">
|
||||
<a href="http://www.schillmania.com/projects/soundmanager2/" title="SoundManager 2 home">SoundManager 2 project page</a> (not an MP3 link)
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
334
js/libs/soundmanager/demo/360-player/canvas-visualization.html
Normal file
|
@ -0,0 +1,334 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<title>360° MP3 player UI demo (SoundManager 2): Javascript + Canvas Visualization</title>
|
||||
<meta name="description" content="Javascript + Canvas + SoundManager 2: 360-degree circular control / jog wheel example for playing MP3 links, with EQ and spectrum visualization options" />
|
||||
<!-- demo, make the fonts nicer etc. -->
|
||||
<link rel="stylesheet" type="text/css" href="../index.css" />
|
||||
|
||||
<!-- soundManager.useFlashBlock: related CSS -->
|
||||
<link rel="stylesheet" type="text/css" href="../flashblock/flashblock.css" />
|
||||
|
||||
<!-- required -->
|
||||
<link rel="stylesheet" type="text/css" href="360player.css" />
|
||||
<link rel="stylesheet" type="text/css" href="360player-visualization.css" />
|
||||
|
||||
<!-- special IE-only canvas fix -->
|
||||
<!--[if IE]><script type="text/javascript" src="script/excanvas.js"></script><![endif]-->
|
||||
|
||||
<!-- Apache-licensed animation library -->
|
||||
<script type="text/javascript" src="script/berniecode-animator.js"></script>
|
||||
|
||||
<!-- the core stuff -->
|
||||
<script type="text/javascript" src="../../script/soundmanager2.js"></script>
|
||||
<script type="text/javascript" src="script/360player.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
soundManager.url = '../../swf/'; // path to directory containing SM2 SWF
|
||||
|
||||
soundManager.useFastPolling = true; // increased JS callback frequency, combined with useHighPerformance = true
|
||||
|
||||
threeSixtyPlayer.config.scaleFont = (navigator.userAgent.match(/msie/i)?false:true);
|
||||
threeSixtyPlayer.config.showHMSTime = true;
|
||||
|
||||
// enable some spectrum stuffs
|
||||
|
||||
threeSixtyPlayer.config.useWaveformData = true;
|
||||
threeSixtyPlayer.config.useEQData = true;
|
||||
|
||||
// enable this in SM2 as well, as needed
|
||||
|
||||
if (threeSixtyPlayer.config.useWaveformData) {
|
||||
soundManager.flash9Options.useWaveformData = true;
|
||||
}
|
||||
if (threeSixtyPlayer.config.useEQData) {
|
||||
soundManager.flash9Options.useEQData = true;
|
||||
}
|
||||
if (threeSixtyPlayer.config.usePeakData) {
|
||||
soundManager.flash9Options.usePeakData = true;
|
||||
}
|
||||
|
||||
// favicon is expensive CPU-wise, but can be used.
|
||||
if (window.location.href.match(/hifi/i)) {
|
||||
threeSixtyPlayer.config.useFavIcon = true;
|
||||
}
|
||||
|
||||
if (window.location.href.match(/html5/i)) {
|
||||
// for testing IE 9, etc.
|
||||
soundManager.useHTML5Audio = true;
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<!-- DEMO only, customization UI: Yahoo! YUI colorpicker stuff -->
|
||||
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.7.0/build/slider/assets/skins/sam/slider.css" />
|
||||
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.7.0/build/colorpicker/assets/skins/sam/colorpicker.css" />
|
||||
<script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/yahoo-dom-event/yahoo-dom-event.js"></script>
|
||||
<script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/animation/animation-min.js"></script>
|
||||
<script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/dragdrop/dragdrop-min.js"></script>
|
||||
<script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/slider/slider-min.js"></script>
|
||||
<script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/element/element-min.js"></script>
|
||||
<script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/colorpicker/colorpicker-min.js"></script>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="demo.css" />
|
||||
<style type="text/css">
|
||||
|
||||
#left h2 {
|
||||
padding-top:0px;
|
||||
margin-bottom:0.25em;
|
||||
color:#666;
|
||||
}
|
||||
|
||||
pre.block {
|
||||
margin-top:0.5em;
|
||||
}
|
||||
|
||||
/* special case */
|
||||
|
||||
#left {
|
||||
width:auto;
|
||||
max-width:100%;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<!-- demo configuration stuff, you don't need this -->
|
||||
<link rel="stylesheet" type="text/css" href="demo-slider-controls.css" />
|
||||
<script type="text/javascript" src="demo-slider-controls.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="left">
|
||||
|
||||
<h1><a href="http://www.schillmania.com/projects/soundmanager2/" title="Javascript MP3 player project home">SoundManager 2</a> / <a href="http://schillmania.com/projects/soundmanager2/demo/360-player/">360° Player Demo</a>: JS + Canvas Visualization</h1>
|
||||
|
||||
<p class="note" style="color:#666;margin-bottom:0.5em">Canvas-based UI with visualization options. <b>Note: Spectrum/EQ visualizations disabled for IE (too slow.) Data is not currently available under HTML5.</b></p>
|
||||
<p class="note" style="color:#666;margin-bottom:0.5em">You can also <a href="#debug=1" onclick="window.location.href = this.href;window.location.reload()" title="Enable debug mode, show frames per second">show FPS</a><span id="config-link"> or <a href="#customize" onclick="window.location.href=this.href;window.location.reload()">customize the UI</a></span><span id="hifi">, or see the <a href="#hifi=1" onclick="window.location.href=this.href;window.location.reload()">hi-fi version</a></span>. Check the <a href="canvas-visualization-basic.html">basic template</a> for a minimal code example; also see the <a href="../360-player/" title="360° player UI">default 360° UI</a>.</p>
|
||||
|
||||
<!-- customization crap -->
|
||||
|
||||
<div id="config-ui" style="clear:both;position:relative;max-width:1110px;margin-top:1em;display:none">
|
||||
|
||||
<div style="position:relative">
|
||||
|
||||
<form action="#" method="get">
|
||||
|
||||
<div id="controls">
|
||||
|
||||
<div class="checkbox">
|
||||
<div>
|
||||
<input id="use-waveform" type="checkbox" checked="checked" title="Enable waveform feature." onclick="controller.updateExample();controller.updateExampleCode()" value="Apply" /> Waveform
|
||||
<input id="disabled-1" type="checkbox" title="Enable EQ (spectrum) feature." onclick="controller.updateExample();controller.updateExampleCode()" value="Apply" style="margin-left:1em" checked="checked" /> EQ
|
||||
<input type="checkbox" name="use-amplifier" id="use-amplifier" checked="checked" onclick="controller.updateExample();controller.updateExampleCode()" style="margin-left:1em"> Amplifier
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="clear:left"></div>
|
||||
|
||||
<dl class="col">
|
||||
|
||||
<dt>Circle Diameter</dt>
|
||||
<dd class="title">Size</dd>
|
||||
<dd>1-256</dd>
|
||||
<dd class="control">
|
||||
<div class="bar" title="Click to move here"></div>
|
||||
<div class="slider" title="Size of circle"></div>
|
||||
</dd>
|
||||
|
||||
<dt>Waveform Thickness</dt>
|
||||
<dd class="title">thickness</dd>
|
||||
<dd>1-100</dd>
|
||||
<dd class="control">
|
||||
<div class="bar" title="Click to move here"></div>
|
||||
<div class="slider" title="Thickness of line"></div>
|
||||
</dd>
|
||||
|
||||
<dt>Wave Downsample</dt>
|
||||
<dd class="title">(Scale)</dd>
|
||||
<dd>1-16</dd>
|
||||
<dd class="control">
|
||||
<div class="bar" title="Click to move here"></div>
|
||||
<div class="slider" title="Primary (inner circle) colour"></div>
|
||||
</dd>
|
||||
|
||||
<dt>EQ Thickness</dt>
|
||||
<dd class="title">thickness</dd>
|
||||
<dd>1-50</dd>
|
||||
<dd class="control">
|
||||
<div class="bar" title="Click to move here"></div>
|
||||
<div class="slider" title="Thickness of line"></div>
|
||||
</dd>
|
||||
|
||||
<dt>EQ Downsample</dt>
|
||||
<dd class="title">(Scale)</dd>
|
||||
<dd>1-16</dd>
|
||||
<dd class="control">
|
||||
<div class="bar" title="Click to move here"></div>
|
||||
<div class="slider" title="Primary (inner circle) colour"></div>
|
||||
</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
<div id="options" class="col">
|
||||
|
||||
<div>
|
||||
Waveform position:
|
||||
<input type="radio" name="waveform-inside" id="waveform-inside" value="true" checked="checked" onclick="controller.updateExample();controller.updateExampleCode()"> Inside | <input type="radio" name="waveform-inside" id="waveform-inside" value="false" onclick="controller.updateExample();controller.updateExampleCode()"> Outside
|
||||
</div>
|
||||
|
||||
<div>
|
||||
EQ position:
|
||||
<input type="radio" name="eq-inside" id="eq-inside" value="true" onclick="controller.updateExample();controller.updateExampleCode()"> Inside | <input type="radio" name="eq-inside" id="eq-inside" value="false" checked="checked" onclick="controller.updateExample();controller.updateExampleCode()"> Outside
|
||||
</div>
|
||||
|
||||
<div>
|
||||
Waveform color:
|
||||
<input type="text" name="waveform-color" id="waveform-color" value="#000000" onclick="createCP(this,setWaveformColor)" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
EQ color:
|
||||
<input type="text" name="eq-color" id="eq-color" value="#000000" onclick="createCP(this,setEQColor)" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
Loaded ring color:
|
||||
<input type="text" name="loaded-ring-color" id="loaded-ring-color" value="#000000" onclick="createCP(this,setLoadedRingColor)" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
Progress ring color:
|
||||
<input type="text" name="progress-ring-color" id="progress-ring-color" value="#000000" onclick="createCP(this,setProgressRingColor)" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
Background ring color:
|
||||
<input type="text" name="bg-ring-color" id="bg-ring-color" value="#000000" onclick="createCP(this,setBackgroundRingColor)" />
|
||||
</div>
|
||||
|
||||
<p class="compact">
|
||||
<input type="button" onclick="controller.randomize()" value="Randomize controls" title="Assign random control values" style="font-size:x-small" />
|
||||
</p>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="cp-container">
|
||||
<!-- color picker stuff goes here -->
|
||||
</div>
|
||||
|
||||
<div id="config-code-block" style="float:right;display:inline;margin-left:1em;margin-top:-0.7em">
|
||||
<!--
|
||||
<pre id="config-link" class="block"><code style="cursor:pointer" onclick="document.getElementById('config-link').style.display='none';document.getElementById('config-pre-block').style.display='block';return false"> [click to show code] </code></pre>
|
||||
-->
|
||||
<pre id="config-pre-block" class="block"><code id="config-code">Code goes here</code></pre>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<p style="clear:left">Get a sound playing, then adjust the values to see real-time updates.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- here are the MP3 links, which are decorated with the 360 canvas element/UI etc. -->
|
||||
|
||||
<div id="sm2-container">
|
||||
<!-- sm2 flash goes here -->
|
||||
</div>
|
||||
|
||||
<h2 style="margin-top:1em">Inline list</h2>
|
||||
|
||||
<div class="sm2-inline-list"> <!-- remove this class to have one item per line -->
|
||||
|
||||
<div class="ui360"><a href="http://freshly-ground.com/data/audio/sm2/Adrian%20Glynn%20-%20Blue%20Belle%20Lament.mp3">Adrian Glynn - Blue Belle Lament</a></div>
|
||||
<div class="ui360"><a href="http://freshly-ground.com/data/audio/sm2/SonReal%20-%20I%20Tried.mp3">SonReal - I Tried</a></div>
|
||||
<div class="ui360"><a href="http://freshly-ground.com/data/audio/sm2/SonReal%20-%20People%20Asking.mp3">SonReal - People Asking</a></div>
|
||||
<div class="ui360"><a href="http://freshly-ground.com/data/audio/mpc/20060826%20-%20Armstrong.mp3">20060826 - Armstrong Groove</a></div>
|
||||
|
||||
</div>
|
||||
|
||||
<p class="note medium-note" style="clear:both"><b>Artist thank-yous</b>: "Blue Belle Lament" courtesy of <a href="http://www.adrianglynn.com/" title="Adrian Glynn, Vancouver-based Singer/Songwriter">Adrian Glynn</a>. "I Tried" and "People Asking" courtesy of <a href="http://sonreal.bandcamp.com/album/the-lightyear-mixtape" title="The Lightyear Mixtape from SonReal, Vancouver-based hip-hop artist">SonReal</a>.</p>
|
||||
|
||||
<h2 style="clear:left;padding-top:1em">Block list</h2>
|
||||
|
||||
<div>
|
||||
<div class="ui360"><a href="http://freshly-ground.com/data/audio/mpc/20090207%20-%20Loverman.mp3">20090207 - Loverman</a></div>
|
||||
<div class="ui360"><a href="../../demo/_mp3/1hz-10khz-sweep.mp3">1-10 Khz Sweep (Warning: <span style="color:#ff3333">LOUD</span>)</a></div>
|
||||
<div class="ui360"><a href="../../demo/_mp3/sine,%20square,%20sawtooth,%20rando.mp3">Sine, Square, Sawtooth, Wave (Warning: <span style="color:#ff3333">LOUD</span>)</a></div>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="clear:left"></div>
|
||||
|
||||
<h2 style="clear:left;padding-top:1em">Variant: Annotations/meta-data</h2>
|
||||
|
||||
|
||||
<ul class="ui360playlist">
|
||||
|
||||
<li>
|
||||
|
||||
<div class="ui360">
|
||||
<a href="http://freshly-ground.com/data/audio/binaural/A%20Virtual%20Haircut%20in%20San%20Francisco%20%283%20Scenes%29.mp3">A Virtual Haircut (3 scenes)</a>
|
||||
<div class="metadata">
|
||||
<div class="duration">4:43</div> <!-- total track time (for positioning while loading, until determined -->
|
||||
<ul>
|
||||
<li><p>Electric razor</p><span>0:00</span></li> <!-- first scene -->
|
||||
<li><p>Water, scissors</p><span>2:41</span></li> <!-- start time of second scene -->
|
||||
<li><p>More razor work</p><span>4:00</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="ui360">
|
||||
<a href="http://freshly-ground.com/data/audio/binaural/Rubber%20Chicken%20Launch%20%28office%29.mp3">Rubber Chicken Launch (Office)</a>
|
||||
|
||||
<div class="metadata">
|
||||
<div class="duration">0:47</div>
|
||||
<ul>
|
||||
<li><p>First attempt</p><span>0:00</span></li>
|
||||
<li><p>Fire!</p><span>0:02</span></li>
|
||||
<li><p>"Too much angle"</p><span>0:05</span></li>
|
||||
<li><p>Random chicken noise</p><span>0:18</span></li>
|
||||
<li><p>"Wait a second"</p><span>0:31</span></li>
|
||||
<li><p>Derrr..</p><span>0:34</span></li>
|
||||
<li><p>Launch attempt #2</p><span>0:36</span></li>
|
||||
<li><p>"Wrong angle"</p><span>0:39</span></li>
|
||||
<li><p>"Fail"</p><span>0:42</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<div style="clear:both"></div>
|
||||
|
||||
<p style="margin-left:1em">
|
||||
<a href="http://www.schillmania.com/projects/soundmanager2/" title="SoundManager 2 home">SoundManager 2 project page</a> (not an MP3 link)
|
||||
</p>
|
||||
|
||||
<script type="text/javascript">
|
||||
if (window.location.toString().match(/#customize/i)) {
|
||||
document.getElementById('config-link').style.display = 'none';
|
||||
document.getElementById('config-ui').style.display = 'block';
|
||||
}
|
||||
</script>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
179
js/libs/soundmanager/demo/360-player/demo-slider-controls.css
Normal file
|
@ -0,0 +1,179 @@
|
|||
#cp-container { position:relative;float:left;display:inline; margin-left:1em;padding: 6px; background-color: #f6f6f6; border:1px solid #eee; width: 320px; height:180px;z-index:2; }
|
||||
|
||||
.yui-picker-controls li,
|
||||
.yui-picker-controls input {
|
||||
font-size:1em;
|
||||
font-family:"helvetica neue",helvetica,arial,verdana;
|
||||
}
|
||||
|
||||
#controls {
|
||||
position:relative;
|
||||
margin-top:1.5em;
|
||||
font-size:0.85em;
|
||||
}
|
||||
|
||||
#options {
|
||||
float:left;
|
||||
display:inline;
|
||||
margin-bottom:0.5em;
|
||||
margin-top:-1.2em;
|
||||
}
|
||||
|
||||
#controls .checkbox {
|
||||
float:left;
|
||||
display:inline;
|
||||
width:21.2em;
|
||||
margin-right:2.5em;
|
||||
}
|
||||
|
||||
#controls .checkbox div {
|
||||
/* tab */
|
||||
width:auto;
|
||||
padding:0.4em;
|
||||
border:1px solid #ddd;
|
||||
border-bottom:none;
|
||||
background:#eee;
|
||||
}
|
||||
|
||||
#controls .checkbox div,
|
||||
#controls .checkbox input {
|
||||
font-family:arial,tahoma,verdana,"sans serif";
|
||||
font-size:1em;
|
||||
vertical-align:middle;
|
||||
}
|
||||
|
||||
#controls dl {
|
||||
width:21em;
|
||||
}
|
||||
|
||||
#controls dl.col {
|
||||
position:relative;
|
||||
float:left;
|
||||
display:inline;
|
||||
margin:0px;
|
||||
margin-right:1em;
|
||||
padding:0.75em;
|
||||
/*
|
||||
height:12.4em;
|
||||
*/
|
||||
height:auto;
|
||||
border:1px solid #ddd;
|
||||
background:#f6f6f6;
|
||||
}
|
||||
|
||||
#controls .disabled {
|
||||
color:#ccc;
|
||||
}
|
||||
|
||||
#controls .disabled dt,
|
||||
#controls .disabled dd {
|
||||
color:#999;
|
||||
opacity:0.5;
|
||||
}
|
||||
|
||||
#controls dl dd p {
|
||||
margin:0px;
|
||||
padding:0px;
|
||||
}
|
||||
|
||||
#controls dt,
|
||||
#controls dd {
|
||||
margin:0px;
|
||||
padding:0px;
|
||||
}
|
||||
|
||||
#controls dt {
|
||||
border-bottom:none;
|
||||
}
|
||||
|
||||
#controls dt {
|
||||
float:left;
|
||||
display:inline;
|
||||
background:transparent;
|
||||
padding-right:0.7em;
|
||||
margin-right:0.7em;
|
||||
border-right:1px solid #ccc;
|
||||
font-size:1.1em;
|
||||
color:#333;
|
||||
font-family:"helvetica neue",helvetica,verdana,arial,"sans serif";
|
||||
}
|
||||
|
||||
#controls dd {
|
||||
margin:0px;
|
||||
padding:0px;
|
||||
font-size:0.9em;
|
||||
vertical-align:middle;
|
||||
color:#666;
|
||||
}
|
||||
|
||||
#controls .title {
|
||||
float:left;
|
||||
display:inline;
|
||||
margin-right:0.6em;
|
||||
color:#333;
|
||||
}
|
||||
|
||||
/* those slider bits you might be wondering about */
|
||||
|
||||
#controls .control {
|
||||
position:relative;
|
||||
border-left:0px;
|
||||
width:214px;
|
||||
height:20px;
|
||||
}
|
||||
|
||||
#controls .control .bar {
|
||||
position:absolute;
|
||||
left:0px;
|
||||
top:0px;
|
||||
width:214px;
|
||||
height:20px;
|
||||
background:transparent url(../_image/slider-bar.gif) no-repeat 0px 9px;
|
||||
cursor:pointer;
|
||||
cursor:hand;
|
||||
}
|
||||
|
||||
#controls .control .slider {
|
||||
position:absolute;
|
||||
left:0px;
|
||||
top:0px;
|
||||
width:20px;
|
||||
height:20px;
|
||||
background:transparent url(../_image/slider.png) no-repeat 0px 0px;
|
||||
*background:none;
|
||||
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop,src='../_image/slider.png');
|
||||
cursor:pointer;
|
||||
cursor:hand;
|
||||
}
|
||||
|
||||
#controls .control .slider:hover {
|
||||
background:transparent url(../_image/slider-1.png) no-repeat 0px 0px;
|
||||
*background:none;
|
||||
}
|
||||
|
||||
#controls .control .slider.hover {
|
||||
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop,src='../_image/slider-1.png');
|
||||
}
|
||||
|
||||
#controls .disabled .control .slider {
|
||||
background:transparent url(../_image/slider-disabled.png) no-repeat 0px 0px;
|
||||
*background:none;
|
||||
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop,src='../_image/slider-disabled.png');
|
||||
}
|
||||
|
||||
#controls .disabled .control .slider:hover {
|
||||
background:transparent url(../_image/slider-disabled-1.png) no-repeat 0px 0px;
|
||||
*background:none;
|
||||
}
|
||||
|
||||
#controls .disabled .control .slider.hover {
|
||||
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop,src='../_image/slider-disabled-1.png');
|
||||
}
|
||||
|
||||
#controls input[type=text] {
|
||||
width:5em;
|
||||
}
|
||||
|
||||
#options div {
|
||||
margin-bottom:0.25em;
|
||||
}
|
714
js/libs/soundmanager/demo/360-player/demo-slider-controls.js
Normal file
|
@ -0,0 +1,714 @@
|
|||
/*
|
||||
Ancient fireworks slider control code (2005)
|
||||
http://schillmania.com/projects/fireworks/
|
||||
--------------------------------------------
|
||||
Not required for your use!
|
||||
*/
|
||||
|
||||
function Animator2() {
|
||||
var self = this;
|
||||
this.tweens = [];
|
||||
this.tweens['default'] = [1,2,3,4,5,6,7,8,9,10,9,8,7,6,5,4,3,2,1];
|
||||
this.tweens['blast'] = [12,12,11,10,10,9,8,7,6,5,4,3,2,1];
|
||||
this.tweens['fade'] = [10,10,10,10,10,10,10,10,10,10];
|
||||
this.queue = [];
|
||||
this.queue.IDs = [];
|
||||
this.active = false;
|
||||
this.timer = null;
|
||||
|
||||
this.createTween = function(start,end,type) {
|
||||
// return array of tween coordinate data (start->end)
|
||||
type = type||'default';
|
||||
var tween = [start];
|
||||
var tmp = start;
|
||||
var diff = end-start;
|
||||
var x = self.tweens[type].length;
|
||||
for (var i=0; i<x; i++) {
|
||||
tmp += diff*self.tweens[type][i]*0.01;
|
||||
tween[i] = new Object();
|
||||
tween[i].data = tmp;
|
||||
tween[i].event = null;
|
||||
}
|
||||
return tween;
|
||||
}
|
||||
|
||||
this.enqueue = function(o,fMethod,fOnComplete) {
|
||||
// add object and associated methods to animation queue
|
||||
// writeDebug('animator.enqueue()');
|
||||
if (!fMethod) {
|
||||
// writeDebug('animator.enqueue(): missing fMethod');
|
||||
}
|
||||
if (typeof(self.queue.IDs[o.oID])=='undefined') {
|
||||
// writeDebug('animator.enqueue(): added '+o.oID);
|
||||
var i = self.queue.length;
|
||||
self.queue.IDs[o.oID] = i;
|
||||
self.queue[i] = o;
|
||||
} else {
|
||||
// writeDebug('animator.enqueue(): '+o.oID+' already queued');
|
||||
var i = self.queue.IDs[o.oID]; // retrieve queue index
|
||||
self.queue[i].active = true;
|
||||
self.queue[i].frame = 0;
|
||||
}
|
||||
o.active = true; // flag for animation
|
||||
self.queue[i]._method = fMethod;
|
||||
self.queue[i]._oncomplete = fOnComplete?fOnComplete:null;
|
||||
}
|
||||
|
||||
this.animate = function() {
|
||||
var active = 0;
|
||||
for (var i=self.queue.length; i--;) {
|
||||
if (self.queue[i].active) {
|
||||
self.queue[i]._method();
|
||||
active++;
|
||||
}
|
||||
}
|
||||
if (active==0 && self.timer) {
|
||||
// all animations finished
|
||||
self.stop();
|
||||
} else {
|
||||
// writeDebug(active+' active');
|
||||
}
|
||||
}
|
||||
|
||||
this.start = function() {
|
||||
if (self.timer || self.active) {
|
||||
// writeDebug('animator.start(): already active');
|
||||
return false;
|
||||
}
|
||||
// writeDebug('animator.start()'); // report only if started
|
||||
self.active = true;
|
||||
self.timer = setInterval(self.animate,mc.intervalRate);
|
||||
}
|
||||
|
||||
this.stop = function() {
|
||||
// writeDebug('animator.stop()',true);
|
||||
clearInterval(self.timer);
|
||||
self.timer = null;
|
||||
self.active = false;
|
||||
self.queue = [];
|
||||
self.queue.IDs = [];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function MainController() {
|
||||
var self = this;
|
||||
this.intervalRate = 20; // rate (ms) to run animation at, general best default = 20
|
||||
this.DEBUG = true; // debug mode disabled by default
|
||||
this.oFW = null;
|
||||
this.isIE = (navigator.appVersion.indexOf('MSIE')+1);
|
||||
this.isOpera = (navigator.userAgent.toLowerCase().indexOf('opera')+1);
|
||||
if (this.isOpera) this.isIE = false; // no impersonation allowed here!
|
||||
this.animator = null;
|
||||
this.gOID = 0; // global object ID counter (for animation queue)
|
||||
this.particleTypes = 6;
|
||||
this.particleXY = 10;
|
||||
this.tweenFade = [100,90,80,70,60,50,40,30,20,10,0];
|
||||
this.isSafari = (navigator.appVersion.toLowerCase().indexOf('safari')+1?1:0);
|
||||
this.canvasX = null;
|
||||
this.canvasY = null;
|
||||
this.screenY = null; // screen area (not entire page)
|
||||
self.scrollY = null;
|
||||
|
||||
self.getWindowCoords = function() {
|
||||
self.canvasX = (document.documentElement.clientWidth||document.body.clientWidth||document.body.scrollWidth);
|
||||
self.canvasY = (document.documentElement.clientHeight||document.body.clientHeight||document.body.scrollHeight);
|
||||
self.screenY = self.canvasY;
|
||||
self.scrollY = parseInt(window.scrollY||document.documentElement.scrollTop||document.body.scrollTop);
|
||||
self.canvasY += self.scrollY;
|
||||
}
|
||||
|
||||
this.getWindowCoordsAlt = function() {
|
||||
self.canvasX = window.innerWidth;
|
||||
self.canvasY = window.innerHeight;
|
||||
self.screenY = self.canvasY;
|
||||
self.scrollY = parseInt(window.scrollY||document.documentElement.scrollTop||document.body.scrollTop);
|
||||
self.canvasY += self.scrollY;
|
||||
}
|
||||
|
||||
this.getPanX = function(x) {
|
||||
x = parseInt(x);
|
||||
var pos = x/self.canvasX;
|
||||
if (pos<0.4) {
|
||||
pos *= -1;
|
||||
} else if (pos >= 0.4 && pos <= 0.6) {
|
||||
pos = 0.5;
|
||||
}
|
||||
pos = parseInt(pos*100);
|
||||
// writeDebug('getPanX('+x+'): '+pos+'%');
|
||||
return pos;
|
||||
}
|
||||
|
||||
this.isEmpty = function(o) {
|
||||
// needs further hacking
|
||||
return (typeof(o)=='undefined'||(o==null&&o!=0)||(o==''&&o!=0)||o=='null');
|
||||
}
|
||||
|
||||
this.init = function() {
|
||||
// self.oFW = document.getElementById('fw');
|
||||
// self.oFP = document.getElementById('fp');
|
||||
// if (typeof(enableDebugMode)!='undefined' && (self.DEBUG||window.location.toString().toLowerCase().indexOf('debug')>=0)) enableDebugMode();
|
||||
self.getWindowCoords();
|
||||
self.animator = new Animator2();
|
||||
}
|
||||
|
||||
this.destructor = function() {
|
||||
/*
|
||||
for (var i=self.fireworks.length; i--;) {
|
||||
self.fireworks[i] = null;
|
||||
}
|
||||
self.fireworks = null;
|
||||
if (soundManager) {
|
||||
soundManager.destructor();
|
||||
soundManager = null;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
if (this.isSafari || this.isOpera) this.getWindowCoords = this.getWindowCoordsAlt;
|
||||
|
||||
}
|
||||
|
||||
|
||||
function Controller(o) {
|
||||
var self = this;
|
||||
this.o = o;
|
||||
this.controls = [];
|
||||
this.cb = [];
|
||||
this.options = [];
|
||||
this.functionExample = document.getElementById('function-example');
|
||||
this.fbIE = null;
|
||||
|
||||
this.randomize = function() {
|
||||
for (var i=1; i<self.controls.length; i++) {
|
||||
setTimeout(self.controls[i].randomize,20+(20*i+1));
|
||||
}
|
||||
}
|
||||
|
||||
this.cbClick = function(nIndex) {
|
||||
document.getElementById('controls').getElementsByTagName('dl')[nIndex].className = 'col'+(this.checked==false||this.checked==''?' disabled':'');
|
||||
self.updateExample();
|
||||
self.updateExampleCode();
|
||||
}
|
||||
|
||||
this.updateExample = function() {
|
||||
if (threeSixtyPlayer) {
|
||||
var val = self.controls[0].value;
|
||||
threeSixtyPlayer.config.circleDiameter = self.controls[0].value;
|
||||
threeSixtyPlayer.config.circleRadius = self.controls[0].value/2;
|
||||
// update some stuff
|
||||
|
||||
// set the cover width/height to match the canvas
|
||||
if (threeSixtyPlayer.lastSound) {
|
||||
// always set cover to max area?
|
||||
// threeSixtyPlayer.lastSound._data.oCover.style.width = 250+'px';
|
||||
// threeSixtyPlayer.lastSound._data.oCover.style.height = 250+'px';
|
||||
// threeSixtyPlayer.lastSound._data.oCover.style.width = threeSixtyPlayer.config.circleDiameter+'px';
|
||||
// threeSixtyPlayer.lastSound._data.oCover.style.height = threeSixtyPlayer.config.circleDiameter+'px';
|
||||
threeSixtyPlayer.refreshCoords(threeSixtyPlayer.lastSound);
|
||||
}
|
||||
|
||||
threeSixtyPlayer.config.waveformDataLineRatio = (self.controls[1].value/100)*2;
|
||||
|
||||
threeSixtyPlayer.config.waveformDataDownsample = (self.controls[2].value);
|
||||
|
||||
threeSixtyPlayer.config.eqDataLineRatio = parseInt((self.controls[3].value/100)*3*1000)/1000;
|
||||
|
||||
threeSixtyPlayer.config.eqDataDownsample = (self.controls[4].value);
|
||||
|
||||
threeSixtyPlayer.config.useEQData = (document.getElementById('disabled-1').checked?true:false);
|
||||
|
||||
// radio buttons
|
||||
|
||||
threeSixtyPlayer.config.useWaveformData=(document.getElementById('use-waveform').checked?true:false);
|
||||
|
||||
threeSixtyPlayer.config.waveformDataOutside = document.getElementById('waveform-inside').checked?false:true;
|
||||
|
||||
threeSixtyPlayer.config.eqDataOutside = document.getElementById('eq-inside').checked?false:true;
|
||||
|
||||
threeSixtyPlayer.config.useAmplifier = (document.getElementById('use-amplifier').checked?true:false);
|
||||
|
||||
// threeSixtyPlayer.refreshCoords();
|
||||
}
|
||||
}
|
||||
|
||||
this.updateExampleCode = function() {
|
||||
// set innerHTML
|
||||
document.getElementById('config-code').innerHTML = "\
|
||||
// 360player.js, config section\n\
|
||||
\n\
|
||||
this.config = {\n\
|
||||
\n\
|
||||
playNext: <span>"+threeSixtyPlayer.config.playNext+"</span>,\n\
|
||||
autoPlay: <span>"+threeSixtyPlayer.config.autoPlay+"</span>,\n\
|
||||
allowMultiple: <span>"+threeSixtyPlayer.config.allowMultiple+"</span>,\n\
|
||||
loadRingColor: <span>'"+threeSixtyPlayer.config.loadRingColor+"'</span>,\n\
|
||||
playRingColor: <span>'"+threeSixtyPlayer.config.playRingColor+"'</span>,\n\
|
||||
backgroundRingColor: <span>'"+threeSixtyPlayer.config.backgroundRingColor+"'</span>,\n\
|
||||
circleDiameter: <span>"+threeSixtyPlayer.config.circleDiameter+"</span>,\n\
|
||||
circleRadius: <span>"+threeSixtyPlayer.config.circleRadius+"</span>,\n\
|
||||
imageRoot: <span>'"+threeSixtyPlayer.config.imageRoot+"'</span>,\n\
|
||||
animDuration: <span>"+threeSixtyPlayer.config.animDuration+"</span>,\n\
|
||||
animTransition: <span>Animator.tx.bouncy</span>,\n\
|
||||
showHMSTime: <span>"+threeSixtyPlayer.config.showHMSTime+"</span>,\n\
|
||||
\n\
|
||||
useWaveformData: <span>"+threeSixtyPlayer.config.useWaveformData+"</span>,\n\
|
||||
waveformDataColor: <span>'"+threeSixtyPlayer.config.waveformDataColor+"'</span>,\n\
|
||||
waveformDataDownsample: <span>"+threeSixtyPlayer.config.waveformDataDownsample+"</span>,\n\
|
||||
waveformDataOutside: <span>"+threeSixtyPlayer.config.waveformDataOutside+"</span>,\n\
|
||||
waveformDataConstrain: <span>false</span>,\n\
|
||||
waveformDataLineRatio: <span>"+threeSixtyPlayer.config.waveformDataLineRatio+"</span>,\n\
|
||||
\n\
|
||||
useEQData: <span>"+threeSixtyPlayer.config.useEQData+"</span>,\n\
|
||||
eqDataColor: <span>'"+threeSixtyPlayer.config.eqDataColor+"'</span>,\n\
|
||||
eqDataDownsample: <span>"+threeSixtyPlayer.config.eqDataDownsample+"</span>,\n\
|
||||
eqDataOutside: <span>"+threeSixtyPlayer.config.eqDataOutside+"</span>,\n\
|
||||
eqDataLineRatio: <span>"+threeSixtyPlayer.config.eqDataLineRatio+"</span>,\n\
|
||||
\n\
|
||||
usePeakData: <span>"+threeSixtyPlayer.config.usePeakData+"</span>,\n\
|
||||
peakDataColor: <span>'"+threeSixtyPlayer.config.peakDataColor+"'</span>,\n\
|
||||
peakDataOutside: <span>"+threeSixtyPlayer.config.peakDataOutside+"</span>,\n\
|
||||
peakDataLineRatio: <span>"+threeSixtyPlayer.config.peakDataLineRatio+"</span>,\n\
|
||||
\n\
|
||||
useAmplifier: <span>"+threeSixtyPlayer.config.useAmplifier+"</span>\n\
|
||||
\n\
|
||||
}";
|
||||
document.getElementById('config-code').style.display = 'block'; // weird Fx fix
|
||||
}
|
||||
|
||||
this.createCustomFirework = function() {
|
||||
}
|
||||
|
||||
this.destructor = function() {
|
||||
for (var i=self.controls.length; i--;) {
|
||||
self.controls[i].destructor();
|
||||
}
|
||||
for (i=self.cb.length; i--;) {
|
||||
self.cb.onclick = null;
|
||||
self.cb[i] = null;
|
||||
}
|
||||
for (i=self.options.length; i--;) {
|
||||
self.options[i] = null;
|
||||
}
|
||||
if (navigator.userAgent.match(/msie/i)) {
|
||||
self.fbIE.onmouseover = null;
|
||||
self.fbIE.onmouseout = null;
|
||||
self.fbIE = null;
|
||||
}
|
||||
self.cb = null;
|
||||
self.options = null;
|
||||
self.controls = null;
|
||||
self.functionExample = null;
|
||||
self.o = null;
|
||||
}
|
||||
|
||||
var items = parseInt(this.o.length/3);
|
||||
for (var i=0; i<items; i++) {
|
||||
this.controls[this.controls.length] = new Slider(this.o[(3*i)+2].getElementsByTagName('div')[1],this.o[(3*i)+1],this.o[(3*i)+2].getElementsByTagName('div')[0]);
|
||||
}
|
||||
this.cb = [document.getElementById('disabled-0'),document.getElementById('disabled-1')];
|
||||
/*
|
||||
for (i=this.cb.length; i--;) {
|
||||
this.cb[i]._index = i;
|
||||
this.cb[i].onclick = this.cbClick;
|
||||
}
|
||||
*/
|
||||
this.options = [];
|
||||
/*
|
||||
this.cb[1].checked = false;
|
||||
this.options = [document.getElementById('opt-random0'),document.getElementById('opt-random1')];
|
||||
this.options[0].checked = false;
|
||||
this.options[1].checked = true;
|
||||
if (navigator.userAgent.match(/msie/i)) {
|
||||
this.fbIE = document.getElementById('fireButton');
|
||||
this.fbIE.onmouseover = function() {this.className='hover';}
|
||||
this.fbIE.onmouseout = function() {this.className='';}
|
||||
}
|
||||
*/
|
||||
|
||||
setTimeout(function(){
|
||||
var values = [
|
||||
256,
|
||||
65,
|
||||
40,
|
||||
72,
|
||||
48
|
||||
];
|
||||
for (var i=0; i<values.length; i++) {
|
||||
self.controls[i].setValue(values[i]); // defaults
|
||||
}
|
||||
},1);
|
||||
}
|
||||
|
||||
function Slider(o,oV,oB) {
|
||||
var self = this;
|
||||
this.o = o;
|
||||
this.oV = oV;
|
||||
this.oB = oB;
|
||||
this.scale = parseInt(oV.innerHTML.toString().substr(2));
|
||||
this.oID = 'sc'+(gOID++);
|
||||
this.offX = 0;
|
||||
this.x = 0;
|
||||
this.xMin = 0-10;
|
||||
this.xMax = self.o.parentNode.offsetWidth-10;
|
||||
this.value = 0;
|
||||
this.timer = null;
|
||||
this._className = this.o.className;
|
||||
this.tween = [];
|
||||
this.frame = 0;
|
||||
|
||||
this.over = function() {
|
||||
this.className = self._className+' hover';
|
||||
event.cancelBubble=true;
|
||||
return false;
|
||||
}
|
||||
|
||||
this.out = function() {
|
||||
this.className = self._className;
|
||||
event.cancelBubble=true;
|
||||
return false;
|
||||
}
|
||||
|
||||
this.down = function(e) {
|
||||
var e = e?e:event;
|
||||
self.offX = e.clientX-self.o.offsetLeft;
|
||||
addEvent(document,'mousemove',self.move);
|
||||
addEvent(document,'mouseup',self.up);
|
||||
return false;
|
||||
}
|
||||
|
||||
this.barClick = function(e) {
|
||||
var e=e?e:event;
|
||||
self.slide(self.x,e.clientX-self.o.parentNode.parentNode.offsetLeft-self.o.offsetWidth);
|
||||
}
|
||||
|
||||
this.move = function(e) {
|
||||
var e=e?e:event;
|
||||
var x = e.clientX-self.offX;
|
||||
if (x>self.xMax) {
|
||||
x = self.xMax;
|
||||
} else if (x<self.xMin) {
|
||||
x = self.xMin;
|
||||
}
|
||||
if (x != self.x) {
|
||||
self.moveTo(x);
|
||||
self.doUpdate();
|
||||
controller.updateExample();
|
||||
controller.updateExampleCode();
|
||||
}
|
||||
e.stopPropgation?e.stopPropagation():e.cancelBubble=true;
|
||||
return false;
|
||||
}
|
||||
|
||||
this.up = function(e) {
|
||||
removeEvent(document,'mousemove',self.move);
|
||||
removeEvent(document,'mouseup',self.up);
|
||||
// controller.updateExample();
|
||||
controller.updateExampleCode();
|
||||
}
|
||||
|
||||
this.slide = function(x0,x1) {
|
||||
self.tween = mc.animator.createTween(x0,x1);
|
||||
mc.animator.enqueue(self,self.animate,function(){
|
||||
controller.updateExample()
|
||||
controller.updateExampleCode();
|
||||
});
|
||||
mc.animator.start();
|
||||
}
|
||||
|
||||
this.moveTo = function(x) {
|
||||
self.x = x;
|
||||
self.o.style.marginLeft = x+'px';
|
||||
}
|
||||
|
||||
this.animate = function() {
|
||||
self.moveTo(self.tween[self.frame].data);
|
||||
self.doUpdate(50);
|
||||
controller.updateExample();
|
||||
if (self.frame++>=self.tween.length-1) {
|
||||
self.active = false;
|
||||
self.frame = 0;
|
||||
if (self._oncomplete) self._oncomplete();
|
||||
// self.doUpdate();
|
||||
return false;
|
||||
}
|
||||
self.doUpdate();
|
||||
return true;
|
||||
}
|
||||
|
||||
this.doUpdate = function(t) {
|
||||
// if (!self.timer) self.timer = setTimeout(self.update,t||20);
|
||||
self.update();
|
||||
}
|
||||
|
||||
this.update = function() {
|
||||
self.timer = null;
|
||||
self.value = 1+parseInt(self.x/self.xMax*(self.scale-1));
|
||||
if (self.value<1) self.value = 1;
|
||||
// if (self.oV.innerHTML != self.value) self.oV.innerHTML = self.value;
|
||||
// self.oV.innerHTML = self.value;
|
||||
}
|
||||
|
||||
this.setValue = function(x) {
|
||||
self.slide(self.x,Math.min(self.xMax,x));
|
||||
}
|
||||
|
||||
this.randomize = function() {
|
||||
self.slide(self.x,parseInt(Math.random()*self.xMax));
|
||||
}
|
||||
|
||||
this.destructor = function() {
|
||||
self.o.onmouseover = null;
|
||||
self.o.onmouseout = null;
|
||||
self.o.onmousedown = null;
|
||||
self.o = null;
|
||||
self.oV = null;
|
||||
self.oB.onclick = null;
|
||||
self.oB = null;
|
||||
}
|
||||
|
||||
if (soundManager.isIE) {
|
||||
// IE is lame, no :hover
|
||||
this.o.onmouseover = this.over;
|
||||
this.o.onmouseout = this.out;
|
||||
}
|
||||
|
||||
this.o.onmousedown = this.down;
|
||||
this.oB.onclick = this.barClick;
|
||||
self.update();
|
||||
|
||||
}
|
||||
|
||||
var gOID = 0;
|
||||
|
||||
function demoInit() {
|
||||
controller = new Controller(document.getElementById('controls').getElementsByTagName('dd'));
|
||||
}
|
||||
|
||||
function demoDestuctor() {
|
||||
controller.destructor();
|
||||
controller = null;
|
||||
}
|
||||
|
||||
var controller = null;
|
||||
|
||||
var mc = new MainController();
|
||||
// create null objects if APIs not present
|
||||
|
||||
function createCP(oInput,oHandler) {
|
||||
var Event = YAHOO.util.Event;
|
||||
|
||||
cpHandler = oHandler;
|
||||
if (picker != null) {
|
||||
// picker.showcontrols(true);
|
||||
var c = oInput.value.substr(1);
|
||||
picker.setValue(hex2decArray([c.substr(0,2),c.substr(2,2),c.substr(4,2)]),true); // be silent
|
||||
return false;
|
||||
}
|
||||
|
||||
Event.onDOMReady(function() {
|
||||
picker = new YAHOO.widget.ColorPicker("cp-container", {
|
||||
showhsvcontrols: true,
|
||||
showhexcontrols: true,
|
||||
images: {
|
||||
PICKER_THUMB: "../_image/picker_thumb.png",
|
||||
HUE_THUMB: "../_image/hue_thumb.png"
|
||||
}
|
||||
});
|
||||
|
||||
// picker.showcontrols(false);
|
||||
//a listener for logging RGB color changes;
|
||||
//this will only be visible if logger is enabled:
|
||||
var onRgbChange = function(o) {
|
||||
/*o is an object
|
||||
{ newValue: (array of R, G, B values),
|
||||
prevValue: (array of R, G, B values),
|
||||
type: "rgbChange"
|
||||
}
|
||||
*/
|
||||
cpHandler(o.newValue);
|
||||
controller.updateExampleCode();
|
||||
}
|
||||
|
||||
//subscribe to the rgbChange event;
|
||||
picker.on("rgbChange", onRgbChange);
|
||||
|
||||
//use setValue to reset the value to white:
|
||||
Event.on("reset", "click", function(e) {
|
||||
picker.setValue([255, 255, 255], false); //false here means that rgbChange
|
||||
//wil fire; true would silence it
|
||||
});
|
||||
|
||||
//use the "get" method to get the current value
|
||||
//of one of the Color Picker's properties; in
|
||||
//this case, we'll get the hex value and write it
|
||||
//to the log:
|
||||
Event.on("gethex", "click", function(e) {
|
||||
console.log("Current hex value: " + picker.get("hex"));
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
var picker = null;
|
||||
|
||||
cpHandler = function() {
|
||||
}
|
||||
|
||||
|
||||
// hex -> dec / dec -> hex
|
||||
// http://www.southwest.com.au/~jfuller/binary/converter.htm
|
||||
|
||||
function dec2hex(cval) {
|
||||
if (cval > 255) cval = 255;
|
||||
var hexascii = "0123456789ABCDEF";
|
||||
var cval0 = Math.floor(cval/16);
|
||||
var cval1 = cval-(cval0*16);
|
||||
var c1 = hexascii.charAt(cval0);
|
||||
var c2 = hexascii.charAt(cval1);
|
||||
return (c1+c2);
|
||||
}
|
||||
|
||||
function hex2dec(cval) {
|
||||
cval = cval.toUpperCase();
|
||||
var tval = 0;
|
||||
var hexascii = "0123456789ABCDEF";
|
||||
var mychar, ch;
|
||||
for (var c=0; c<cval.length; c++) {
|
||||
mychar = cval.charAt(c);
|
||||
for (ch=0; ch<16; ch++) {
|
||||
if (mychar == hexascii.charAt(ch)) {
|
||||
tval += ch;
|
||||
if (c<cval.length-1) tval *= 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
return tval;
|
||||
}
|
||||
|
||||
function hex2decArray(hArray) {
|
||||
var result = [];
|
||||
for (var i=0,j=hArray.length; i<j; i++) {
|
||||
result[i] = hex2dec(hArray[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function dec2hexArray(dArray) {
|
||||
var result = [];
|
||||
for (var i=0,j=dArray.length; i<j; i++) {
|
||||
result[i] = dec2hex(dArray[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
|
||||
threeSixtyPlayer.config.waveformDataColor = '#'+dec2hexArray([self.controls[5].value,self.controls[6].value,self.controls[7].value]).join('');
|
||||
|
||||
threeSixtyPlayer.config.eqDataColor = '#'+dec2hexArray([self.controls[8].value,self.controls[9].value,self.controls[10].value]).join('');
|
||||
|
||||
threeSixtyPlayer.config.loadRingColor = '#'+dec2hexArray([self.controls[11].value,self.controls[12].value,self.controls[13].value]).join('');
|
||||
|
||||
threeSixtyPlayer.config.playRingColor = '#'+dec2hexArray([self.controls[14].value,self.controls[15].value,self.controls[16].value]).join('');
|
||||
|
||||
threeSixtyPlayer.config.waveformDataLineRatio = (self.controls[1].value/100)*2;
|
||||
|
||||
threeSixtyPlayer.config.waveformDataDownsample = (self.controls[2].value);
|
||||
|
||||
threeSixtyPlayer.config.eqDataLineRatio = (self.controls[3].value/100)*3;
|
||||
|
||||
threeSixtyPlayer.config.eqDataDownsample = (self.controls[4].value);
|
||||
|
||||
*/
|
||||
|
||||
function _id(sID) {
|
||||
return document.getElementById(sID);
|
||||
}
|
||||
|
||||
function setWaveformColor(sColor) {
|
||||
var value = '#'+(dec2hexArray(sColor).join(''));
|
||||
threeSixtyPlayer.config.waveformDataColor = value;
|
||||
_id('waveform-color').value = value;
|
||||
}
|
||||
|
||||
function setEQColor(sColor) {
|
||||
var value = '#'+dec2hexArray(sColor).join('');
|
||||
_id('eq-color').value = value;
|
||||
threeSixtyPlayer.config.eqDataColor = value;
|
||||
}
|
||||
|
||||
function setLoadedRingColor(sColor) {
|
||||
var value = '#'+dec2hexArray(sColor).join('');
|
||||
_id('loaded-ring-color').value = value;
|
||||
threeSixtyPlayer.config.loadRingColor = value;
|
||||
}
|
||||
|
||||
function setProgressRingColor(sColor) {
|
||||
var value = '#'+dec2hexArray(sColor).join('');
|
||||
_id('progress-ring-color').value = value;
|
||||
threeSixtyPlayer.config.playRingColor = value;
|
||||
}
|
||||
|
||||
function setBackgroundRingColor(sColor) {
|
||||
var value = '#'+dec2hexArray(sColor).join('');
|
||||
_id('bg-ring-color').value = value;
|
||||
threeSixtyPlayer.config.backgroundRingColor = value;
|
||||
}
|
||||
|
||||
function addEvent(o,evtName,evtHandler) {
|
||||
typeof(attachEvent)=='undefined'?o.addEventListener(evtName,evtHandler,false):o.attachEvent('on'+evtName,evtHandler);
|
||||
}
|
||||
|
||||
function removeEvent(o,evtName,evtHandler) {
|
||||
typeof(attachEvent)=='undefined'?o.removeEventListener(evtName,evtHandler,false):o.detachEvent('on'+evtName,evtHandler);
|
||||
}
|
||||
|
||||
if (window.location.toString().match(/#customize/i)) {
|
||||
addEvent(window,'resize',mc.getWindowCoords);
|
||||
addEvent(window,'scroll',mc.getWindowCoords);
|
||||
addEvent(window,'load',mc.init);
|
||||
addEvent(window,'load',demoInit);
|
||||
}
|
||||
|
||||
if (window.location.toString().match(/hifi/i)) {
|
||||
soundManager.onready(function(){
|
||||
document.getElementById('hifi').style.display = 'none';
|
||||
threeSixtyPlayer.config = {
|
||||
playNext: false,
|
||||
autoPlay: false,
|
||||
loadRingColor: '#ccc',
|
||||
playRingColor: '#000',
|
||||
backgroundRingColor: '#eee',
|
||||
circleDiameter: 256,
|
||||
circleRadius: 128,
|
||||
imageRoot: '',
|
||||
animDuration: 500,
|
||||
animTransition: Animator.tx.bouncy,
|
||||
showHMSTime: true,
|
||||
|
||||
useWaveformData: true,
|
||||
waveformDataColor: '#0099ff',
|
||||
waveformDataDownsample: 1,
|
||||
waveformDataOutside: true,
|
||||
waveformDataConstrain: false,
|
||||
waveformDataLineRatio: 0.56,
|
||||
|
||||
useEQData: true,
|
||||
eqDataColor: '#339933',
|
||||
eqDataDownsample: 1,
|
||||
eqDataOutside: true,
|
||||
eqDataLineRatio: 0.72,
|
||||
|
||||
usePeakData: true,
|
||||
peakDataColor: '#ff33ff',
|
||||
peakDataOutside: true,
|
||||
peakDataLineRatio: 0.5,
|
||||
|
||||
useAmplifier: true
|
||||
|
||||
}
|
||||
});
|
||||
}
|
75
js/libs/soundmanager/demo/360-player/demo.css
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
|
||||
-------------------------------------------------------------
|
||||
|
||||
In-page demo CSS - see external CSS for actual relevant stuff.
|
||||
|
||||
--------------------------------------------------------------
|
||||
|
||||
*/
|
||||
|
||||
#soundmanager-debug {
|
||||
/* SM2 debug container (optional, makes debug more useable) */
|
||||
position:absolute;position:fixed;*position:absolute;bottom:10px;right:10px;width:50em;height:18em;overflow:auto;background:#fff;margin:1em;padding:1em;border:1px solid #999;font-family:"lucida console",verdana,tahoma,"sans serif";font-size:x-small;line-height:1.5em;opacity:0.9;filter:alpha(opacity=90);
|
||||
}
|
||||
|
||||
body {
|
||||
font:75% normal verdana,arial,tahoma,"sans serif";
|
||||
}
|
||||
|
||||
h1, h2, h3 {
|
||||
font:3em arial,tahoma,verdana;
|
||||
font-weight:normal;
|
||||
margin-bottom:0px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-top:0.25em;
|
||||
}
|
||||
|
||||
h1, h2 {
|
||||
letter-spacing:-1px; /* zomg web x.0! ;) */
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size:2em;
|
||||
margin-top:0px;
|
||||
margin-bottom:0.1em;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size:1.5em;
|
||||
margin-bottom:1em;
|
||||
}
|
||||
|
||||
h1 a,
|
||||
h1 a:hover {
|
||||
color:#000;
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
h1 a:hover {
|
||||
text-decoration:underline;
|
||||
}
|
||||
|
||||
ul.notes {
|
||||
margin-left:0px;
|
||||
padding-left:1.5em;
|
||||
}
|
||||
|
||||
.note {
|
||||
margin-top:0px;
|
||||
font-style:italic;
|
||||
color:#999;
|
||||
margin-bottom:0px;
|
||||
}
|
||||
|
||||
pre {
|
||||
font-size:1.2em;
|
||||
_font-size:1em;
|
||||
}
|
||||
|
||||
#left {
|
||||
max-width:56em;
|
||||
margin-left:1em;
|
||||
}
|
BIN
js/libs/soundmanager/demo/360-player/empty.gif
Normal file
After Width: | Height: | Size: 43 B |
BIN
js/libs/soundmanager/demo/360-player/icon_loading_dots.gif
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
js/libs/soundmanager/demo/360-player/icon_loading_spinner.gif
Normal file
After Width: | Height: | Size: 530 B |
After Width: | Height: | Size: 2.5 KiB |
167
js/libs/soundmanager/demo/360-player/index.html
Normal file
|
@ -0,0 +1,167 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<title>360° MP3 player UI demo (SoundManager 2)</title>
|
||||
<meta name="robots" content="noindex" />
|
||||
<meta name="description" content="Javascript-driven sound, canvas-based MP3 player UI demo: 360-degree circular control / jog wheel example for playing MP3 links using SoundManager 2, Javascript and Canvas.">
|
||||
|
||||
<!-- required -->
|
||||
<link rel="stylesheet" type="text/css" href="360player.css" />
|
||||
|
||||
<!-- special IE-only canvas fix -->
|
||||
<!--[if IE]><script type="text/javascript" src="script/excanvas.js"></script><![endif]-->
|
||||
|
||||
<!-- Apache-licensed animation library -->
|
||||
<script type="text/javascript" src="script/berniecode-animator.js"></script>
|
||||
|
||||
<!-- the core stuff -->
|
||||
<script type="text/javascript" src="../../script/soundmanager2.js"></script>
|
||||
<script type="text/javascript" src="script/360player.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
soundManager.url = '../../swf/';
|
||||
</script>
|
||||
|
||||
<!-- stuff you don't need -->
|
||||
<!-- makes the fonts nicer etc. -->
|
||||
<link rel="stylesheet" type="text/css" href="../index.css" />
|
||||
<link rel="stylesheet" type="text/css" href="demo.css" />
|
||||
|
||||
<!-- soundManager.useFlashBlock: related CSS -->
|
||||
<link rel="stylesheet" type="text/css" href="../flashblock/flashblock.css" />
|
||||
|
||||
<style type="text/css">
|
||||
|
||||
/* Demo page, general layout */
|
||||
|
||||
#left {
|
||||
position:relative;
|
||||
width:950px;
|
||||
max-width:100%;
|
||||
}
|
||||
|
||||
#left h2 {
|
||||
padding-top:0px;
|
||||
margin-bottom:0.25em;
|
||||
color:#666;
|
||||
}
|
||||
|
||||
pre.block {
|
||||
margin-top:0.5em;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="left">
|
||||
|
||||
<h1><a href="http://www.schillmania.com/projects/soundmanager2/" title="Javascript MP3 player project home">SoundManager 2</a> / <a href="http://schillmania.com/projects/soundmanager2/demo/360-player/">360° Player</a>: JS + Canvas UI</h1>
|
||||
|
||||
<p class="note" style="color:#666;margin-bottom:0.5em">Canvas-based UI. Load progress, seek, play/pause etc. Also see <a href="canvas-visualization.html" title="Javascript canvas visualization with waveform/eq data">360° UI visualization</a> demo.</p>
|
||||
|
||||
<div id="sm2-container">
|
||||
<!-- flash movie is added here -->
|
||||
</div>
|
||||
|
||||
<div style="margin-top:1.25em">
|
||||
|
||||
<div style="float:left;display:inline"> <!-- float is just for this demo layout, you don't need it. -->
|
||||
|
||||
<div class="ui360" style="margin-top:-0.55em"><a href="../_mp3/rain.mp3">Rain</a></div>
|
||||
|
||||
<div class="ui360"><a href="http://freshly-ground.com/data/audio/mpc/20090119%20-%20Untitled%20Groove.mp3">20090119 - Untitled Groove</a></div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div style="float:left;display:inline;margin-left:40px;border-left:1px solid #ccc;padding-left:30px;width:140px">
|
||||
|
||||
<p style="margin-top:1em;margin-bottom:0px">Alternate style: inline</p>
|
||||
|
||||
<div class="sm2-inline-list" style="margin-bottom:10px"> <!-- note the CSS class, changes the layout -->
|
||||
|
||||
<div class="ui360"><a href="http://www.freshly-ground.com/data/audio/binaural/Mak.mp3">Angry cow sound?</a></div>
|
||||
<div class="ui360"><a href="http://www.freshly-ground.com/data/audio/binaural/Things that open, close and roll.mp3">Things that open, close and roll</a></div>
|
||||
<div class="ui360"><a href="http://www.freshly-ground.com/misc/music/20060826%20-%20Armstrong.mp3">20060826 - Armstrong</a></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div style="clear:both"></div>
|
||||
|
||||
|
||||
<h3>How This Works</h3>
|
||||
|
||||
<p>The script looks for a container element matching <code>div.<span>ui360</span></code>, and then the first link inside of it.</p>
|
||||
|
||||
<div>
|
||||
|
||||
<pre class="block"><code><div class="<span>ui360</span>">
|
||||
<a href="/path/to/an.mp3">
|
||||
</div></code></pre>
|
||||
|
||||
</div>
|
||||
|
||||
<p>When the link is clicked, the script adds a <code>UI</code> template to the block, prepending it in front of the MP3 link:</p>
|
||||
|
||||
<pre class="block"><code><div class="<span>ui360</span>">
|
||||
<span><span><-- dynamically-inserted block --></span></span>
|
||||
<div class="<span>ui</span>">
|
||||
<canvas class="<span>sm2-canvas</span>"></canvas>
|
||||
<img class="<span>sm2-360btn</span>" />
|
||||
<div class="<span>sm2-timing</span>"></div>
|
||||
<div class="<span>sm2-cover</span>"></div>
|
||||
</div>
|
||||
<span><span><-- /UI --></span></span>
|
||||
<a href="<span>/path/to/an.mp3</span>">
|
||||
</div></code></pre>
|
||||
|
||||
<h3>Customizing the UI</h3>
|
||||
|
||||
<p>The player's default 50x50-pixel canvas is defined both within JavaScript and CSS. For an example with different values, see this <a href="canvas-visualization.html" title="360° UI: larger version">larger version</a>.</p>
|
||||
|
||||
<pre class="block"><code>threeSixtyPlayer.config = {
|
||||
playNext: <span>false</span>, <span><span>// stop after one sound, or play through list until end</span></span>
|
||||
autoPlay: <span>false</span>, <span><span>// start playing the first sound right away</span></span>
|
||||
allowMultiple: <span>true</span>, <span><span>// let many sounds play at once (false = one at a time)</span></span>
|
||||
loadRingColor: <span>'#ccc',</span> <span><span>// amount of sound which has loaded</span></span>
|
||||
playRingColor: <span>'#000'</span>, <span><span>// amount of sound which has played</span></span>
|
||||
backgroundRingColor: <span>'#eee', </span><span><span>// "default" color shown underneath everything else</span></span>
|
||||
imageRoot: <span>''</span>,</span> <span><span>// path to prepend for empty.gif used for play/pause button
|
||||
animDuration: <span>500</span>,
|
||||
animTransition: <span>Animator.tx.bouncy</span> <span><span>// http://www.berniecode.com/writing/animator.html</span></span>
|
||||
}</code></pre>
|
||||
|
||||
<p>The CSS for the canvas UI block is a bit ugly, but JavaScript reads the width of the <code>.sm2-360ui</code> element in the DOM as set by CSS and uses that to later draw and update the canvas element while playing.</p>
|
||||
|
||||
<pre class="block"><code>.ui360,
|
||||
.sm2-360ui {
|
||||
<span><span>/* size of the container for the circle, etc. */</span></span>
|
||||
width:<span>50px</span>;</span>
|
||||
height:<span>50px</span>;</span>
|
||||
}
|
||||
</code></pre>
|
||||
|
||||
<h3>Third-party Components</h3>
|
||||
|
||||
<p>This demo includes use of <a href="http://www.berniecode.com/writing/animator.html">Bernie's Better Animation Class</a> (Apache licensed) for some animation effects.</p>
|
||||
<p>Also, some loader/spinner icons from <a href="http://ajaxload.info">ajaxload.info</a> are used for showing loading/buffering states.</p>
|
||||
|
||||
<hr />
|
||||
|
||||
<p>
|
||||
<a href="http://www.schillmania.com/projects/soundmanager2/" title="SoundManager 2 home">SoundManager 2 project page</a> (not an MP3 link)
|
||||
</p>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
1225
js/libs/soundmanager/demo/360-player/script/360player.js
Normal file
|
@ -0,0 +1,674 @@
|
|||
/*
|
||||
Animator.js 1.1.9
|
||||
|
||||
This library is released under the BSD license:
|
||||
|
||||
Copyright (c) 2006, Bernard Sumption. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer. Redistributions in binary
|
||||
form must reproduce the above copyright notice, this list of conditions and
|
||||
the following disclaimer in the documentation and/or other materials
|
||||
provided with the distribution. Neither the name BernieCode nor
|
||||
the names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
// http://www.berniecode.com/writing/animator.html
|
||||
|
||||
// Applies a sequence of numbers between 0 and 1 to a number of subjects
|
||||
// construct - see setOptions for parameters
|
||||
function Animator(options) {
|
||||
this.setOptions(options);
|
||||
var _this = this;
|
||||
this.timerDelegate = function(){_this.onTimerEvent()};
|
||||
this.subjects = [];
|
||||
this.subjectScopes = [];
|
||||
this.target = 0;
|
||||
this.state = 0;
|
||||
this.lastTime = null;
|
||||
};
|
||||
Animator.prototype = {
|
||||
// apply defaults
|
||||
setOptions: function(options) {
|
||||
this.options = Animator.applyDefaults({
|
||||
interval: 20, // time between animation frames
|
||||
duration: 400, // length of animation
|
||||
onComplete: function(){},
|
||||
onStep: function(){},
|
||||
transition: Animator.tx.easeInOut
|
||||
}, options);
|
||||
},
|
||||
// animate from the current state to provided value
|
||||
seekTo: function(to) {
|
||||
this.seekFromTo(this.state, to);
|
||||
},
|
||||
// animate from the current state to provided value
|
||||
seekFromTo: function(from, to) {
|
||||
this.target = Math.max(0, Math.min(1, to));
|
||||
this.state = Math.max(0, Math.min(1, from));
|
||||
this.lastTime = new Date().getTime();
|
||||
if (!this.intervalId) {
|
||||
this.intervalId = window.setInterval(this.timerDelegate, this.options.interval);
|
||||
}
|
||||
},
|
||||
// animate from the current state to provided value
|
||||
jumpTo: function(to) {
|
||||
this.target = this.state = Math.max(0, Math.min(1, to));
|
||||
this.propagate();
|
||||
},
|
||||
// seek to the opposite of the current target
|
||||
toggle: function() {
|
||||
this.seekTo(1 - this.target);
|
||||
},
|
||||
// add a function or an object with a method setState(state) that will be called with a number
|
||||
// between 0 and 1 on each frame of the animation
|
||||
addSubject: function(subject,scope) {
|
||||
this.subjects[this.subjects.length] = subject;
|
||||
this.subjectScopes[this.subjectScopes.length] = scope;
|
||||
return this;
|
||||
},
|
||||
// remove all subjects
|
||||
clearSubjects: function() {
|
||||
this.subjects = [];
|
||||
this.subjectScopes = [];
|
||||
},
|
||||
// forward the current state to the animation subjects
|
||||
propagate: function() {
|
||||
var value = this.options.transition(this.state);
|
||||
for (var i=0; i<this.subjects.length; i++) {
|
||||
if (this.subjects[i].setState) {
|
||||
this.subjects[i].setState(value);
|
||||
} else {
|
||||
this.subjects[i].apply(this.subjectScopes[i],[value]);
|
||||
}
|
||||
}
|
||||
},
|
||||
// called once per frame to update the current state
|
||||
onTimerEvent: function() {
|
||||
var now = new Date().getTime();
|
||||
var timePassed = now - this.lastTime;
|
||||
this.lastTime = now;
|
||||
var movement = (timePassed / this.options.duration) * (this.state < this.target ? 1 : -1);
|
||||
if (Math.abs(movement) >= Math.abs(this.state - this.target)) {
|
||||
this.state = this.target;
|
||||
} else {
|
||||
this.state += movement;
|
||||
}
|
||||
|
||||
try {
|
||||
this.propagate();
|
||||
} finally {
|
||||
this.options.onStep.call(this);
|
||||
if (this.target == this.state) {
|
||||
window.clearInterval(this.intervalId);
|
||||
this.intervalId = null;
|
||||
this.options.onComplete.call(this);
|
||||
}
|
||||
}
|
||||
},
|
||||
// shortcuts
|
||||
play: function() {this.seekFromTo(0, 1)},
|
||||
reverse: function() {this.seekFromTo(1, 0)},
|
||||
// return a string describing this Animator, for debugging
|
||||
inspect: function() {
|
||||
var str = "#<Animator:\n";
|
||||
for (var i=0; i<this.subjects.length; i++) {
|
||||
str += this.subjects[i].inspect();
|
||||
}
|
||||
str += ">";
|
||||
return str;
|
||||
}
|
||||
}
|
||||
// merge the properties of two objects
|
||||
Animator.applyDefaults = function(defaults, prefs) {
|
||||
prefs = prefs || {};
|
||||
var prop, result = {};
|
||||
for (prop in defaults) result[prop] = prefs[prop] !== undefined ? prefs[prop] : defaults[prop];
|
||||
return result;
|
||||
}
|
||||
// make an array from any object
|
||||
Animator.makeArray = function(o) {
|
||||
if (o == null) return [];
|
||||
if (!o.length) return [o];
|
||||
var result = [];
|
||||
for (var i=0; i<o.length; i++) result[i] = o[i];
|
||||
return result;
|
||||
}
|
||||
// convert a dash-delimited-property to a camelCaseProperty (c/o Prototype, thanks Sam!)
|
||||
Animator.camelize = function(string) {
|
||||
var oStringList = string.split('-');
|
||||
if (oStringList.length == 1) return oStringList[0];
|
||||
|
||||
var camelizedString = string.indexOf('-') == 0
|
||||
? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1)
|
||||
: oStringList[0];
|
||||
|
||||
for (var i = 1, len = oStringList.length; i < len; i++) {
|
||||
var s = oStringList[i];
|
||||
camelizedString += s.charAt(0).toUpperCase() + s.substring(1);
|
||||
}
|
||||
return camelizedString;
|
||||
}
|
||||
// syntactic sugar for creating CSSStyleSubjects
|
||||
Animator.apply = function(el, style, options) {
|
||||
if (style instanceof Array) {
|
||||
return new Animator(options).addSubject(new CSSStyleSubject(el, style[0], style[1]));
|
||||
}
|
||||
return new Animator(options).addSubject(new CSSStyleSubject(el, style));
|
||||
}
|
||||
// make a transition function that gradually accelerates. pass a=1 for smooth
|
||||
// gravitational acceleration, higher values for an exaggerated effect
|
||||
Animator.makeEaseIn = function(a) {
|
||||
return function(state) {
|
||||
return Math.pow(state, a*2);
|
||||
}
|
||||
}
|
||||
// as makeEaseIn but for deceleration
|
||||
Animator.makeEaseOut = function(a) {
|
||||
return function(state) {
|
||||
return 1 - Math.pow(1 - state, a*2);
|
||||
}
|
||||
}
|
||||
// make a transition function that, like an object with momentum being attracted to a point,
|
||||
// goes past the target then returns
|
||||
Animator.makeElastic = function(bounces) {
|
||||
return function(state) {
|
||||
state = Animator.tx.easeInOut(state);
|
||||
return ((1-Math.cos(state * Math.PI * bounces)) * (1 - state)) + state;
|
||||
}
|
||||
}
|
||||
// make an Attack Decay Sustain Release envelope that starts and finishes on the same level
|
||||
//
|
||||
Animator.makeADSR = function(attackEnd, decayEnd, sustainEnd, sustainLevel) {
|
||||
if (sustainLevel == null) sustainLevel = 0.5;
|
||||
return function(state) {
|
||||
if (state < attackEnd) {
|
||||
return state / attackEnd;
|
||||
}
|
||||
if (state < decayEnd) {
|
||||
return 1 - ((state - attackEnd) / (decayEnd - attackEnd) * (1 - sustainLevel));
|
||||
}
|
||||
if (state < sustainEnd) {
|
||||
return sustainLevel;
|
||||
}
|
||||
return sustainLevel * (1 - ((state - sustainEnd) / (1 - sustainEnd)));
|
||||
}
|
||||
}
|
||||
// make a transition function that, like a ball falling to floor, reaches the target and/
|
||||
// bounces back again
|
||||
Animator.makeBounce = function(bounces) {
|
||||
var fn = Animator.makeElastic(bounces);
|
||||
return function(state) {
|
||||
state = fn(state);
|
||||
return state <= 1 ? state : 2-state;
|
||||
}
|
||||
}
|
||||
|
||||
// pre-made transition functions to use with the 'transition' option
|
||||
Animator.tx = {
|
||||
easeInOut: function(pos){
|
||||
return ((-Math.cos(pos*Math.PI)/2) + 0.5);
|
||||
},
|
||||
linear: function(x) {
|
||||
return x;
|
||||
},
|
||||
easeIn: Animator.makeEaseIn(1.5),
|
||||
easeOut: Animator.makeEaseOut(1.5),
|
||||
strongEaseIn: Animator.makeEaseIn(2.5),
|
||||
strongEaseOut: Animator.makeEaseOut(2.5),
|
||||
elastic: Animator.makeElastic(1),
|
||||
veryElastic: Animator.makeElastic(3),
|
||||
bouncy: Animator.makeBounce(1),
|
||||
veryBouncy: Animator.makeBounce(3)
|
||||
}
|
||||
|
||||
// animates a pixel-based style property between two integer values
|
||||
function NumericalStyleSubject(els, property, from, to, units) {
|
||||
this.els = Animator.makeArray(els);
|
||||
if (property == 'opacity' && window.ActiveXObject) {
|
||||
this.property = 'filter';
|
||||
} else {
|
||||
this.property = Animator.camelize(property);
|
||||
}
|
||||
this.from = parseFloat(from);
|
||||
this.to = parseFloat(to);
|
||||
this.units = units != null ? units : 'px';
|
||||
}
|
||||
NumericalStyleSubject.prototype = {
|
||||
setState: function(state) {
|
||||
var style = this.getStyle(state);
|
||||
var visibility = (this.property == 'opacity' && state == 0) ? 'hidden' : '';
|
||||
var j=0;
|
||||
for (var i=0; i<this.els.length; i++) {
|
||||
try {
|
||||
this.els[i].style[this.property] = style;
|
||||
} catch (e) {
|
||||
// ignore fontWeight - intermediate numerical values cause exeptions in firefox
|
||||
if (this.property != 'fontWeight') throw e;
|
||||
}
|
||||
if (j++ > 20) return;
|
||||
}
|
||||
},
|
||||
getStyle: function(state) {
|
||||
state = this.from + ((this.to - this.from) * state);
|
||||
if (this.property == 'filter') return "alpha(opacity=" + Math.round(state*100) + ")";
|
||||
if (this.property == 'opacity') return state;
|
||||
return Math.round(state) + this.units;
|
||||
},
|
||||
inspect: function() {
|
||||
return "\t" + this.property + "(" + this.from + this.units + " to " + this.to + this.units + ")\n";
|
||||
}
|
||||
}
|
||||
|
||||
// animates a colour based style property between two hex values
|
||||
function ColorStyleSubject(els, property, from, to) {
|
||||
this.els = Animator.makeArray(els);
|
||||
this.property = Animator.camelize(property);
|
||||
this.to = this.expandColor(to);
|
||||
this.from = this.expandColor(from);
|
||||
this.origFrom = from;
|
||||
this.origTo = to;
|
||||
}
|
||||
|
||||
ColorStyleSubject.prototype = {
|
||||
// parse "#FFFF00" to [256, 256, 0]
|
||||
expandColor: function(color) {
|
||||
var hexColor, red, green, blue;
|
||||
hexColor = ColorStyleSubject.parseColor(color);
|
||||
if (hexColor) {
|
||||
red = parseInt(hexColor.slice(1, 3), 16);
|
||||
green = parseInt(hexColor.slice(3, 5), 16);
|
||||
blue = parseInt(hexColor.slice(5, 7), 16);
|
||||
return [red,green,blue]
|
||||
}
|
||||
if (window.DEBUG) {
|
||||
alert("Invalid colour: '" + color + "'");
|
||||
}
|
||||
},
|
||||
getValueForState: function(color, state) {
|
||||
return Math.round(this.from[color] + ((this.to[color] - this.from[color]) * state));
|
||||
},
|
||||
setState: function(state) {
|
||||
var color = '#'
|
||||
+ ColorStyleSubject.toColorPart(this.getValueForState(0, state))
|
||||
+ ColorStyleSubject.toColorPart(this.getValueForState(1, state))
|
||||
+ ColorStyleSubject.toColorPart(this.getValueForState(2, state));
|
||||
for (var i=0; i<this.els.length; i++) {
|
||||
this.els[i].style[this.property] = color;
|
||||
}
|
||||
},
|
||||
inspect: function() {
|
||||
return "\t" + this.property + "(" + this.origFrom + " to " + this.origTo + ")\n";
|
||||
}
|
||||
}
|
||||
|
||||
// return a properly formatted 6-digit hex colour spec, or false
|
||||
ColorStyleSubject.parseColor = function(string) {
|
||||
var color = '#', match;
|
||||
if(match = ColorStyleSubject.parseColor.rgbRe.exec(string)) {
|
||||
var part;
|
||||
for (var i=1; i<=3; i++) {
|
||||
part = Math.max(0, Math.min(255, parseInt(match[i])));
|
||||
color += ColorStyleSubject.toColorPart(part);
|
||||
}
|
||||
return color;
|
||||
}
|
||||
if (match = ColorStyleSubject.parseColor.hexRe.exec(string)) {
|
||||
if(match[1].length == 3) {
|
||||
for (var i=0; i<3; i++) {
|
||||
color += match[1].charAt(i) + match[1].charAt(i);
|
||||
}
|
||||
return color;
|
||||
}
|
||||
return '#' + match[1];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// convert a number to a 2 digit hex string
|
||||
ColorStyleSubject.toColorPart = function(number) {
|
||||
if (number > 255) number = 255;
|
||||
var digits = number.toString(16);
|
||||
if (number < 16) return '0' + digits;
|
||||
return digits;
|
||||
}
|
||||
ColorStyleSubject.parseColor.rgbRe = /^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i;
|
||||
ColorStyleSubject.parseColor.hexRe = /^\#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
|
||||
|
||||
// Animates discrete styles, i.e. ones that do not scale but have discrete values
|
||||
// that can't be interpolated
|
||||
function DiscreteStyleSubject(els, property, from, to, threshold) {
|
||||
this.els = Animator.makeArray(els);
|
||||
this.property = Animator.camelize(property);
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.threshold = threshold || 0.5;
|
||||
}
|
||||
|
||||
DiscreteStyleSubject.prototype = {
|
||||
setState: function(state) {
|
||||
var j=0;
|
||||
for (var i=0; i<this.els.length; i++) {
|
||||
this.els[i].style[this.property] = state <= this.threshold ? this.from : this.to;
|
||||
}
|
||||
},
|
||||
inspect: function() {
|
||||
return "\t" + this.property + "(" + this.from + " to " + this.to + " @ " + this.threshold + ")\n";
|
||||
}
|
||||
}
|
||||
|
||||
// animates between two styles defined using CSS.
|
||||
// if style1 and style2 are present, animate between them, if only style1
|
||||
// is present, animate between the element's current style and style1
|
||||
function CSSStyleSubject(els, style1, style2) {
|
||||
els = Animator.makeArray(els);
|
||||
this.subjects = [];
|
||||
if (els.length == 0) return;
|
||||
var prop, toStyle, fromStyle;
|
||||
if (style2) {
|
||||
fromStyle = this.parseStyle(style1, els[0]);
|
||||
toStyle = this.parseStyle(style2, els[0]);
|
||||
} else {
|
||||
toStyle = this.parseStyle(style1, els[0]);
|
||||
fromStyle = {};
|
||||
for (prop in toStyle) {
|
||||
fromStyle[prop] = CSSStyleSubject.getStyle(els[0], prop);
|
||||
}
|
||||
}
|
||||
// remove unchanging properties
|
||||
var prop;
|
||||
for (prop in fromStyle) {
|
||||
if (fromStyle[prop] == toStyle[prop]) {
|
||||
delete fromStyle[prop];
|
||||
delete toStyle[prop];
|
||||
}
|
||||
}
|
||||
// discover the type (numerical or colour) of each style
|
||||
var prop, units, match, type, from, to;
|
||||
for (prop in fromStyle) {
|
||||
var fromProp = String(fromStyle[prop]);
|
||||
var toProp = String(toStyle[prop]);
|
||||
if (toStyle[prop] == null) {
|
||||
if (window.DEBUG) alert("No to style provided for '" + prop + '"');
|
||||
continue;
|
||||
}
|
||||
|
||||
if (from = ColorStyleSubject.parseColor(fromProp)) {
|
||||
to = ColorStyleSubject.parseColor(toProp);
|
||||
type = ColorStyleSubject;
|
||||
} else if (fromProp.match(CSSStyleSubject.numericalRe)
|
||||
&& toProp.match(CSSStyleSubject.numericalRe)) {
|
||||
from = parseFloat(fromProp);
|
||||
to = parseFloat(toProp);
|
||||
type = NumericalStyleSubject;
|
||||
match = CSSStyleSubject.numericalRe.exec(fromProp);
|
||||
var reResult = CSSStyleSubject.numericalRe.exec(toProp);
|
||||
if (match[1] != null) {
|
||||
units = match[1];
|
||||
} else if (reResult[1] != null) {
|
||||
units = reResult[1];
|
||||
} else {
|
||||
units = reResult;
|
||||
}
|
||||
} else if (fromProp.match(CSSStyleSubject.discreteRe)
|
||||
&& toProp.match(CSSStyleSubject.discreteRe)) {
|
||||
from = fromProp;
|
||||
to = toProp;
|
||||
type = DiscreteStyleSubject;
|
||||
units = 0; // hack - how to get an animator option down to here
|
||||
} else {
|
||||
if (window.DEBUG) {
|
||||
alert("Unrecognised format for value of "
|
||||
+ prop + ": '" + fromStyle[prop] + "'");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
this.subjects[this.subjects.length] = new type(els, prop, from, to, units);
|
||||
}
|
||||
}
|
||||
|
||||
CSSStyleSubject.prototype = {
|
||||
// parses "width: 400px; color: #FFBB2E" to {width: "400px", color: "#FFBB2E"}
|
||||
parseStyle: function(style, el) {
|
||||
var rtn = {};
|
||||
// if style is a rule set
|
||||
if (style.indexOf(":") != -1) {
|
||||
var styles = style.split(";");
|
||||
for (var i=0; i<styles.length; i++) {
|
||||
var parts = CSSStyleSubject.ruleRe.exec(styles[i]);
|
||||
if (parts) {
|
||||
rtn[parts[1]] = parts[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
// else assume style is a class name
|
||||
else {
|
||||
var prop, value, oldClass;
|
||||
oldClass = el.className;
|
||||
el.className = style;
|
||||
for (var i=0; i<CSSStyleSubject.cssProperties.length; i++) {
|
||||
prop = CSSStyleSubject.cssProperties[i];
|
||||
value = CSSStyleSubject.getStyle(el, prop);
|
||||
if (value != null) {
|
||||
rtn[prop] = value;
|
||||
}
|
||||
}
|
||||
el.className = oldClass;
|
||||
}
|
||||
return rtn;
|
||||
|
||||
},
|
||||
setState: function(state) {
|
||||
for (var i=0; i<this.subjects.length; i++) {
|
||||
this.subjects[i].setState(state);
|
||||
}
|
||||
},
|
||||
inspect: function() {
|
||||
var str = "";
|
||||
for (var i=0; i<this.subjects.length; i++) {
|
||||
str += this.subjects[i].inspect();
|
||||
}
|
||||
return str;
|
||||
}
|
||||
}
|
||||
// get the current value of a css property,
|
||||
CSSStyleSubject.getStyle = function(el, property){
|
||||
var style;
|
||||
if(document.defaultView && document.defaultView.getComputedStyle){
|
||||
style = document.defaultView.getComputedStyle(el, "").getPropertyValue(property);
|
||||
if (style) {
|
||||
return style;
|
||||
}
|
||||
}
|
||||
property = Animator.camelize(property);
|
||||
if(el.currentStyle){
|
||||
style = el.currentStyle[property];
|
||||
}
|
||||
return style || el.style[property]
|
||||
}
|
||||
|
||||
|
||||
CSSStyleSubject.ruleRe = /^\s*([a-zA-Z\-]+)\s*:\s*(\S(.+\S)?)\s*$/;
|
||||
CSSStyleSubject.numericalRe = /^-?\d+(?:\.\d+)?(%|[a-zA-Z]{2})?$/;
|
||||
CSSStyleSubject.discreteRe = /^\w+$/;
|
||||
|
||||
// required because the style object of elements isn't enumerable in Safari
|
||||
/*
|
||||
CSSStyleSubject.cssProperties = ['background-color','border','border-color','border-spacing',
|
||||
'border-style','border-top','border-right','border-bottom','border-left','border-top-color',
|
||||
'border-right-color','border-bottom-color','border-left-color','border-top-width','border-right-width',
|
||||
'border-bottom-width','border-left-width','border-width','bottom','color','font-size','font-size-adjust',
|
||||
'font-stretch','font-style','height','left','letter-spacing','line-height','margin','margin-top',
|
||||
'margin-right','margin-bottom','margin-left','marker-offset','max-height','max-width','min-height',
|
||||
'min-width','orphans','outline','outline-color','outline-style','outline-width','overflow','padding',
|
||||
'padding-top','padding-right','padding-bottom','padding-left','quotes','right','size','text-indent',
|
||||
'top','width','word-spacing','z-index','opacity','outline-offset'];*/
|
||||
|
||||
|
||||
CSSStyleSubject.cssProperties = ['azimuth','background','background-attachment','background-color','background-image','background-position','background-repeat','border-collapse','border-color','border-spacing','border-style','border-top','border-top-color','border-right-color','border-bottom-color','border-left-color','border-top-style','border-right-style','border-bottom-style','border-left-style','border-top-width','border-right-width','border-bottom-width','border-left-width','border-width','bottom','clear','clip','color','content','cursor','direction','display','elevation','empty-cells','css-float','font','font-family','font-size','font-size-adjust','font-stretch','font-style','font-variant','font-weight','height','left','letter-spacing','line-height','list-style','list-style-image','list-style-position','list-style-type','margin','margin-top','margin-right','margin-bottom','margin-left','max-height','max-width','min-height','min-width','orphans','outline','outline-color','outline-style','outline-width','overflow','padding','padding-top','padding-right','padding-bottom','padding-left','pause','position','right','size','table-layout','text-align','text-decoration','text-indent','text-shadow','text-transform','top','vertical-align','visibility','white-space','width','word-spacing','z-index','opacity','outline-offset','overflow-x','overflow-y'];
|
||||
|
||||
|
||||
// chains several Animator objects together
|
||||
function AnimatorChain(animators, options) {
|
||||
this.animators = animators;
|
||||
this.setOptions(options);
|
||||
for (var i=0; i<this.animators.length; i++) {
|
||||
this.listenTo(this.animators[i]);
|
||||
}
|
||||
this.forwards = false;
|
||||
this.current = 0;
|
||||
}
|
||||
|
||||
AnimatorChain.prototype = {
|
||||
// apply defaults
|
||||
setOptions: function(options) {
|
||||
this.options = Animator.applyDefaults({
|
||||
// by default, each call to AnimatorChain.play() calls jumpTo(0) of each animator
|
||||
// before playing, which can cause flickering if you have multiple animators all
|
||||
// targeting the same element. Set this to false to avoid this.
|
||||
resetOnPlay: true
|
||||
}, options);
|
||||
},
|
||||
// play each animator in turn
|
||||
play: function() {
|
||||
this.forwards = true;
|
||||
this.current = -1;
|
||||
if (this.options.resetOnPlay) {
|
||||
for (var i=0; i<this.animators.length; i++) {
|
||||
this.animators[i].jumpTo(0);
|
||||
}
|
||||
}
|
||||
this.advance();
|
||||
},
|
||||
// play all animators backwards
|
||||
reverse: function() {
|
||||
this.forwards = false;
|
||||
this.current = this.animators.length;
|
||||
if (this.options.resetOnPlay) {
|
||||
for (var i=0; i<this.animators.length; i++) {
|
||||
this.animators[i].jumpTo(1);
|
||||
}
|
||||
}
|
||||
this.advance();
|
||||
},
|
||||
// if we have just play()'d, then call reverse(), and vice versa
|
||||
toggle: function() {
|
||||
if (this.forwards) {
|
||||
this.seekTo(0);
|
||||
} else {
|
||||
this.seekTo(1);
|
||||
}
|
||||
},
|
||||
// internal: install an event listener on an animator's onComplete option
|
||||
// to trigger the next animator
|
||||
listenTo: function(animator) {
|
||||
var oldOnComplete = animator.options.onComplete;
|
||||
var _this = this;
|
||||
animator.options.onComplete = function() {
|
||||
if (oldOnComplete) oldOnComplete.call(animator);
|
||||
_this.advance();
|
||||
}
|
||||
},
|
||||
// play the next animator
|
||||
advance: function() {
|
||||
if (this.forwards) {
|
||||
if (this.animators[this.current + 1] == null) return;
|
||||
this.current++;
|
||||
this.animators[this.current].play();
|
||||
} else {
|
||||
if (this.animators[this.current - 1] == null) return;
|
||||
this.current--;
|
||||
this.animators[this.current].reverse();
|
||||
}
|
||||
},
|
||||
// this function is provided for drop-in compatibility with Animator objects,
|
||||
// but only accepts 0 and 1 as target values
|
||||
seekTo: function(target) {
|
||||
if (target <= 0) {
|
||||
this.forwards = false;
|
||||
this.animators[this.current].seekTo(0);
|
||||
} else {
|
||||
this.forwards = true;
|
||||
this.animators[this.current].seekTo(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// an Accordion is a class that creates and controls a number of Animators. An array of elements is passed in,
|
||||
// and for each element an Animator and a activator button is created. When an Animator's activator button is
|
||||
// clicked, the Animator and all before it seek to 0, and all Animators after it seek to 1. This can be used to
|
||||
// create the classic Accordion effect, hence the name.
|
||||
// see setOptions for arguments
|
||||
function Accordion(options) {
|
||||
this.setOptions(options);
|
||||
var selected = this.options.initialSection, current;
|
||||
if (this.options.rememberance) {
|
||||
current = document.location.hash.substring(1);
|
||||
}
|
||||
this.rememberanceTexts = [];
|
||||
this.ans = [];
|
||||
var _this = this;
|
||||
for (var i=0; i<this.options.sections.length; i++) {
|
||||
var el = this.options.sections[i];
|
||||
var an = new Animator(this.options.animatorOptions);
|
||||
var from = this.options.from + (this.options.shift * i);
|
||||
var to = this.options.to + (this.options.shift * i);
|
||||
an.addSubject(new NumericalStyleSubject(el, this.options.property, from, to, this.options.units));
|
||||
an.jumpTo(0);
|
||||
var activator = this.options.getActivator(el);
|
||||
activator.index = i;
|
||||
activator.onclick = function(){_this.show(this.index)};
|
||||
this.ans[this.ans.length] = an;
|
||||
this.rememberanceTexts[i] = activator.innerHTML.replace(/\s/g, "");
|
||||
if (this.rememberanceTexts[i] === current) {
|
||||
selected = i;
|
||||
}
|
||||
}
|
||||
this.show(selected);
|
||||
}
|
||||
|
||||
Accordion.prototype = {
|
||||
// apply defaults
|
||||
setOptions: function(options) {
|
||||
this.options = Object.extend({
|
||||
// REQUIRED: an array of elements to use as the accordion sections
|
||||
sections: null,
|
||||
// a function that locates an activator button element given a section element.
|
||||
// by default it takes a button id from the section's "activator" attibute
|
||||
getActivator: function(el) {return document.getElementById(el.getAttribute("activator"))},
|
||||
// shifts each animator's range, for example with options {from:0,to:100,shift:20}
|
||||
// the animators' ranges will be 0-100, 20-120, 40-140 etc.
|
||||
shift: 0,
|
||||
// the first page to show
|
||||
initialSection: 0,
|
||||
// if set to true, document.location.hash will be used to preserve the open section across page reloads
|
||||
rememberance: true,
|
||||
// constructor arguments to the Animator objects
|
||||
animatorOptions: {}
|
||||
}, options || {});
|
||||
},
|
||||
show: function(section) {
|
||||
for (var i=0; i<this.ans.length; i++) {
|
||||
this.ans[i].seekTo(i > section ? 1 : 0);
|
||||
}
|
||||
if (this.options.rememberance) {
|
||||
document.location.hash = this.rememberanceTexts[section];
|
||||
}
|
||||
}
|
||||
}
|
17
js/libs/soundmanager/demo/360-player/script/excanvas.js
Normal file
BIN
js/libs/soundmanager/demo/_image/360ui-screenshot1.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
js/libs/soundmanager/demo/_image/360ui-screenshot2.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
js/libs/soundmanager/demo/_image/360ui-screenshot3.png
Normal file
After Width: | Height: | Size: 9.7 KiB |
BIN
js/libs/soundmanager/demo/_image/360ui-screenshot4.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
js/libs/soundmanager/demo/_image/8tracks-logo.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
js/libs/soundmanager/demo/_image/discogs.gif
Normal file
After Width: | Height: | Size: 544 B |
BIN
js/libs/soundmanager/demo/_image/flash9-dark.png
Normal file
After Width: | Height: | Size: 240 B |
BIN
js/libs/soundmanager/demo/_image/flash9.png
Normal file
After Width: | Height: | Size: 285 B |
BIN
js/libs/soundmanager/demo/_image/getsatisfaction-icon.gif
Normal file
After Width: | Height: | Size: 89 B |
BIN
js/libs/soundmanager/demo/_image/hue_thumb.png
Normal file
After Width: | Height: | Size: 140 B |
BIN
js/libs/soundmanager/demo/_image/lastfm.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
js/libs/soundmanager/demo/_image/mixcrate.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
js/libs/soundmanager/demo/_image/muxtape-logo.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
js/libs/soundmanager/demo/_image/new-bw.png
Normal file
After Width: | Height: | Size: 201 B |
BIN
js/libs/soundmanager/demo/_image/new-dark.png
Normal file
After Width: | Height: | Size: 205 B |
BIN
js/libs/soundmanager/demo/_image/new.png
Normal file
After Width: | Height: | Size: 228 B |
BIN
js/libs/soundmanager/demo/_image/opera.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
js/libs/soundmanager/demo/_image/picker_thumb.png
Normal file
After Width: | Height: | Size: 136 B |
BIN
js/libs/soundmanager/demo/_image/slider-1.png
Normal file
After Width: | Height: | Size: 887 B |
BIN
js/libs/soundmanager/demo/_image/slider-bar.gif
Normal file
After Width: | Height: | Size: 101 B |
BIN
js/libs/soundmanager/demo/_image/slider.png
Normal file
After Width: | Height: | Size: 570 B |
After Width: | Height: | Size: 5.8 KiB |
BIN
js/libs/soundmanager/demo/_image/speaker.png
Normal file
After Width: | Height: | Size: 6.3 KiB |
BIN
js/libs/soundmanager/demo/_image/wedge.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
js/libs/soundmanager/demo/_mp3/1hz-10khz-sweep.mp3
Normal file
BIN
js/libs/soundmanager/demo/_mp3/440hz.mp3
Normal file
BIN
js/libs/soundmanager/demo/_mp3/880hz.mp3
Normal file
BIN
js/libs/soundmanager/demo/_mp3/background0.mp3
Normal file
BIN
js/libs/soundmanager/demo/_mp3/background1.mp3
Normal file
BIN
js/libs/soundmanager/demo/_mp3/background2.mp3
Normal file
BIN
js/libs/soundmanager/demo/_mp3/bass.mp3
Normal file
BIN
js/libs/soundmanager/demo/_mp3/button-0.mp3
Normal file
BIN
js/libs/soundmanager/demo/_mp3/button-1.mp3
Normal file
BIN
js/libs/soundmanager/demo/_mp3/click-high.mp3
Normal file
BIN
js/libs/soundmanager/demo/_mp3/click-low.mp3
Normal file
BIN
js/libs/soundmanager/demo/_mp3/coins.mp3
Normal file
BIN
js/libs/soundmanager/demo/_mp3/fancy-beer-bottle-pop.mp3
Normal file
BIN
js/libs/soundmanager/demo/_mp3/going_outside.mp3
Normal file
BIN
js/libs/soundmanager/demo/_mp3/mak.mp3
Normal file
BIN
js/libs/soundmanager/demo/_mp3/mouseover.mp3
Normal file
BIN
js/libs/soundmanager/demo/_mp3/mouseover2.mp3
Normal file
BIN
js/libs/soundmanager/demo/_mp3/mouseover3.mp3
Normal file
BIN
js/libs/soundmanager/demo/_mp3/office_lobby.mp3
Normal file
BIN
js/libs/soundmanager/demo/_mp3/rain.mp3
Normal file
BIN
js/libs/soundmanager/demo/_mp3/select.mp3
Normal file
BIN
js/libs/soundmanager/demo/_mp3/sine, square, sawtooth, rando.mp3
Normal file
BIN
js/libs/soundmanager/demo/_mp3/walking.mp3
Normal file
74
js/libs/soundmanager/demo/animation-1/css/animation.css
Normal file
|
@ -0,0 +1,74 @@
|
|||
body {
|
||||
font-size:75%;
|
||||
}
|
||||
|
||||
h1, h2, h3 {
|
||||
font:normal 3em "Helvetica Neue",helvetica,georgia,"times new roman","Arial Rounded MT Bold",verdana,tahoma,arial,"sans serif";
|
||||
font-weight:normal;
|
||||
margin-bottom:0px;
|
||||
}
|
||||
|
||||
h1, h2 {
|
||||
letter-spacing:-1px; /* zomg web x.0! ;) */
|
||||
}
|
||||
|
||||
h1, h2, h3 {
|
||||
padding-bottom:1px;
|
||||
margin-bottom:0.25em;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-top:0px;
|
||||
margin-bottom:0px;
|
||||
background-color:#666;
|
||||
color:#ccc;
|
||||
margin-left:-5px;
|
||||
padding-left:5px;
|
||||
padding-right:5px;
|
||||
padding-bottom:5px;
|
||||
}
|
||||
|
||||
h1,
|
||||
h1 a {
|
||||
color:#fff;
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
h1 a:hover {
|
||||
text-decoration:underline;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size:2em;
|
||||
margin-top:1em;
|
||||
background-color:#aaa;
|
||||
color:#fff;
|
||||
padding:5px;
|
||||
margin-left:-5px;
|
||||
min-width:23em;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size:1.65em;
|
||||
margin-top:0.5em;
|
||||
margin-bottom:0.25em;
|
||||
color:#333;
|
||||
min-width:28em;
|
||||
}
|
||||
|
||||
h3 a {
|
||||
font-size:small;
|
||||
}
|
||||
|
||||
h4 {
|
||||
color:#444;
|
||||
}
|
||||
p {
|
||||
font:normal 1em/2em verdana,tahoma,arial,"sans serif";
|
||||
}
|
||||
|
||||
.balls img {
|
||||
position:absolute;
|
||||
width:12px;
|
||||
height:12px;
|
||||
}
|
BIN
js/libs/soundmanager/demo/animation-1/image/ball.gif
Normal file
After Width: | Height: | Size: 549 B |
46
js/libs/soundmanager/demo/animation-1/index.html
Normal file
|
@ -0,0 +1,46 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<link rel="stylesheet" href="../template/template.css" media="screen" />
|
||||
<link rel="stylesheet" href="css/animation.css" media="screen" />
|
||||
<script type="text/javascript" src="../../script/soundmanager2-nodebug-jsmin.js"></script>
|
||||
<script type="text/javascript" src="script/animation.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div style="margin-right:43em">
|
||||
|
||||
<h1>Interval-based animation (with sound)</h1>
|
||||
|
||||
<p>
|
||||
Click + drag for fun.
|
||||
</p>
|
||||
|
||||
<h2>Speeding Up ExternalInterface: Keep .swf in view</h2>
|
||||
|
||||
<p>SoundManager 2 now incorporates a "high performance" mode, which has been shown to noticeably improve timing and frequency of flash callbacks. This is important for timing, reducing delay between a JS call and the sound being played, etc.</p>
|
||||
|
||||
<p>To reduce audio delay and timing issues from slow JS/Flash communication, SM2 will try to ensure that the flash movie is visible on screen at all times. If hidden or otherwise off-screen, Flash will be given lower priority and thus JS/flash "lag" (ie., delay) will be introduced when trying to play audio "in sync."</p>
|
||||
|
||||
<p>Generally, positioning the flash movie using position:fixed and bottom/left or bottom/right 0px is the less-intrusive option.</p>
|
||||
|
||||
<p style="margin:0px;padding:0px">
|
||||
<input id="useMouse" name="usemouse" value="usemouse" type="checkbox"> Throw from mouse
|
||||
</p>
|
||||
<p style="margin:0px;padding:0px">
|
||||
<button id="b-start" onclick="startAnimation()" disabled="disabled">Start</button>
|
||||
<button id="b-stop" onclick="stopAnimation()" disabled="disabled">Stop</button>
|
||||
</p>
|
||||
|
||||
|
||||
<p>Sound source: <a href="http://freesound.iua.upf.edu/samplesViewSingle.php?id=19987">"Acclivity"</a>, Free Sound Project</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="ball-container" class="balls">
|
||||
<img src="image/ball.gif" alt="" />
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
189
js/libs/soundmanager/demo/animation-1/script/animation.js
Normal file
|
@ -0,0 +1,189 @@
|
|||
var balls = [];
|
||||
var canvasX = 0;
|
||||
var canvasY = 0;
|
||||
var timer = null;
|
||||
var m_lastX = 0;
|
||||
var m_lastY = 0;
|
||||
var M_SPACE = 24;
|
||||
var B_VMIN = 5;
|
||||
var B_VMAX = 5;
|
||||
var B_WIDTH = 13;
|
||||
var B_HEIGHT = 13;
|
||||
var useMouse = null;
|
||||
var ballSound = null;
|
||||
var ballPopSound = null;
|
||||
|
||||
function rnd(n) {
|
||||
return Math.random()*n;
|
||||
}
|
||||
|
||||
function rndI(n) {
|
||||
return parseInt(rnd(n));
|
||||
}
|
||||
|
||||
function createBall(oParent) {
|
||||
oParent.appendChild(balls[0].cloneNode(true));
|
||||
initBall(balls[balls.length-1],balls.length);
|
||||
}
|
||||
|
||||
function createBallAtMouse(e) {
|
||||
e = e?e:event;
|
||||
createBall(document.getElementById('ball-container'));
|
||||
with (balls[balls.length-1]) {
|
||||
_x = e.clientX;
|
||||
_y = e.clientY;
|
||||
if (useMouse.checked != false) {
|
||||
_vX = (m_lastX-e.clientX)*-0.7;
|
||||
_vY = (m_lastY-e.clientY)*-0.7;
|
||||
} else {
|
||||
_vX = 0;
|
||||
_vY = 0;
|
||||
}
|
||||
}
|
||||
moveBall(balls[balls.length-1]);
|
||||
}
|
||||
|
||||
function initBall(oBall,i) {
|
||||
oBall._id = 'ball'+i;
|
||||
oBall._active = true;
|
||||
oBall._x = rnd(canvasX);
|
||||
oBall._y = rnd(canvasY);
|
||||
oBall._vX = B_VMIN+rnd(B_VMAX)*(Math.random()>0.5?1:-1);
|
||||
oBall._vY = B_VMIN+rnd(B_VMAX);
|
||||
oBall.style.display = 'block';
|
||||
}
|
||||
|
||||
function moveBall(oBall) {
|
||||
oBall._x += oBall._vX;
|
||||
oBall._y += (oBall._vY++); // gravity!
|
||||
var bounce = false;
|
||||
if ((oBall._vX>0 && oBall._x+oBall._vX+B_WIDTH>canvasX) || (oBall._vX<0 && oBall._x+oBall._vX<0)) {
|
||||
oBall._vX *= -1;
|
||||
bounce = true;
|
||||
}
|
||||
if ((oBall._vY>0 && oBall._y+oBall._vY+B_HEIGHT>canvasY) || (oBall._vY<0 && oBall._y+oBall._vY<0)) {
|
||||
// bounce on Y axis - with resistance on both axes
|
||||
if (oBall._vY>0) oBall._y = canvasY-B_HEIGHT; // bounce exactly from bottom
|
||||
oBall._vY *= -(oBall._vY>1?0.6:1);
|
||||
bounce = true;
|
||||
if (Math.abs(oBall._vX)>0.5) {
|
||||
oBall._vX *= 0.85;
|
||||
} else {
|
||||
oBall._vX = 0;
|
||||
}
|
||||
if (Math.abs(oBall._vY)<=3 && Math.abs(oBall._vX==0)) {
|
||||
oBall._active = false;
|
||||
bounce = false;
|
||||
ballPopSound.play();
|
||||
oBall.style.display = 'none';
|
||||
}
|
||||
}
|
||||
oBall.style.left = oBall._x+'px';
|
||||
oBall.style.top = oBall._y+'px';
|
||||
if (bounce) ballSound.play({pan:getPan(oBall._x,canvasX)});
|
||||
}
|
||||
|
||||
function getPan(x,canvasX) {
|
||||
var pos = x/canvasX;
|
||||
var pan = null;
|
||||
if (pos<=0.4) {
|
||||
pan = Math.floor(-100+(pos/0.4*100));
|
||||
} else if (pos>0.4 && pos<=0.5) {
|
||||
pan = 0;
|
||||
} else {
|
||||
pan = Math.floor(pos*100);
|
||||
}
|
||||
return pan;
|
||||
}
|
||||
|
||||
function animateStuff() {
|
||||
for (var i=balls.length; i--;) {
|
||||
if (balls[i]._active) moveBall(balls[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function startAnimation() {
|
||||
if (!timer) timer = setInterval(animateStuff,20);
|
||||
document.getElementById('b-start').disabled = true;
|
||||
document.getElementById('b-stop').disabled = false;
|
||||
}
|
||||
|
||||
function stopAnimation() {
|
||||
if (!timer) return false;
|
||||
clearInterval(timer);
|
||||
timer = null;
|
||||
document.getElementById('b-start').disabled = false;
|
||||
document.getElementById('b-stop').disabled = true;
|
||||
}
|
||||
|
||||
function mouseDown(e) {
|
||||
e = e?e:event;
|
||||
m_lastX = e.clientX;
|
||||
m_lastY = e.clientY;
|
||||
document.onmousemove = mouseMove;
|
||||
document.onmouseup = mouseUp;
|
||||
return false;
|
||||
}
|
||||
|
||||
function mouseMove(e) {
|
||||
e = e?e:event;
|
||||
if (Math.abs(e.clientX-m_lastX)>M_SPACE || Math.abs(e.clientY-m_lastY)>M_SPACE) {
|
||||
createBallAtMouse(e);
|
||||
m_lastX = e.clientX;
|
||||
m_lastY = e.clientY;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function mouseUp() {
|
||||
document.onmousemove = null;
|
||||
document.onmouseup = null;
|
||||
}
|
||||
|
||||
function init() {
|
||||
ballSound = soundManager.createSound({
|
||||
id: 'ballSound',
|
||||
url: '../animation/audio/fingerplop.mp3',
|
||||
volume: 50,
|
||||
multiShot: true,
|
||||
autoLoad: true
|
||||
});
|
||||
ballPopSound = soundManager.createSound({
|
||||
id: 'ballPopSound',
|
||||
url: '../animation/audio/fingerplop2.mp3',
|
||||
volume: 50,
|
||||
multiShot: true,
|
||||
autoLoad: true
|
||||
});
|
||||
balls = document.getElementById('ball-container').getElementsByTagName('img');
|
||||
for (var i=balls.length; i--;) {
|
||||
initBall(balls[i],i);
|
||||
}
|
||||
useMouse = document.getElementById('useMouse');
|
||||
useMouse.checked = true;
|
||||
getWindowCoords();
|
||||
startAnimation();
|
||||
document.onmousedown = mouseDown;
|
||||
}
|
||||
|
||||
// I know this is kinda broken in Opera.
|
||||
getWindowCoords = (navigator.userAgent.toLowerCase().indexOf('opera')>0||navigator.appVersion.toLowerCase().indexOf('safari')!=-1)?function() {
|
||||
canvasX = window.innerWidth;
|
||||
canvasY = window.innerHeight;
|
||||
}:function() {
|
||||
canvasX = document.documentElement.clientWidth||document.body.clientWidth||document.body.scrollWidth;
|
||||
canvasY = document.documentElement.clientHeight||document.body.clientHeight||document.body.scrollHeight;
|
||||
}
|
||||
|
||||
window.onresize = getWindowCoords;
|
||||
|
||||
soundManager.flashVersion = 9;
|
||||
soundManager.url = '../../swf/';
|
||||
soundManager.useHighPerformance = true;
|
||||
soundManager.debugMode = false; // disable debug mode
|
||||
soundManager.defaultOptions.multiShot = true;
|
||||
|
||||
soundManager.onload = function() {
|
||||
// soundManager is ready to use (create sounds and so on)
|
||||
init();
|
||||
}
|
BIN
js/libs/soundmanager/demo/animation-2a/bg-land.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
js/libs/soundmanager/demo/animation-2a/bg-sky.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
js/libs/soundmanager/demo/animation-2a/cursor-10.cur
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
js/libs/soundmanager/demo/animation-2a/cursor-11.cur
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
js/libs/soundmanager/demo/animation-2a/cursor-3.cur
Normal file
After Width: | Height: | Size: 4.2 KiB |