DIR : /home/kozerus/public_html/snd5.html
/home/kozerus/public_html
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<title>Guitar Zero</title>
<!-- https://resoundingechoes.net/js30/01-guitar-zero/ -->
<link rel='stylesheet' href='style.css' />
<style>
body {
font-size: 16px;
background: #000;
position: relative;
font-family: "Lucida Sans Typewriter", sans-serif;
min-height: 100vh;
padding: 0;
margin: 0;
}
header {
padding: 3em 0 1.5em;
font-size: 1.8rem;
opacity: 0.8;
text-align: center;
}
h1 {
color: #fff;
margin: 0;
}
div#key-set {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
max-width: 800px;
margin: auto;
}
div.key-container {
margin: 0 1em 1em 0;
}
div.key {
cursor: pointer;
display: inline-block;
padding: 1em;
text-align: center;
border: solid 1px yellow;
color: #fff;
transition: all 0.2s;
}
div.key.playing {
transform: scale(1.05);
box-shadow: 0 0 1px 2px orange;
background: #555;
}
kbd{
display: block;
font-size: 2em;
color: lime;
margin-bottom: 0.5em;
}
div.controls {
text-align: center;
}
button.looper {
background: #4169E1;
color: white;
border: none;
border-radius: 2px;
display: block;
cursor: pointer;
margin: 0.5em auto 0;
padding: 0 0.3em;
font-size: 1.2em;
}
button.looper.active {
background: lime;
}
footer {
color: #fff;
margin: 2em 0;
}
footer p {
text-align: right;
line-height: 1.5em;
padding-right: 2em;
margin: 0;
}
footer p a {
color: #4169E1;
}
footer p a:hover,
footer p a:focus {
color: #68228B;
}
@media screen and (max-width: 700px ) {
body {
font-size: 12px;
}
header {
padding: 1em 0;
}
h1 {
font-size: 1.2em;
}
div.key-container {
margin-bottom: 2em;
}
button.looper {
font-size: 2em;
padding-left: 0.3em;
padding-right: 0.3em;
}
}
@media screen and ( max-width: 400px ) {
}
</style>
<!--
<link rel='icon' href='https://resoundingechoes.net/wp-content/uploads/cropped-resoundingechoes-icon-192x192.png' />
-->
</head>
<body>
<header>
<h1>Guitar Zero</h1>
</header>
<div id='key-set'></div>
<footer>
<p class='recordings-credit'>Sounds played & recorded by <a href='https://resoundingechoes.net/development/using-javascript-html-play-audio-browser/'>Michael Hull</a></p>
<p class='idea-credit'>Inspired by <a target='_blank' href='https://javascript30.com/'>JavaScript 30</a></p>
</footer>
<!-- Key template -->
<script type='text/html' id='key-template'>
<div class='key'>
<kbd>{{ key.key }}</kbd>
<span class='sound'>{{ key.name }}</span>
<audio src="sounds/{{ key.name }}.wav"></audio>
</div>
<div class='controls'>
<button class='looper'>∞</button>
</div>
</script>
<!-- Main JS file -->
<script src='guitar-zero.js'></script>
<!--
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', "UA-66931247-1", 'auto');
ga('send', 'pageview');
</script>
-->
<script>
'use strict';
(function() {
// The main Guitar Zero object
var gz = {};
// The container div for the keys
gz.keysContainer = document.querySelector('#key-set');
// The template for creating new keys
gz.keyTemplate = document.querySelector( '#key-template' );
// The set of key objects
gz.keys = [
{
key: 'Q',
name: 'Blurp',
code: 81,
},
{
key: 'W',
name: 'Reow',
code: 87,
},
{
key: 'E',
name: 'Slippery',
code: 69,
},
{
key: 'R',
name: 'Bye-e-eye',
code: 82,
},
{
key: 'T',
name: 'Ring-Out',
code: 84,
},
{
key: 'Y',
name: 'Falling-Down',
code: 89,
},
{
key: 'U',
name: 'Double-Up',
code: 85,
},
{
key: 'I',
name: 'Yowza',
code: 73,
},
{
key: 'O',
name: 'What',
code: 79,
},
{
key: 'P',
name: 'Climbing-Up',
code: 80,
},
{
key: '[',
name: 'Bell-Toll',
code: 219,
}
]; // end: gz.keys
/**
* Key binding method
*
* Expects to be called via gz.Key.call() on items from gz.keys
*/
gz.Key = function() {
var key = this;
/**
* Create the DOM element from the template
*/
key.container = document.createElement('div');
key.container.classList.add('key-container');
key.container.innerHTML = gz.keyTemplate.innerHTML.replace(
/{{ key\.(key|name|code) }}/g,
( fullMatch, match ) => this[ match ]
);
key.element = key.container.querySelector( '.key' );
/**
* Add element to the DOM
*/
gz.keysContainer.appendChild( key.container );
// the audio element for this key
key.audio = key.element.querySelector('audio');
// the loop button for this key
key.looper = key.container.querySelector('button.looper');
/**
* Play this key
*/
key.play = function() {
key.element.classList.add('playing');
key.audio.currentTime = 0;
key.audio.play();
}
key.loop = function() {
if( ! key.isLooping ) {
key.looper.classList.add('active');
key.audio.setAttribute('loop', 'loop');
key.isLooping = true;
}
else {
key.looper.classList.remove('active');
key.audio.removeAttribute('loop');
key.isLooping = false;
}
}
/**
* Remove transition effects
*/
key.removeTransition = function( e ) {
if( 'transform' !== e.propertyName ) {
return;
}
key.element.classList.remove('playing');
}
/**
* Bind DOM events for this key
*/
key.element.addEventListener( 'transitionend', key.removeTransition );
key.element.addEventListener( 'touchstart', key.play );
key.element.addEventListener( 'click', key.play );
key.looper.addEventListener( 'touchdown', key.loop );
key.looper.addEventListener( 'click', key.loop );
} // end: Key()
// call the binding method on all keys
gz.keys.forEach( key => gz.Key.call( key ) );
/**
* Get a key object by keyCode
*/
gz.getKey = function( code ) {
code = parseInt( code );
var returnKey = null;
this.keys.forEach( key => {
if( key.code === code ) {
returnKey = key;
}
} );
return returnKey;
}
/**
* Callback for keydown event
*/
gz.keyDown = e => {
const key = gz.getKey( parseInt( e.keyCode ) );
if( ! key ) {
return;
}
key.play();
}
window.addEventListener( 'keydown', gz.keyDown );
})();
</script>
</body>
</html>
//
koh5_pano
Drag mouse to navigate.
Navigation
- Left/Right Mouse drag: Changes camera heading.
- Up/Sown Mouse drag: Changes camera pitch.
- Scroll wheel: Changes camera field of view.
- I-Key: Displays Info panel with canvas size, image size and FPS.
17.Aug.2010, Martin Wengenmayer