merge with Robs changes
2
Gemfile
|
@ -7,7 +7,7 @@ gem 'rails', '3.2.17'
|
||||||
# gem 'rails', :git => 'git://github.com/rails/rails.git'
|
# gem 'rails', :git => 'git://github.com/rails/rails.git'
|
||||||
|
|
||||||
gem 'devise'
|
gem 'devise'
|
||||||
gem 'redis'
|
gem 'redis', '2.2.2'
|
||||||
gem 'pg'
|
gem 'pg'
|
||||||
gem 'cancan'
|
gem 'cancan'
|
||||||
gem 'formula'
|
gem 'formula'
|
||||||
|
|
|
@ -117,7 +117,7 @@ GEM
|
||||||
rake (10.3.2)
|
rake (10.3.2)
|
||||||
rdoc (3.12.2)
|
rdoc (3.12.2)
|
||||||
json (~> 1.4)
|
json (~> 1.4)
|
||||||
redis (3.0.7)
|
redis (2.2.2)
|
||||||
sass (3.3.7)
|
sass (3.3.7)
|
||||||
sass-rails (3.2.6)
|
sass-rails (3.2.6)
|
||||||
railties (~> 3.2.0)
|
railties (~> 3.2.0)
|
||||||
|
@ -160,6 +160,6 @@ DEPENDENCIES
|
||||||
pg
|
pg
|
||||||
rails (= 3.2.17)
|
rails (= 3.2.17)
|
||||||
rails3-jquery-autocomplete
|
rails3-jquery-autocomplete
|
||||||
redis
|
redis (= 2.2.2)
|
||||||
sass-rails
|
sass-rails
|
||||||
uglifier (>= 1.0.3)
|
uglifier (>= 1.0.3)
|
||||||
|
|
47
Gemfile~
|
@ -1,47 +0,0 @@
|
||||||
source 'https://rubygems.org'
|
|
||||||
|
|
||||||
gem 'rails', '3.2.17'
|
|
||||||
|
|
||||||
# Bundle edge Rails instead:
|
|
||||||
# gem 'rails', :git => 'git://github.com/rails/rails.git'
|
|
||||||
|
|
||||||
gem 'devise'
|
|
||||||
gem 'redis'
|
|
||||||
gem 'pg'
|
|
||||||
gem 'cancan'
|
|
||||||
gem 'formula'
|
|
||||||
gem 'formtastic'
|
|
||||||
gem 'json'
|
|
||||||
gem 'rails3-jquery-autocomplete'
|
|
||||||
gem 'best_in_place'
|
|
||||||
gem 'therubyracer' #optional
|
|
||||||
#gem 'rb-readline'
|
|
||||||
|
|
||||||
# Gems used only for assets and not required
|
|
||||||
# in production environments by default.
|
|
||||||
group :assets do
|
|
||||||
gem 'sass-rails'
|
|
||||||
gem 'coffee-rails', '~> 3.2.1'
|
|
||||||
|
|
||||||
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
|
|
||||||
# gem 'therubyracer'
|
|
||||||
|
|
||||||
gem 'uglifier', '>= 1.0.3'
|
|
||||||
end
|
|
||||||
|
|
||||||
gem 'jquery-rails', '2.1.2'
|
|
||||||
|
|
||||||
# To use ActiveModel has_secure_password
|
|
||||||
# gem 'bcrypt-ruby', '~> 3.0.0'
|
|
||||||
|
|
||||||
# To use Jbuilder templates for JSON
|
|
||||||
gem 'jbuilder', '0.8.2'
|
|
||||||
|
|
||||||
# Use unicorn as the web server
|
|
||||||
# gem 'unicorn'
|
|
||||||
|
|
||||||
# Deploy with Capistrano
|
|
||||||
# gem 'capistrano'
|
|
||||||
|
|
||||||
# To use debugger
|
|
||||||
# gem 'ruby-debug19', :require => 'ruby-debug'
|
|
BIN
app/assets/images/synapsevisualize.png
Normal file
After Width: | Height: | Size: 909 B |
|
@ -0,0 +1,71 @@
|
||||||
|
== 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
|
||||||
|
|
||||||
|
* 100% Flash-free MP3 + MP4/AAC where supported
|
||||||
|
* Compatible with Apple iPad 3.2, iPhone/iOS 4 and newer
|
||||||
|
* Fallback to Flash for MP3/MP4 support, as needed
|
||||||
|
* SM2 API is transparent; HTML5/flash switching handled internally
|
||||||
|
* HTML5 API support approximates Flash 8 API features
|
||||||
|
* Some other formats (WAV/OGG) supported via HTML5, depending on browser
|
||||||
|
* See "useHTML5Audio" property 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:
|
||||||
|
|
||||||
|
* SoundCloud / The Cloud Player
|
||||||
|
* last.fm
|
||||||
|
* Opera (media player component)
|
||||||
|
* 8tracks
|
||||||
|
* Discogs
|
||||||
|
* The Hype Machine
|
||||||
|
* nyan.cat
|
||||||
|
* turntable.fm
|
||||||
|
* AudioGalaxy
|
||||||
|
|
||||||
|
== Project home, documentation, live demos etc.:
|
||||||
|
|
||||||
|
http://www.schillmania.com/projects/soundmanager2/
|
||||||
|
|
||||||
|
== Compiling JS builds (-nodebug, -jsmin) and Flash components, AS2/AS3 to SWF
|
||||||
|
|
||||||
|
An Ant build file defines the tasks for compiling JS and SWF components, useful if you make changes to the SM2 source and want to recompile.
|
||||||
|
Google's Closure Compiler is used for the JS. AS2 compilation is done by MTASC, and AS3 is handled by Adobe's Open Source Flex SDK (mxmlc) compiler.
|
||||||
|
Refer to the build.xml file for compiler downloads and path definitions.
|
||||||
|
|
||||||
|
== Versioning / Development Notes
|
||||||
|
|
||||||
|
Releases are versioned by date, e.g., V2.97a.20110424 and are tagged as such.*
|
||||||
|
The latest official release is always on trunk/master.
|
||||||
|
Post-release development builds may be available on the appropriate +DEV branch, eg., V2.97a.20110801+DEV
|
||||||
|
|
||||||
|
== Forks and Pull Requests
|
||||||
|
|
||||||
|
Firstly, thank you for wanting to contribute! Bug fixes and tweaks are welcomed, particularly if they follow the general coding style of the project.
|
||||||
|
If making a pull request, use the project's current +DEV development branch as the merge target instead of "master", if possible (please and thank-you.)
|
||||||
|
|
||||||
|
* SoundManager 2 has been at "version" 2.97 for a long time, because 2.97 was arguably the best llama-ass-whipping version of WinAmp. (WinAmp 3 was not as good, and WinAmp 5 was "the best of 2 and 3 combined.") This MP3 player was my favourite Windows app during the 90's, and is missed as there's nothing quite like it on OS X where I spend most of my time these days.
|
After Width: | Height: | Size: 329 B |
After Width: | Height: | Size: 422 B |
After Width: | Height: | Size: 329 B |
After Width: | Height: | Size: 339 B |
After Width: | Height: | Size: 441 B |
After Width: | Height: | Size: 477 B |
After Width: | Height: | Size: 441 B |
After Width: | Height: | Size: 368 B |
After Width: | Height: | Size: 889 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 881 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1,009 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1,001 B |
After Width: | Height: | Size: 1.3 KiB |
|
@ -0,0 +1,156 @@
|
||||||
|
/* larger canvas, spectrum + EQ visualization and other items */
|
||||||
|
|
||||||
|
.ui360-vis,
|
||||||
|
.ui360-vis .sm2-360ui,
|
||||||
|
.sm2-inline-list .ui360-vis {
|
||||||
|
/* size of the container for the circle, etc. */
|
||||||
|
width:256px;
|
||||||
|
height:256px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui360-vis {
|
||||||
|
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 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm2-inline-list .ui360-vis {
|
||||||
|
cursor:pointer
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui360-vis a {
|
||||||
|
font:14px "helvetica neue",helvetica,monaco,lucida,terminal,monospace;
|
||||||
|
white-space:nowrap;
|
||||||
|
text-indent:0px; /* undo inline style */
|
||||||
|
top:46%; /* ehh. */
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm2-inline-list .ui360-vis a {
|
||||||
|
line-height:256px;
|
||||||
|
top:auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui360-vis .sm2-360ui {
|
||||||
|
margin-left:-256px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui360-vis .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-vis,
|
||||||
|
.sm2-inline-list .ui360-vis .sm2-360ui {
|
||||||
|
margin-left:0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm2-inline-list .ui360-vis {
|
||||||
|
margin:8px 13px 7px 0px;
|
||||||
|
padding-left:0px;
|
||||||
|
background-position:50% 50%; /* initial play button position */
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm2-inline-list .ui360-vis .sm2-360ui {
|
||||||
|
border:1px solid #eee;
|
||||||
|
/* offset the border */
|
||||||
|
margin-left:-1px;
|
||||||
|
margin-top:-1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm2-inline-list .ui360-vis a {
|
||||||
|
position:absolute;
|
||||||
|
display:inline;
|
||||||
|
left:0px;
|
||||||
|
bottom:0px;
|
||||||
|
top:1px;
|
||||||
|
width:100%; /* 2px padding in box */
|
||||||
|
height:99%; /* dumb vertical hack */
|
||||||
|
*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;
|
||||||
|
border-radius:0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm2-inline-list .ui360 a:hover {
|
||||||
|
background-color:transparent; /* reset */
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm2-inline-list .ui360-vis:hover .sm2-360ui,
|
||||||
|
.sm2-inline-list .ui360-vis a.sm2_link:hover,
|
||||||
|
.sm2-inline-list .ui360-vis a.sm2_link:active,
|
||||||
|
.sm2-inline-list .ui360-vis a.sm2_link:focus {
|
||||||
|
background-color:transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm2-inline-list .ui360-vis:hover a.sm2_link {
|
||||||
|
background-color:#fafafa;
|
||||||
|
*background-color:transparent; /* eh, screw IE. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use a bigger loading image for this layout */
|
||||||
|
|
||||||
|
.ui360-vis .sm2-360btn,
|
||||||
|
.ui360-vis .sm2-360ui.sm2_paused .sm2-360btn,
|
||||||
|
.ui360-vis .sm2-360ui.sm2_playing .sm2-360btn {
|
||||||
|
width:48px;
|
||||||
|
height:48px;
|
||||||
|
margin-left:-24px;
|
||||||
|
margin-top:-24px;
|
||||||
|
border-radius: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui360-vis,
|
||||||
|
.ui360-vis .sm2-360ui.sm2_paused .sm2-360btn,
|
||||||
|
.ui360-vis .sm2-360btn-default {
|
||||||
|
background:transparent url(360-button-vis-play.png) no-repeat 50% 50%;
|
||||||
|
background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAABuVBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADv7++lpaXr6+uAgIDk5OQzMzPt7e1tbW3n5+dgYGDW1tZNTU10dHQ5OTnw8PCvr6/e3t6JiYlAQEDb29vo6OgrKyuqqqrq6uq4uLjf399AQEDGxsbq6uqAgIDY2Nje3t61tbXp6enU1NTu7u7r6+vl5eXt7e2fn5/n5+fDw8Ph4eHv7+/t7e3CwsLW1tbu7u7b29vw8PDm5uYgICDp6enY2Nji4uLo6Ojm5uakpKTS0tLPz8/h4eHw8PDs7Ozj4+Pa2trg4ODx8fHT09Pk5OTPz8/S0tLBwcGmpqawsLCOjo7h4eHn5+fo6OgAAADY2NjNzc3n5+cAAADd3d3Gxsbu7u7t7e0AAADX19fl5eXi4uLf39/Hx8fn5+fs7Ozg4ODR0dHX19e4uLjv7+/z8/P09PTy8vL19fXv7+/n5+fx8fH29vbs7Ozq6urm5ubo6Ojw8PDu7u7p6enr6+sAAAB/f3/Z2dn39/fh4eGOjo4ODg7t7e3l5eWWlpba2tqjo6NVVVXk5OTe3t65ubnMzMzExMTf39/GxsampqZiYmJNcTiZAAAAbXRSTlMAAQIEAwcFCAb5EdAImAXpB6oIUAoLCfsgZQ0EVrsGEr4ZYQgbsgpUYxikNd/aatQQli+R7rlUUdas6+8I+VaFruoOOV/S8Nq5sWL8UqmKUFsuHyTcrtsJm0z7C49V3NMKkdKXuk7S7oVeVSv7tAAEVwAAAu5JREFUeF6llmVz3DwURmNLsr1pmJmZmZmxzMwsybS8gXJfhl9cKXbHEK+TmZ4P/nDnOXN1NbalHD8CQ7QRGDmhnIQhBDYQnkhheRECSVIQQrLMHookAciUkHhBw1zVwuLShcJIpPDC0uJC1VxDQTaFx1srSvM3DUxU1TRVlWBjM7+0opUrQaupLSnrLK7ELIepwaCYmbiyuLOspJY38eeLykdGxzDhYQfKCmOjI+VFPkMQYF7NZD0l2DgFJrR+siYPegxBzBvqeoQxpgGw8qOuoTz3HGw9udUPCaFZIORhdS5blZOHjXWDBIdABusanb0S4MpqEw4XcNPqCrQFQQTN+XwPQ8CY5jcDUbB3KLdlg6hnQDZacqEgWA3a2rF6Jri9zWohwI6dXXK2QHZ3OqBw0qC7B6vnAPd0sxZMkHr7VNPD34YZgNrXK3EBSgPU9HJ4eIQDDDogQS4ow4QJxy4+MmKs4oYJZFhhggjQuMoKHoHzn3bsQx1HQOTClOkXLP6lviZTtjCjmn7B5g/izqszliBHTB+HDhl3PSJbwnxSS3n45HDkVLXkvCWg5Uws7eHgJ98/uKqxzLI9w3o6oXuwhd+OPNVEet0WtnU9/sWNJfz1u6cY1/VtLghQuRgk/PmBmT7hogJPXo3L8YQed3Nw8PWfuB89Eb8scUGUrl33DfH/N93BGeH6NUnkArh1O5FOuNETp2GR27cAE/iaJu6mz8HdCQnan+i96XQmdgaZ9PQ9+xMVoPJgNhrNhBKNzj5Q+E/AavH4SSz6OZRo7Mlj3oDDp7jyPJoKJfr8CpvAOUrQi6eppJaVZOrpCwTdP1cgr93UjKxoN9dka2KX8ealZtBADO3lG2+e7xRAd7Y0igOg2tYdBKD/CBIBenf/lYGJD2y8uv8OgaBDDkry3v57SlQXhL7f35OlwJOXGUBBl571JykmzCIE02T/s0tIASyf/R6Arr59fcM62G+8fnsVhdwFwq4Ov345Of/15wd0RYY81HHUTQAAAABJRU5ErkJggg==);
|
||||||
|
*background-image:url(360-button-vis-play.png);
|
||||||
|
_background:transparent url(360-button-vis-play.gif) no-repeat 50% 50%;
|
||||||
|
cursor:pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui360-vis:hover .sm2-360btn,
|
||||||
|
.ui360-vis .sm2-360btn-default:hover,
|
||||||
|
.ui360-vis .sm2-360ui.sm2_paused .sm2-360btn:hover {
|
||||||
|
background:transparent url(360-button-vis-play-light.png) no-repeat 50% 50%;
|
||||||
|
_background:transparent url(360-button-vis-play.gif) no-repeat 50% 50%;
|
||||||
|
cursor:pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.ui360-vis .sm2-360ui.sm2_playing .sm2-360btn:hover,
|
||||||
|
.ui360-vis .sm2-360btn-playing:hover {
|
||||||
|
background:transparent url(360-button-vis-pause-light.png) no-repeat 50% 50%;
|
||||||
|
_background:transparent url(360-button-vis-pause-light.gif) no-repeat 50% 50%;
|
||||||
|
cursor:pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui360-vis {
|
||||||
|
/* non-JS / before-loaded state */
|
||||||
|
background-position: 21% 50%;
|
||||||
|
_background:transparent url(360-button-vis-play.gif) no-repeat 21% 50%; /* IE 6-only: special crap GIF */
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui360-vis .sm2-360btn-default {
|
||||||
|
/* real button, post-loaded state */
|
||||||
|
_background:transparent url(360-button-vis-play.gif) no-repeat 50% 50%; /* IE 6-only: special crap GIF */
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui360-vis .sm2-360ui.sm2_dragging .sm2-360btn {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
|
@ -0,0 +1,271 @@
|
||||||
|
/* General warning: Beta-ish. Code could be a bit cleaner. */
|
||||||
|
|
||||||
|
.ui360, /* entire UI */
|
||||||
|
.sm2-360ui { /* canvas container */
|
||||||
|
position:relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui360,
|
||||||
|
.sm2-360ui {
|
||||||
|
min-width:50px; /* should always be at least this. */
|
||||||
|
min-height:50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm2-360ui {
|
||||||
|
width:50px;
|
||||||
|
height:50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui360,
|
||||||
|
.ui360 * {
|
||||||
|
vertical-align:middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm2-360ui {
|
||||||
|
position:relative;
|
||||||
|
display:inline-block; /* firefox 3 et al */
|
||||||
|
float:left; /* IE 6+7, firefox 2 needs this, inline-block would work with fx3 and others */
|
||||||
|
*display:inline;
|
||||||
|
/*
|
||||||
|
clear:left;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm2-360ui.sm2_playing,
|
||||||
|
.sm2-360ui.sm2_paused {
|
||||||
|
/* bump on top when active */
|
||||||
|
z-index:10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui360 a { /* .sm2_link class added to playable links by SM2 */
|
||||||
|
float:left;
|
||||||
|
display:inline;
|
||||||
|
position:relative;
|
||||||
|
color:#000;
|
||||||
|
text-decoration:none;
|
||||||
|
left:3px; /* slight spacing on left UI */
|
||||||
|
top:18px; /* vertical align */
|
||||||
|
text-indent:50px; /* make room for UI at left */
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui360 a.sm2_link { /* SM2 has now started */
|
||||||
|
text-indent:0px; /* UI now in place. */
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui360 a,
|
||||||
|
.ui360 a:hover,
|
||||||
|
.ui360 a:focus {
|
||||||
|
padding:2px;
|
||||||
|
margin-left:-2px;
|
||||||
|
margin-top:-2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui360 a:hover,
|
||||||
|
.ui360 a:focus {
|
||||||
|
background:#eee;
|
||||||
|
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;
|
||||||
|
background-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==); /* old-skool bug: IE 9 won't catch mouse events otherwise. /smash */
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui360 .sm2-360btn {
|
||||||
|
position:absolute;
|
||||||
|
display:block;
|
||||||
|
top:50%;
|
||||||
|
left:50%;
|
||||||
|
/*
|
||||||
|
width:22px;
|
||||||
|
height:22px;
|
||||||
|
margin-left:-11px;
|
||||||
|
margin-top:-11px;
|
||||||
|
*/
|
||||||
|
/* by default, cover whole space. make smaller when playing. */
|
||||||
|
width:50px;
|
||||||
|
height:50px;
|
||||||
|
margin-left:-25px;
|
||||||
|
margin-top:-25px;
|
||||||
|
border-radius: 25px;
|
||||||
|
cursor:pointer;
|
||||||
|
z-index:3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui360 .sm2-360data {
|
||||||
|
display:inline-block;
|
||||||
|
font-family:helvetica;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm2-inline-block .ui360 .sm2-360btn,
|
||||||
|
.ui360 .sm2-360ui.sm2_playing .sm2-360btn,
|
||||||
|
.ui360 .sm2-360ui.sm2_paused .sm2-360btn {
|
||||||
|
/* smaller clickable button, in center */
|
||||||
|
width:22px;
|
||||||
|
height:22px;
|
||||||
|
margin-left:-11px;
|
||||||
|
margin-top:-11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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,
|
||||||
|
.ui360 .sm2-360ui.sm2_paused .sm2-360btn {
|
||||||
|
background:transparent url(360-button-play.png) no-reoeat;
|
||||||
|
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAABoUlEQVR42sWVu2oCQRhGU/s8gpVYJeQJNkZSbiH4QNuLlQZS21sJayGYaOEFVFDxNiremj9zig2uzk5YQpKFg8PMd75ZZle9E5Ff4e+Ll8tlQuNoPI2vUcCYOdbIxCmm9F5T0YgNMmS/LebSwWdNa7VayXq9ls1mI9vtVna7nQBj5lgjQxYHN7KY3QkiUbDf7+V4PMrpdArBHGtkyOJc3/n1mVaUUl+F5/PZSrABDi4dpmKH3QkixQEHlw5TsccZmsRCoSD1et1ajkuHqdg/HA5GKZPJCOTzeanVasYMLh2mYsXDIGAoDuG6rlSr1WCdBxrcsTIWazgrQiHS6bSRYJ3XDzeq2O/3+9Ltdm9IpVIhstmslEqlUAY36ii8ZrMpjUbjhmQyKeA4jhSLRWMGN+rhOZ1Oh8ANuVxOyuUy40hwo163RK/XeyPQbrdjgYNr/ILAYDB41Gf1wZnFAQfX+iM0HA5fxuPx+2g0Ej22QoYsDq61mGsymTxMp9NX/Sk2yJDFsRZfXpzXbDZ7WiwW3nw+9zUKGDPHGpkL5V//mn7OJyJZApyzeUS5AAAAAElFTkSuQmCC);
|
||||||
|
*background-image: url(360-button-play.png);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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: 14px 50%;
|
||||||
|
_background:transparent url(360-button-play.gif) no-repeat 14px 50%; /* IE 6-only: special crap GIF */
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui360 .sm2-360btn-default,
|
||||||
|
.ui360 .sm2-360ui.sm2_paused .sm2-360btn {
|
||||||
|
background-position:50% 50%;
|
||||||
|
_background:transparent url(360-button-play.gif) no-repeat 50% 50%; /* IE 6-only: special crap GIF */
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui360 .sm2-360btn-default,
|
||||||
|
.ui360 .sm2-360ui.sm2_paused .sm2-360btn {
|
||||||
|
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,
|
||||||
|
.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 {
|
||||||
|
/* inline player: minor tweak, tighten spacing */
|
||||||
|
margin-right:-2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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,132 @@
|
||||||
|
<!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="robots" content="noindex" />
|
||||||
|
<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.setup({
|
||||||
|
// path to directory containing SM2 SWF
|
||||||
|
url: '../../swf/'
|
||||||
|
});
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (threeSixtyPlayer.config.useWaveformData || threeSixtyPlayer.flash9Options.useEQData || threeSixtyPlayer.flash9Options.usePeakData) {
|
||||||
|
// even if HTML5 supports MP3, prefer flash so the visualization features can be used.
|
||||||
|
soundManager.preferFlash = 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 < 9 (too slow.) Data not implemented 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 ui360-vis"><a href="../../demo/mpc/audio/CRASH_1.mp3">Crash 1</a></div>
|
||||||
|
<div class="ui360 ui360-vis"><a href="../../demo/mpc/audio/CRASH_5.mp3">Crash 5</a></div>
|
||||||
|
<div class="ui360 ui360-vis"><a href="../../demo/mpc/audio/CRASH_6.mp3">Crash 6</a></div>
|
||||||
|
<div class="ui360 ui360-vis"><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 ui360-vis"><a href="../../demo/_mp3/sine,%20square,%20sawtooth,%20rando.mp3">Sine, Square, Sawtooth, Wave (Warning: LOUD)</a></div>
|
||||||
|
<div class="ui360 ui360-vis"><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>
|
|
@ -0,0 +1,359 @@
|
||||||
|
<!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="robots" content="noindex" />
|
||||||
|
<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.setup({
|
||||||
|
// path to directory containing SM2 SWF
|
||||||
|
url: '../../swf/'
|
||||||
|
});
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (threeSixtyPlayer.config.useWaveformData || threeSixtyPlayer.flash9Options.useEQData || threeSixtyPlayer.flash9Options.usePeakData) {
|
||||||
|
// even if HTML5 supports MP3, prefer flash so the visualization features can be used.
|
||||||
|
soundManager.preferFlash = 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">
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-image: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#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%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui360 span {
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
</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-top:0.5em;margin-bottom:0.5em">Canvas-based UI with visualization options. <b>Note: Spectrum/EQ visualizations disabled for IE < 9 (too slow.) Data is not implemented 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="Amount to downsample waveform data by"></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="Amount to downsample EQ data by"></div>
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
<dt>Ring Thickness</dt>
|
||||||
|
<dd class="title">(Scale)</dd>
|
||||||
|
<dd>1-200</dd>
|
||||||
|
<dd class="control">
|
||||||
|
<div class="bar" title="Click to move here"></div>
|
||||||
|
<div class="slider" title="Scale factor for the ring width"></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 ui360-vis"><a href="http://freshly-ground.com/data/audio/sm2/The%20Fugitives%20-%20Graffiti%20Sex.mp3">The Fugitives - Graffiti Sex</a></div>
|
||||||
|
<div class="ui360 ui360-vis"><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 ui360-vis"><a href="http://freshly-ground.com/data/audio/sm2/SonReal%20-%20I%20Tried.mp3">SonReal - I Tried</a></div>
|
||||||
|
<div class="ui360 ui360-vis"><a href="http://freshly-ground.com/data/audio/sm2/SonReal%20-%20People%20Asking.mp3">SonReal - People Asking</a></div>
|
||||||
|
<div class="ui360 ui360-vis"><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>: "Graffiti Sex" courtesy of <a href="http://www.fugitives.ca/" title="A group of musicians, poets, and multi-instrumentalists from Vancouver, Canada">The Fugitives</a>. "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 ui360-vis"><a href="http://freshly-ground.com/data/audio/mpc/20090207%20-%20Loverman.mp3">20090207 - Loverman</a></div>
|
||||||
|
<div class="ui360 ui360-vis"><a href="http://freshly-ground.com/data/audio/sm2/dialup.mp3">56K Modem dial-up sound (Warning: <span style="color:#ff3333">LOUD</span>)</a></div>
|
||||||
|
<div class="ui360 ui360-vis"><a href="../../demo/_mp3/1hz-10khz-sweep.mp3">1-10 Khz Sweep (Warning: <span style="color:#ff3333">LOUD</span>)</a></div>
|
||||||
|
<div class="ui360 ui360-vis"><a href="../../demo/_mp3/sine,%20square,%20sawtooth,%20rando.mp3">Sine, Square, Sawtooth, Wave (Warning: <span style="color:#ff3333">LOUD</span>)</a></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="note medium-note" style="clear:left">56K Modem sound (Creative Commons license) via <a href="http://www.freesound.org/samplesViewSingle.php?id=16475">dialup.mp3</a>, from freesound.org user <a href="http://www.freesound.org/usersViewSingle.php?id=54447">Jlew</a>.</p>
|
||||||
|
|
||||||
|
|
||||||
|
<h2 style="clear:left;padding-top:1em">Variant: Annotations/meta-data</h2>
|
||||||
|
|
||||||
|
|
||||||
|
<ul class="ui360playlist">
|
||||||
|
|
||||||
|
<li>
|
||||||
|
|
||||||
|
<div class="ui360 ui360-vis">
|
||||||
|
<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 ui360-vis">
|
||||||
|
<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>
|
|
@ -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;
|
||||||
|
}
|
|
@ -0,0 +1,750 @@
|
||||||
|
/*
|
||||||
|
Ancient fireworks slider control code (2005)
|
||||||
|
Kinda/sorta refactored for SM2 360 demo
|
||||||
|
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.scaleArcWidth = (self.controls[5].value/100);
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (threeSixtyPlayer.lastSound) {
|
||||||
|
|
||||||
|
threeSixtyPlayer.lastSound._360data.circleDiameter = self.controls[0].value;
|
||||||
|
|
||||||
|
threeSixtyPlayer.lastSound._360data.circleRadius = self.controls[0].value/2;
|
||||||
|
|
||||||
|
threeSixtyPlayer.lastSound._360data.waveformDataLineRatio = (self.controls[1].value/100)*2;
|
||||||
|
|
||||||
|
threeSixtyPlayer.lastSound._360data.waveformDataDownsample = (self.controls[2].value);
|
||||||
|
|
||||||
|
threeSixtyPlayer.lastSound._360data.eqDataLineRatio = parseInt((self.controls[3].value/100)*3*1000)/1000;
|
||||||
|
|
||||||
|
threeSixtyPlayer.lastSound._360data.eqDataDownsample = (self.controls[4].value);
|
||||||
|
|
||||||
|
threeSixtyPlayer.lastSound._360data.useEQData = (document.getElementById('disabled-1').checked?true:false);
|
||||||
|
|
||||||
|
// radio buttons
|
||||||
|
|
||||||
|
threeSixtyPlayer.lastSound._360data.useWaveformData=(document.getElementById('use-waveform').checked?true:false);
|
||||||
|
|
||||||
|
threeSixtyPlayer.lastSound._360data.waveformDataOutside = document.getElementById('waveform-inside').checked?false:true;
|
||||||
|
|
||||||
|
threeSixtyPlayer.lastSound._360data.eqDataOutside = document.getElementById('eq-inside').checked?false:true;
|
||||||
|
|
||||||
|
threeSixtyPlayer.lastSound._360data.useAmplifier = (document.getElementById('use-amplifier').checked?true:false);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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\
|
||||||
|
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(){
|
||||||
|
// default values for controls
|
||||||
|
var values = [
|
||||||
|
256,
|
||||||
|
65,
|
||||||
|
40,
|
||||||
|
72,
|
||||||
|
48,
|
||||||
|
100
|
||||||
|
];
|
||||||
|
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 window.addEventListener !== 'undefined' ? o.addEventListener(evtName,evtHandler,false) : o.attachEvent('on'+evtName,evtHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeEvent(o,evtName,evtHandler) {
|
||||||
|
typeof window.removeEventListener !== '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,
|
||||||
|
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,
|
||||||
|
scaleArcWidth: 1, // thickness factor of playback progress ring
|
||||||
|
useAmplifier: true
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
/**
|
||||||
|
* 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: -0.005em; /* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#left {
|
||||||
|
max-width:56em;
|
||||||
|
margin-left:1em;
|
||||||
|
}
|
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 493 B |
After Width: | Height: | Size: 2.4 KiB |
|
@ -0,0 +1,173 @@
|
||||||
|
<!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.setup({
|
||||||
|
// path to directory containing SM2 SWF
|
||||||
|
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 */
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-image: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#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>: JavaScript + Canvas UI</h1>
|
||||||
|
|
||||||
|
<p class="note" style="color:#666;margin-top:0.5em;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;min-width:200px"> <!-- 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:152px">
|
||||||
|
|
||||||
|
<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">play "an.mp3"</a>
|
||||||
|
</div></code></pre>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>When the 360 player script loads, it 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>
|
||||||
|
<span class="<span>sm2-360btn</span>"></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>
|
||||||
|
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>;
|
||||||
|
height:<span>50px</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>
|
|
@ -0,0 +1,674 @@
|
||||||
|
/** @license
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 8.8 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 63 KiB |
After Width: | Height: | Size: 48 KiB |
After Width: | Height: | Size: 117 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 117 KiB |
|
@ -0,0 +1,127 @@
|
||||||
|
<?xml version="1.0" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<metadata>
|
||||||
|
This is a custom SVG webfont generated by Font Squirrel.
|
||||||
|
Copyright : Generated in 2010 by FontLab Studio Copyright info pending
|
||||||
|
</metadata>
|
||||||
|
<defs>
|
||||||
|
<font id="ChunkFiveRegular" horiz-adv-x="696" >
|
||||||
|
<font-face units-per-em="2048" ascent="1536" descent="-512" />
|
||||||
|
<missing-glyph horiz-adv-x="500" />
|
||||||
|
<glyph unicode="!" horiz-adv-x="630" d="M57 209q0 84 64.5 150.5t169.5 66.5q106 0 175 -63.5t69 -153.5q0 -88 -68 -149.5t-176 -61.5q-98 0 -166 64.5t-68 146.5zM66 1042v390h489v-390l-109 -516h-270z" />
|
||||||
|
<glyph unicode=""" horiz-adv-x="1032" d="M72 1436h393l-62 -613h-256zM567 1436h394l-74 -613h-256z" />
|
||||||
|
<glyph unicode="#" horiz-adv-x="1536" d="M31 375v278h299l59 234h-246v278h316l96 375h270l-96 -375h275l96 375h270l-96 -375h231v-278h-301l-59 -234h248v-278h-320l-94 -377l-270 4l94 373h-275l-94 -377l-270 4l94 373h-227zM600 653h274l60 234h-275z" />
|
||||||
|
<glyph unicode="$" horiz-adv-x="1234" d="M31 35v493h321q0 -57 27 -98t70 -60.5t78.5 -27.5t72.5 -10q150 0 150 100q0 41 -69 74t-166 66.5t-195.5 81.5t-167 141.5t-68.5 220.5q0 188 113.5 289.5t261.5 111.5v172h289v-213q78 -37 114 -100l17 115h299v-480h-316q0 104 -63.5 166t-163.5 62q-43 0 -82 -28 t-39 -77q0 -47 51 -84t128 -62.5t166 -64.5t166 -84t128 -128t51 -189.5t-41 -186t-109.5 -123.5t-144 -64.5t-161.5 -22.5v-211h-289v268q-55 31 -107 76l-22 -123h-299z" />
|
||||||
|
<glyph unicode="%" horiz-adv-x="1906" d="M31 1051q0 180 125 298.5t288 118.5q199 0 310.5 -114.5t111.5 -309.5q0 -184 -110.5 -300.5t-302.5 -116.5q-186 0 -304 115.5t-118 308.5zM336 1051q0 -104 37 -170t80 -66q47 0 76.5 62.5t29.5 166.5q0 100 -32.5 166t-80.5 66q-41 2 -75.5 -60.5t-34.5 -164.5zM387 0 l885 1432h233l-887 -1432h-231zM1040 424q0 180 125 299t289 119q199 0 310.5 -115t111.5 -309q0 -184 -110.5 -301t-303.5 -117q-186 0 -304 115.5t-118 308.5zM1346 424q0 -104 36.5 -170t79.5 -66q47 0 77 62.5t30 167.5q0 100 -33 165.5t-80 65.5q-41 2 -75.5 -60.5 t-34.5 -164.5z" />
|
||||||
|
<glyph unicode="&" horiz-adv-x="1579" d="M20 420q0 264 302 418q-63 41 -106.5 115.5t-43.5 154.5q0 135 125 241.5t313 106.5q219 0 333 -106.5t114 -241.5q0 -111 -67.5 -184.5t-166.5 -114.5l191 -191q59 111 106 273h439v-258h-201q-47 -135 -117 -242l127 -125h119v-266h-305l-133 131q-80 -74 -210 -116 t-276 -42q-250 0 -396.5 126t-146.5 321zM403 432q0 -70 51.5 -113t114.5 -43q145 0 242 86l-260 256h-8q-51 -33 -95.5 -84t-44.5 -102zM506 1114q0 -94 123 -147q6 -4 29.5 14t46 52t22.5 69q0 51 -28.5 88t-90.5 37q-43 0 -72.5 -35t-29.5 -78z" />
|
||||||
|
<glyph unicode="'" horiz-adv-x="559" d="M74 1436h405l-73 -613h-256z" />
|
||||||
|
<glyph unicode="(" horiz-adv-x="794" d="M51 639q0 170 50.5 341t128 303t154.5 227.5t148 158.5l211 -217q-59 -74 -94 -122t-96 -156.5t-93 -243.5t-32 -291q0 -162 29.5 -301t85 -245.5t97.5 -168t103 -133.5l-211 -219q-193 174 -337 459.5t-144 607.5z" />
|
||||||
|
<glyph unicode=")" horiz-adv-x="794" d="M51 -211q61 72 103.5 133.5t97.5 168t85 245.5t30 301q0 156 -32 291t-93.5 243.5t-96 156.5t-94.5 122l211 217q72 -63 148.5 -158.5t154.5 -227.5t128 -303t50 -341q0 -322 -144 -607.5t-337 -459.5z" />
|
||||||
|
<glyph unicode="*" horiz-adv-x="845" d="M10 1085l84 201l234 -108l-27 254h252l-33 -261l232 115l84 -201l-248 -81l184 -197l-186 -143l-162 227l-170 -234l-180 152l178 192z" />
|
||||||
|
<glyph unicode="+" horiz-adv-x="1120" d="M51 625v266h377v377h266v-377h375v-266h-375v-375h-266v375h-377z" />
|
||||||
|
<glyph unicode="," horiz-adv-x="557" d="M-12 -264q115 145 162 294.5t32 370.5l373 -98q6 -195 -82 -376t-250 -324z" />
|
||||||
|
<glyph unicode="-" d="M51 352v273h594v-273h-594z" />
|
||||||
|
<glyph unicode="." horiz-adv-x="528" d="M31 213q0 86 63.5 159.5t168 73.5t170 -73.5t65.5 -159.5q0 -96 -62.5 -158.5t-173.5 -62.5q-98 0 -164.5 67.5t-66.5 153.5z" />
|
||||||
|
<glyph unicode="/" horiz-adv-x="1073" d="M10 -160l762 1700h291l-762 -1704z" />
|
||||||
|
<glyph unicode="0" horiz-adv-x="1226" d="M31 723q0 326 160.5 530.5t416.5 204.5q293 0 440.5 -199.5t147.5 -549.5q0 -344 -150.5 -539t-427.5 -195q-266 0 -426.5 190.5t-160.5 557.5zM436 723q0 -186 57.5 -308t124.5 -122q72 0 119 115.5t47 300.5q0 182 -51 300.5t-127 118.5q-61 2 -115.5 -113.5 t-54.5 -291.5z" />
|
||||||
|
<glyph unicode="1" horiz-adv-x="1015" d="M51 1163l42 21l44 21l39 21q29 15 43 26l41 31q27 19 47 40l48 48q28 28 55 61h364v-1160h191v-272h-820v272h205v760l-205 -96z" />
|
||||||
|
<glyph unicode="2" horiz-adv-x="1208" d="M51 0v297q82 135 140.5 201.5t158.5 146.5q47 43 150.5 111.5t158 121t54.5 109.5q0 135 -172 135q-51 0 -103.5 -29.5t-77 -53t-71.5 -72.5l-221 233q219 254 532 254q209 0 348 -123t139 -325q0 -164 -70.5 -251t-256.5 -208q-86 -55 -180.5 -136t-126.5 -139h360v164 h344v-436h-1106z" />
|
||||||
|
<glyph unicode="3" horiz-adv-x="1105" d="M31 205l209 217q133 -133 270 -133q86 0 135 41t49 116q0 150 -170 150h-153v244h149q76 0 125 36.5t49 104.5q0 78 -54 120t-126 42q-123 0 -240 -123l-198 240q66 72 188.5 133t249.5 61q248 0 385 -117.5t137 -316.5q0 -143 -151 -260q190 -137 190 -336 q0 -213 -170 -332t-397 -119q-141 0 -278.5 70t-198.5 162z" />
|
||||||
|
<glyph unicode="4" horiz-adv-x="1196" d="M20 403v293l590 736h424v-807h109v-222h-109v-133h111v-270h-664v270h129v133h-590zM307 625h303v379z" />
|
||||||
|
<glyph unicode="5" horiz-adv-x="1181" d="M31 221l223 232q147 -152 287 -152q102 0 163.5 57.5t61.5 147.5q0 82 -60.5 140.5t-148.5 58.5q-102 0 -192 -95l-263 117l125 705h811v-306h-551l-34 -198q76 49 221 49q193 0 335 -130t142 -355q0 -125 -53.5 -225.5t-141.5 -163t-195.5 -96.5t-221.5 -34 q-150 0 -296 75t-212 173z" />
|
||||||
|
<glyph unicode="6" horiz-adv-x="1189" d="M33 623q-2 96 8 191t47 213t99.5 207t178 152.5t269.5 67.5q109 4 253 -42t230 -120l-139 -266q-178 104 -299 104q-111 -2 -181.5 -80.5t-86.5 -197.5q41 41 115.5 71.5t152.5 32.5q201 8 340 -121.5t139 -334.5q0 -213 -143.5 -361.5t-386.5 -156.5q-256 -8 -422 165 t-174 476zM416 545q0 -88 50 -165t140 -77q78 0 133.5 51.5t53.5 124.5q-2 72 -42 128.5t-124 54.5q-121 -6 -211 -117z" />
|
||||||
|
<glyph unicode="7" horiz-adv-x="1159" d="M31 1026v406h1108v-273l-551 -1159h-443l549 1159h-336v-133h-327z" />
|
||||||
|
<glyph unicode="8" horiz-adv-x="1144" d="M31 420q0 102 61.5 206.5t159.5 153.5q-74 45 -114 120t-40 153q0 176 131 289.5t357 113.5q231 0 360 -113.5t129 -289.5q0 -96 -49 -170t-123 -109q100 -49 155.5 -147.5t55.5 -206.5q0 -193 -148.5 -320t-392.5 -127q-250 0 -396 126t-146 321zM385 432 q0 -72 56.5 -120t133.5 -48q80 0 133.5 44t55.5 124q0 94 -81 136t-179 46q-49 -29 -84 -79t-35 -103zM434 1069q0 -51 39 -84t79 -41t85 -10q98 47 98 135q0 55 -46 92t-107 37q-59 0 -103.5 -39t-44.5 -90z" />
|
||||||
|
<glyph unicode="9" horiz-adv-x="1202" d="M31 936q0 213 143 361.5t387 156.5q258 8 429 -166t179 -475q2 -106 -8 -205.5t-50 -215.5t-104.5 -202t-181 -145t-270.5 -63q-109 -4 -253 42t-230 119l139 267q178 -104 299 -105q117 4 184.5 76t65.5 203q-98 -98 -250 -105q-201 -8 -340 122t-139 335zM397 956 q2 -72 42 -128t124 -54q102 4 193 117q0 94 -42 168t-130 74q-78 0 -133.5 -51.5t-53.5 -125.5z" />
|
||||||
|
<glyph unicode=":" horiz-adv-x="520" d="M31 201q0 86 62.5 157.5t164.5 71.5q104 0 167.5 -72.5t63.5 -156.5q0 -92 -64.5 -154.5t-166.5 -62.5q-96 0 -161.5 66.5t-65.5 150.5zM31 823q0 86 62.5 158t164.5 72q104 0 167.5 -73t63.5 -157q0 -94 -62 -155.5t-169 -61.5q-92 0 -159.5 67.5t-67.5 149.5z" />
|
||||||
|
<glyph unicode=";" horiz-adv-x="618" d="M10 -264l236 -133q162 143 250 324.5t82 375.5l-373 98q14 -221 -33 -370.5t-162 -294.5zM121 788q0 86 63.5 160t168 74t170 -74t65.5 -160q0 -94 -63.5 -157.5t-172.5 -63.5q-94 0 -162.5 68.5t-68.5 152.5z" />
|
||||||
|
<glyph unicode="<" horiz-adv-x="1124" d="M72 694v256l880 363l101 -250l-627 -240l627 -241l-101 -250z" />
|
||||||
|
<glyph unicode="=" horiz-adv-x="946" d="M51 352v273h844v-273h-844zM51 805v272h844v-272h-844z" />
|
||||||
|
<glyph unicode=">" horiz-adv-x="1124" d="M72 584l626 239l-626 242l100 250l881 -363v-256l-881 -362z" />
|
||||||
|
<glyph unicode="?" horiz-adv-x="1064" d="M4 1200q227 264 533 264q213 0 350 -109.5t137 -310.5q0 -74 -34 -136t-82 -104t-95 -77t-81 -69.5t-34 -67.5v-113h-379l-2 164q0 63 51.5 126.5t112 105.5t111.5 90.5t51 85.5q0 96 -151 96q-61 0 -134 -49t-133 -119zM264 209q0 84 64.5 150.5t169.5 66.5 q106 0 174.5 -63.5t68.5 -153.5q0 -88 -67.5 -149.5t-175.5 -61.5q-98 0 -166 64.5t-68 146.5z" />
|
||||||
|
<glyph unicode="@" horiz-adv-x="1595" d="M10 465q0 106 28 218t89 221.5t148 195.5t217.5 139t283.5 53q369 0 589 -207.5t220 -521.5q0 -57 -10 -116.5t-37 -126t-66.5 -116.5t-108.5 -83t-155 -33q-129 16 -184 68q-135 -98 -270 -99q-143 0 -257 119t-114 299q0 100 45 199.5t143.5 174.5t225.5 75 q113 0 200 -107l13 82l202 -27l-82 -583q2 0 3 -2q41 -25 75 -25q109 0 158 96.5t49 204.5q0 238 -174 396.5t-465 158.5q-147 0 -266 -63.5t-187.5 -163.5t-104.5 -210t-36 -216q0 -254 183.5 -433t449.5 -179q270 0 455 133l20 16l99 -141q-8 -8 -24.5 -19.5t-72 -43 t-118 -55.5t-159.5 -43t-200 -19q-326 0 -565.5 221t-239.5 563zM608 475q0 -92 44 -152.5t102 -60.5q88 0 172 49l39 267q-68 141 -168 141q-86 0 -137.5 -78t-51.5 -166z" />
|
||||||
|
<glyph unicode="A" horiz-adv-x="1685" d="M31 0v268h139l276 899h-84v265h787l362 -1164h144v-268h-821v268h194l-43 140h-420l-43 -140h160v-268h-651zM641 653h268l-135 443z" />
|
||||||
|
<glyph unicode="B" horiz-adv-x="1406" d="M51 0v266h119v901h-119v265h764q502 0 502 -351q0 -131 -44 -201.5t-157 -115.5q121 -33 195.5 -120t74.5 -228q0 -217 -131 -316.5t-426 -99.5h-778zM594 266h164q68 0 117 48t49 128t-45 130.5t-127 50.5h-158v-357zM594 854h125q78 0 108.5 40t30.5 118 q0 70 -38 109.5t-97 39.5h-129v-307z" />
|
||||||
|
<glyph unicode="C" horiz-adv-x="1404" d="M31 702q0 168 59.5 314.5t151.5 240t200.5 146.5t210.5 53q211 0 316 -139l47 115h321v-582h-366q-4 109 -59.5 183.5t-157.5 74.5q-109 0 -176.5 -117t-67.5 -289q0 -162 80 -273.5t219 -111.5q31 0 62.5 8.5t58 20.5t53.5 29.5t46.5 34t40 36t30.5 31.5l22 27l13 14 l239 -262q-262 -289 -620 -289q-328 0 -525.5 197.5t-197.5 537.5z" />
|
||||||
|
<glyph unicode="D" horiz-adv-x="1474" d="M51 0v272h127v889h-127v271h625q362 0 570 -197t208 -500q0 -350 -205 -542.5t-581 -192.5h-617zM598 272h78q156 2 231.5 130t75.5 333q0 180 -77 303t-230 123h-78v-889z" />
|
||||||
|
<glyph unicode="E" horiz-adv-x="1337" d="M51 0v272h129v889h-129v271h1235v-453h-354v182h-328v-282h389v-273h-389v-334h328v191h354v-463h-1235z" />
|
||||||
|
<glyph unicode="F" horiz-adv-x="1306" d="M51 0v272h127v889h-127v271h1225v-453h-363v182h-309v-356h389v-273h-389v-260h209v-272h-762z" />
|
||||||
|
<glyph unicode="G" horiz-adv-x="1589" d="M31 702q0 324 189.5 539t438.5 215q70 0 130.5 -11t98.5 -25.5t70.5 -37t48 -38t32 -36t20.5 -24.5l43 148h305v-605h-367q-4 121 -71.5 190.5t-161.5 69.5q-121 0 -201 -113.5t-80 -271.5q0 -162 76 -269t205 -107q139 0 197 100v86h-125v219h680v-219h-82v-512h-410 l-63 129q-37 -61 -127.5 -104t-202.5 -43q-274 0 -458.5 197t-184.5 523z" />
|
||||||
|
<glyph unicode="H" horiz-adv-x="1572" d="M51 0v270h113v891h-113v271h664v-271h-127v-309h389v309h-121v271h666v-271h-119v-891h119v-270h-666v270h121v310h-389v-310h127v-270h-664z" />
|
||||||
|
<glyph unicode="I" horiz-adv-x="782" d="M51 0v272h129v889h-129v271h680v-271h-127v-889h127v-272h-680z" />
|
||||||
|
<glyph unicode="J" horiz-adv-x="948" d="M41 -125q41 -18 92 -18q170 0 170 295v1011h-176v269h770v-269h-170v-1011q0 -283 -135 -426.5t-442 -143.5q-51 0 -107 23z" />
|
||||||
|
<glyph unicode="K" horiz-adv-x="1669" d="M51 0v266h111v901h-111v265h645v-265h-110v-333l381 333h-148v265h682v-265h-119l-297 -256l414 -645h119v-266h-799v266h139l-221 348l-151 -129v-219h110v-266h-645z" />
|
||||||
|
<glyph unicode="L" horiz-adv-x="1249" d="M51 0v272h113v889h-113v271h647v-271h-108v-889h264v260h344v-532h-1147z" />
|
||||||
|
<glyph unicode="M" horiz-adv-x="2064" d="M51 0v264h111v903h-109v265h776l207 -766l197 766h780v-265h-112v-901h112v-266h-647v266h117l-2 684v121h-8q-35 -190 -60 -274l-215 -797h-428l-229 817q-35 119 -43 254h-9v-807h117v-264h-555z" />
|
||||||
|
<glyph unicode="N" horiz-adv-x="1671" d="M51 0v264h121v903h-119v265h588l504 -752l-2 487h-139v265h616v-265h-135v-1167h-441l-522 780v-516h158v-264h-629z" />
|
||||||
|
<glyph unicode="O" horiz-adv-x="1515" d="M31 723q0 332 200.5 539.5t518.5 207.5q367 0 551 -202.5t184 -558.5q0 -350 -188.5 -548t-532.5 -198q-334 0 -533.5 193.5t-199.5 566.5zM537 723q0 -199 63.5 -318.5t163.5 -119.5q96 0 152.5 115.5t56.5 308.5q0 199 -56.5 322.5t-168.5 123.5h-4q-92 0 -149 -120 q-58 -122 -58 -312z" />
|
||||||
|
<glyph unicode="P" horiz-adv-x="1310" d="M51 0v270h115v893h-115v269h664q172 0 287.5 -34t174 -99.5t81 -137t22.5 -168.5q0 -195 -153.5 -300t-385.5 -105h-155v-318h125v-270h-660zM586 809h92q90 0 145.5 45t55.5 125q0 90 -50.5 138t-140.5 48h-102v-356z" />
|
||||||
|
<glyph unicode="Q" horiz-adv-x="1546" d="M31 725q0 315 190.5 514t497.5 199q350 0 525 -193.5t175 -533.5q0 -326 -170 -512q35 -133 90 -133q41 0 41 92v59h136v-104q0 -143 -80 -235.5t-228 -92.5q-119 0 -199.5 64.5t-117.5 162.5q-74 -12 -160 -12q-319 0 -509.5 186.5t-190.5 538.5zM481 725q0 -66 8 -113 q94 98 242 99q119 0 230 -80q4 49 4 80q0 182 -69 305t-179 123h-3q-92 0 -162 -118q-71 -120 -71 -296zM594 375q61 -68 137 -68q57 0 109 45q-12 86 -36 129t-73 43q-84 1 -137 -149z" />
|
||||||
|
<glyph unicode="R" horiz-adv-x="1509" d="M51 0v270h115v893h-115v269h666q172 0 287.5 -32t175 -93.5t82 -131t22.5 -165.5q0 -117 -83 -198t-214 -99q109 -16 188.5 -99.5t79.5 -191.5q0 -139 50 -139q47 0 47 65v68h137v-113q0 -143 -70.5 -235.5t-228.5 -92.5q-199 0 -298 99.5t-99 281.5q0 143 -36 187.5 t-169 44.5v-318h125v-270h-662zM588 817h92q90 0 143.5 43t53.5 123q0 182 -187 182h-102v-348z" />
|
||||||
|
<glyph unicode="S" horiz-adv-x="1454" d="M51 0v516h381q0 -61 26.5 -103t71.5 -62.5t82 -29t78 -10.5q174 0 174 103q0 37 -58 65.5t-145.5 48t-189.5 57.5t-189 87t-145.5 141t-58.5 215q0 109 47 196t122 139t156.5 78.5t161.5 26.5q317 0 428 -208l21 172h352v-514h-371q0 111 -74.5 174t-187.5 63 q-51 0 -96 -29.5t-45 -78.5q0 -57 84 -100.5t202.5 -81.5t237.5 -87t203 -145t84 -230q0 -115 -49 -201.5t-131 -136t-174.5 -73t-188.5 -23.5q-268 0 -428 189l-22 -158h-359z" />
|
||||||
|
<glyph unicode="T" horiz-adv-x="1435" d="M31 899v533h1374v-533h-301v262h-172v-889h170v-272h-762v272h168v889h-176v-262h-301z" />
|
||||||
|
<glyph unicode="U" horiz-adv-x="1509" d="M31 1165v267h651v-265h-111v-442q0 -233 49.5 -316t155.5 -83q70 0 111 25.5t68.5 116.5t27.5 259v434h-111v271h607v-265h-111v-497q0 -705 -588 -705q-635 18 -635 694v506h-114z" />
|
||||||
|
<glyph unicode="V" horiz-adv-x="1583" d="M-20 1165v267h755l-2 -267h-110l174 -458q59 -180 63 -248h10q6 92 74 260l186 446h-106l-2 267h582v-267h-101l-491 -1165h-377l-543 1165h-112z" />
|
||||||
|
<glyph unicode="W" horiz-adv-x="2078" d="M-20 1165v267h675v-267h-118l53 -299q29 -123 65 -403h11q4 47 100 508l102 461h426l129 -566q39 -182 62 -403h10q16 178 61 391l70 311h-113v267h586v-267h-112l-306 -1165h-485l-123 487q-27 98 -51 254h-8q-14 -102 -49 -249l-125 -492h-475l-271 1165h-114z" />
|
||||||
|
<glyph unicode="X" horiz-adv-x="1710" d="M51 0v264h178l301 391l-370 510h-107v267h811v-267h-119l201 -272l209 272h-180v267h680v-267h-174l-310 -395l369 -504h119v-266h-817v266h116l-155 209l-43 57l-211 -268h182v-264h-680z" />
|
||||||
|
<glyph unicode="Y" horiz-adv-x="1370" d="M-20 1169v263h700v-263h-107l119 -217q6 -16 33 -81.5t31 -84.5h8q4 18 76 177l112 206h-112v263h551v-263h-111l-379 -665v-238h115v-266h-656v266h117v242l-397 661h-100z" />
|
||||||
|
<glyph unicode="Z" horiz-adv-x="1462" d="M51 0v266l746 895l-387 -2l2 -266h-349v539h1344l4 -273l-749 -889h378l2 262h363v-532h-1354z" />
|
||||||
|
<glyph unicode="[" horiz-adv-x="1474" d="M59 0v270h115v893h-115v271h664q170 0 286.5 -39t175 -108.5t81 -145.5t22.5 -174q0 -215 -221 -338l229 -363h119v-266h-393l-340 549h-88v-279h125v-270h-660zM594 809h92q90 0 145.5 45t55.5 125q0 90 -50.5 138t-140.5 48h-102v-356z" />
|
||||||
|
<glyph unicode="\" horiz-adv-x="1073" d="M10 1540h291l762 -1700l-291 -4z" />
|
||||||
|
<glyph unicode="]" horiz-adv-x="1325" d="M61 0v266h84v1002h-84v268h474v-926l237 142h-147v272h573v-272h-158l-129 -76l285 -408h84v-268h-332l-344 489l-72 -49v-172h146v-268h-617z" />
|
||||||
|
<glyph unicode="^" horiz-adv-x="1222" d="M20 621l445 813h297l440 -813h-364l-224 458l-229 -458h-365z" />
|
||||||
|
<glyph unicode="_" horiz-adv-x="1431" d="M51 -2v170h1329v-170h-1329z" />
|
||||||
|
<glyph unicode="a" horiz-adv-x="1228" d="M31 303q0 170 124 273.5t302 103.5q55 0 103 -16.5t69.5 -31t29.5 -24.5v72q0 115 -194 115q-135 0 -305 -95l-86 238q242 145 446 145q100 0 191.5 -20.5t176.5 -65.5t136 -132t51 -203v-400h123v-262h-438l-49 92q-51 -70 -129 -100.5t-148 -30.5q-162 0 -282.5 88 t-120.5 254zM420 324q0 -43 30.5 -70t77.5 -27q43 0 79 20.5t52 47.5v78q-35 59 -120 59q-119 1 -119 -108z" />
|
||||||
|
<glyph unicode="b" horiz-adv-x="1343" d="M63 0v266h87v1002h-87v268h496v-592q33 39 113 67.5t155 28.5q223 0 350 -158q122 -154 122 -364q0 -7 -1 -14q-4 -240 -131 -383.5t-342 -143.5q-74 0 -128 14.5t-80.5 31t-61.5 47.5l-31 -70h-461zM555 489q0 -102 44 -173.5t103 -71.5q66 0 106 69.5t40 186.5 q0 98 -41 175t-107 77q-63 0 -107 -73q-39 -64 -39 -162q0 -14 1 -28z" />
|
||||||
|
<glyph unicode="c" horiz-adv-x="1087" d="M2 518q0 256 145.5 390t358.5 134q158 0 256 -116l35 98h241v-463h-301q-4 88 -34.5 151.5t-94.5 63.5q-86 0 -133 -76.5t-47 -185.5q0 -102 57.5 -171t153.5 -71h5q136 0 243 117l180 -209q-80 -88 -213 -148.5t-289 -60.5q-240 0 -401.5 143.5t-161.5 403.5z" />
|
||||||
|
<glyph unicode="d" horiz-adv-x="1298" d="M20 522q0 231 139.5 376.5t336.5 145.5q135 0 258 -77v303h-95v266h510v-1270h99v-266h-480l-34 76q-102 -94 -258 -94q-211 0 -343.5 159.5t-132.5 380.5zM461 522q0 -98 41 -175t106 -77q63 0 108 73q39 64 38 162v27q0 102 -44 174t-104 72q-66 0 -105.5 -69.5 t-39.5 -186.5z" />
|
||||||
|
<glyph unicode="e" horiz-adv-x="1110" d="M10 518q0 246 156 390.5t395 144.5q180 0 312.5 -83t177.5 -214q23 -66 27 -156q1 -14 1 -27q0 -78 -24 -163h-645q6 -31 14 -51.5t29.5 -52.5t64.5 -48t103 -16q168 0 286 98l172 -199q-207 -178 -528 -178q-215 0 -378 141.5t-163 413.5zM416 612h309q-2 74 -32.5 119 t-119.5 45q-82 0 -117.5 -53.5t-39.5 -110.5z" />
|
||||||
|
<glyph unicode="f" horiz-adv-x="790" d="M51 758v266h84v174q0 43 6 84t31 97.5t66 96.5t119.5 68.5t183.5 28.5q80 0 170 -15.5t131 -35.5l-123 -236q-45 20 -113 21q-66 0 -65 -109v-174h186v-266h-186v-490h123v-268h-611v268h82v490h-84z" />
|
||||||
|
<glyph unicode="g" horiz-adv-x="1310" d="M20 518q0 244 133.5 385t381.5 141q63 0 123.5 -25.5t93.5 -57.5l41 63h487v-268h-123v-613q0 -262 -161.5 -411.5t-477.5 -151.5q-152 2 -272.5 56.5t-196.5 123.5l109 228q49 -43 151.5 -87t204.5 -44q125 0 181.5 57t56.5 135v70q-88 -113 -240 -113 q-246 0 -369 148.5t-123 363.5zM457 522q0 -98 41 -175t106 -77q63 0 108 73q39 64 38 162v27q0 102 -44 174t-104 72q-66 0 -105.5 -69.5t-39.5 -186.5z" />
|
||||||
|
<glyph unicode="h" horiz-adv-x="1353" d="M51 0v268h86v1002h-86v266h496v-639q25 41 124 102.5t197 61.5q113 0 189 -38t110.5 -108.5t47 -140t12.5 -164.5v-342h96v-268h-526v557q0 39 -2 61.5t-12.5 57.5t-37 53.5t-69.5 18.5q-129 0 -129 -191v-289h147v-268h-643z" />
|
||||||
|
<glyph unicode="i" horiz-adv-x="675" d="M51 0v268h86v490h-86v266h475v-756h99v-268h-574zM109 1323q0 78 60 143.5t160.5 65.5t163 -65.5t62.5 -143.5q0 -88 -60.5 -147.5t-164.5 -59.5q-92 0 -156.5 64.5t-64.5 142.5z" />
|
||||||
|
<glyph unicode="j" horiz-adv-x="737" d="M29 -154q68 0 114.5 24t69.5 51.5t35 77.5t13 74.5t1 69.5v615h-86v266h475v-881q0 -86 -12 -157.5t-51 -151.5t-104.5 -135t-181.5 -91t-273 -36v274zM233 1323q0 78 60.5 143.5t161 65.5t163 -65.5t62.5 -143.5q0 -88 -60.5 -147.5t-164.5 -59.5q-92 0 -157 64.5 t-65 142.5z" />
|
||||||
|
<glyph unicode="k" horiz-adv-x="1339" d="M78 0v266h84v1002h-84v268h473v-926l237 142h-147v270h573v-270h-157l-139 -88l276 -396h102v-268h-606v268h86l-155 221l-72 -49v-172h76v-268h-547z" />
|
||||||
|
<glyph unicode="l" horiz-adv-x="679" d="M51 0v268h88v1004h-86v264h475v-1268h121v-268h-598z" />
|
||||||
|
<glyph unicode="m" horiz-adv-x="1859" d="M51 0v268h86v484h-86v270h387l45 -121q125 150 256 150q72 0 128.5 -14.5t92 -42t51 -46t33.5 -45.5q131 147 302 148q119 0 198.5 -40t117.5 -115t52.5 -152.5t14.5 -184.5v-283h100v-276h-520v502q0 12 1 44t1 50t-2 46t-7.5 45.5t-13.5 34.5t-22.5 25.5t-34.5 8.5 q-61 0 -85 -38t-24 -112v-332h123v-274h-530v522q0 137 -14.5 185.5t-71.5 48.5q-92 0 -92 -123v-365h122v-268h-608z" />
|
||||||
|
<glyph unicode="n" horiz-adv-x="1325" d="M51 0v268h86v490h-86v266h436l48 -127q119 164 292 164q92 0 161 -26.5t108 -68.5t62.5 -104.5t31.5 -121t8 -130.5v-342h96v-268h-516v559v48q0 11 -5 47t-16.5 50.5t-35 30t-57.5 15.5q-129 0 -129 -191v-291h147v-268h-631z" />
|
||||||
|
<glyph unicode="o" horiz-adv-x="1175" d="M191 904q167 144 393 145q250 -4 407.5 -147.5t161.5 -393.5v-6q0 -243 -158 -385q-160 -143 -401 -144q-238 0 -406 143q-166 141 -165 394q-1 248 168 394zM442 514q0 -125 43 -201.5t109 -76.5q63 0 101 76.5t38 195.5t-40 195.5t-109 78.5q-59 0 -100.5 -77.5 t-41.5 -190.5z" />
|
||||||
|
<glyph unicode="p" horiz-adv-x="1306" d="M51 -150h86v902h-86v272h469l35 -72q119 88 248 88q229 0 356 -153.5t127 -382.5q0 -240 -132 -383.5t-335 -143.5q-172 0 -266 80v-207h111v-268h-613v268zM553 489q0 -102 44 -173.5t103 -71.5q66 0 106 69.5t40 186.5q0 98 -41 175t-107 77q-63 0 -107 -73 q-39 -64 -39 -162q0 -14 1 -28z" />
|
||||||
|
<glyph unicode="q" horiz-adv-x="1351" d="M51 518q0 256 137.5 391t352.5 135q88 0 155.5 -27.5t87.5 -53.5l39 61h477v-266h-100v-955h100v-274h-649v268h133v271q-104 -86 -262 -86q-201 0 -336 147t-135 389zM492 516q0 -102 44 -174t103 -72q66 0 105.5 70t39.5 186q0 98 -41 175t-106 77q-63 0 -108 -72 q-39 -64 -38 -162q0 -14 1 -28z" />
|
||||||
|
<glyph unicode="r" horiz-adv-x="847" d="M51 0v268h90v490h-88v266h385l62 -131q25 45 44 70.5t54 55.5t89 43t130 13v-368q-147 0 -218 -49.5t-71 -178.5v-211h103v-268h-580z" />
|
||||||
|
<glyph unicode="s" horiz-adv-x="1040" d="M31 0v369h274q0 -49 44 -83t89 -44.5t84 -10.5q90 0 90 70q0 18 -16 31.5t-48 24t-66 19.5l-84 22q-50 13 -87 26q-272 96 -272 328q0 143 115.5 220t244.5 77q102 0 187.5 -46.5t118.5 -113.5l16 135h252v-369h-266q0 63 -64.5 109.5t-144.5 46.5t-80 -74 q0 -16 12 -29.5t41 -26.5t51.5 -21.5t72.5 -24.5l75 -25q80 -27 120.5 -45t98 -56t84 -94.5t26.5 -131.5q0 -139 -112.5 -223.5t-268.5 -84.5q-104 0 -189 43t-124 107l-18 -125h-256z" />
|
||||||
|
<glyph unicode="t" horiz-adv-x="743" d="M31 758v266h110v188l377 121v-309h195v-266h-195v-365q0 -8 -1 -29.5t0 -34t2 -29.5t5 -27.5t11.5 -21.5t19.5 -16.5t29 -5.5q47 0 129 35v-262q-41 -16 -122 -27.5t-126 -11.5q-90 0 -150.5 21.5t-94.5 52.5t-51 94.5t-21.5 114.5t-6.5 147v365h-110z" />
|
||||||
|
<glyph unicode="u" horiz-adv-x="1292" d="M31 754v270h495v-494q0 -135 24.5 -196.5t86.5 -61.5q55 0 92 44t37 112v326h-135v270h530v-752h101v-272h-388l-55 129l-20 -23q-20 -25 -28 -31l-30 -29q-23 -22 -41 -30t-44.5 -21t-58.5 -18.5t-69 -5.5q-227 0 -319 119t-92 381v283h-86z" />
|
||||||
|
<glyph unicode="v" horiz-adv-x="1255" d="M0 764v260h623v-260h-103l94 -217q45 -133 54 -215h8q4 94 61 225l99 207h-109v260h528v-260h-106l-354 -764h-318l-381 764h-96z" />
|
||||||
|
<glyph unicode="w" horiz-adv-x="1785" d="M0 758v266h551v-266h-70l45 -150q41 -139 52 -295h4q20 268 84 482l65 229h379l78 -266q59 -188 88 -445h4q18 193 55 324l35 121h-84v266h500v-266h-84l-240 -758h-432l-141 463l-148 -463h-422l-231 758h-88z" />
|
||||||
|
<glyph unicode="x" horiz-adv-x="1329" d="M41 0v254h137l209 235l-254 279h-92v256h664v-256h-97l144 -156l153 156h-137v256h522v-256h-135l-217 -219l258 -295h96v-254h-653v254h96l-155 166l-148 -166h133v-254h-524z" />
|
||||||
|
<glyph unicode="y" horiz-adv-x="1187" d="M-18 762v262h630v-260h-96l133 -320l133 320h-94v260h520v-254h-98l-389 -946q-23 -49 -40 -80t-54 -76t-80 -70.5t-111.5 -44t-154.5 -18.5q-139 8 -248 103l153 241q68 -59 119 -69q9 -2 18 -2q34 0 62 26q35 33 51 84l29 86l-399 758h-84z" />
|
||||||
|
<glyph unicode="z" horiz-adv-x="1132" d="M51 0v268l494 492h-228v-146h-266v410h1014v-264l-487 -492h215v140h288v-408h-1030z" />
|
||||||
|
<glyph unicode="|" horiz-adv-x="681" d="M205 -418v1854h272v-1854h-272z" />
|
||||||
|
<glyph unicode="­" d="M51 352v273h594v-273h-594z" />
|
||||||
|
<glyph unicode=" " horiz-adv-x="833" />
|
||||||
|
<glyph unicode=" " horiz-adv-x="1669" />
|
||||||
|
<glyph unicode=" " horiz-adv-x="833" />
|
||||||
|
<glyph unicode=" " horiz-adv-x="1669" />
|
||||||
|
<glyph unicode=" " horiz-adv-x="555" />
|
||||||
|
<glyph unicode=" " horiz-adv-x="415" />
|
||||||
|
<glyph unicode=" " horiz-adv-x="276" />
|
||||||
|
<glyph unicode=" " horiz-adv-x="276" />
|
||||||
|
<glyph unicode=" " horiz-adv-x="206" />
|
||||||
|
<glyph unicode=" " horiz-adv-x="333" />
|
||||||
|
<glyph unicode=" " horiz-adv-x="92" />
|
||||||
|
<glyph unicode="‐" d="M51 352v273h594v-273h-594z" />
|
||||||
|
<glyph unicode="‑" d="M51 352v273h594v-273h-594z" />
|
||||||
|
<glyph unicode="‒" d="M51 352v273h594v-273h-594z" />
|
||||||
|
<glyph unicode="–" horiz-adv-x="915" d="M66 352v273h772v-273h-772z" />
|
||||||
|
<glyph unicode="—" horiz-adv-x="1292" d="M86 352v273h1104v-273h-1104z" />
|
||||||
|
<glyph unicode="’" horiz-adv-x="559" d="M74 1436h405l-73 -613h-256z" />
|
||||||
|
<glyph unicode="“" horiz-adv-x="1032" d="M72 1436h393l-62 -613h-256zM567 1436h394l-74 -613h-256z" />
|
||||||
|
<glyph unicode="”" horiz-adv-x="1032" d="M72 1436h393l-62 -613h-256zM567 1436h394l-74 -613h-256z" />
|
||||||
|
<glyph unicode="…" horiz-adv-x="1585" d="M1088 213q0 86 63.5 159.5t168 73.5t170 -73.5t65.5 -159.5q0 -96 -62.5 -158.5t-173.5 -62.5q-98 0 -164.5 67.5t-66.5 153.5zM559 213q0 86 63.5 159.5t168 73.5t170 -73.5t65.5 -159.5q0 -96 -62.5 -158.5t-173.5 -62.5q-98 0 -164.5 67.5t-66.5 153.5zM31 213 q0 86 63.5 159.5t168 73.5t170 -73.5t65.5 -159.5q0 -96 -62.5 -158.5t-173.5 -62.5q-98 0 -164.5 67.5t-66.5 153.5z" />
|
||||||
|
<glyph unicode=" " horiz-adv-x="333" />
|
||||||
|
<glyph unicode=" " horiz-adv-x="415" />
|
||||||
|
<glyph unicode="" horiz-adv-x="1025" d="M0 1025h1025v-1025h-1025v1025z" />
|
||||||
|
</font>
|
||||||
|
</defs></svg>
|
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 201 B |
After Width: | Height: | Size: 233 B |
After Width: | Height: | Size: 89 B |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 102 B |
After Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 180 B |
After Width: | Height: | Size: 168 B |
After Width: | Height: | Size: 205 B |
After Width: | Height: | Size: 7.5 KiB |
After Width: | Height: | Size: 7.4 KiB |
After Width: | Height: | Size: 107 B |
After Width: | Height: | Size: 855 B |
After Width: | Height: | Size: 101 B |
After Width: | Height: | Size: 549 B |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 5.8 KiB |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 168 B |
After Width: | Height: | Size: 832 B |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 52 KiB |
After Width: | Height: | Size: 15 KiB |