Start trying to do some PWA action
This commit is contained in:
parent
9ca3b8ac9d
commit
b24a63b5c8
|
@ -9,6 +9,9 @@
|
||||||
<link rel="icon" type="image/png" href="{{ '/assets/images/face.png' | relative_url }}">
|
<link rel="icon" type="image/png" href="{{ '/assets/images/face.png' | relative_url }}">
|
||||||
{% if page.scripts %}{% for js_file in page.scripts %}
|
{% if page.scripts %}{% for js_file in page.scripts %}
|
||||||
<script src="{{ js_file }}"></script>
|
<script src="{{ js_file }}"></script>
|
||||||
|
{% endfor %}{% endif %}
|
||||||
|
{% if page.headers %}{% for header in page.headers %}
|
||||||
|
{{ header }}
|
||||||
{% endfor %}{% endif %}
|
{% endfor %}{% endif %}
|
||||||
<title>{{ page.title }}</title>
|
<title>{{ page.title }}</title>
|
||||||
</head>
|
</head>
|
||||||
|
@ -37,6 +40,7 @@
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="https://github.com/nealey/">GitHub</a></li>
|
<li><a href="https://github.com/nealey/">GitHub</a></li>
|
||||||
<li><a href="mailto:neale@woozle.org">Email</a></li>
|
<li><a href="mailto:neale@woozle.org">Email</a></li>
|
||||||
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
@ -14,18 +14,19 @@ body {
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
border-radius: 1em;
|
border-radius: 1em;
|
||||||
max-width: 35em;
|
max-width: 35em;
|
||||||
font-family: "Roboto", sans-serif;
|
font-family: "Lato", "Roboto", sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
#title, td.main {
|
#title, td.main {
|
||||||
background-color: #e0e4cc;
|
background-color: #e0e4cc;
|
||||||
border-radius: 0.5em;
|
border-radius: 0.25em;
|
||||||
padding: 0em 1em;
|
padding: 0.1em 0.5em;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
|
box-shadow: 0.2em 0.2em 1em rgba(0,0,0,0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
h1, h2, h3, h4, h5, h6 {
|
h1, h2, h3, h4, h5, h6 {
|
||||||
color: #fa6900;
|
color: #e64;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
|
@ -117,3 +118,11 @@ pre {
|
||||||
font-size: small;
|
font-size: small;
|
||||||
text-indent: inherit;
|
text-indent: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button.big {
|
||||||
|
padding: 0;
|
||||||
|
border: 0;
|
||||||
|
margin: 1em;
|
||||||
|
font-size: 2em;
|
||||||
|
background: inherit;
|
||||||
|
}
|
||||||
|
|
|
@ -1,13 +1,9 @@
|
||||||
<!DOCTYPE html>
|
---
|
||||||
<html lang="en-US">
|
title: Starship Noise Generator
|
||||||
<head>
|
scripts:
|
||||||
<meta charset='utf-8'>
|
- starship.js
|
||||||
<meta name="viewport" content="width=device-width">
|
---
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:regular,bold,italic">
|
|
||||||
<link rel="stylesheet" media="screen" href="/assets/css/default.css">
|
|
||||||
<link rel="icon" href="icon.svg">
|
|
||||||
<link rel="manifest" href="manifest.webmanifest">
|
|
||||||
<style>
|
|
||||||
#play {
|
#play {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
border: 0;
|
border: 0;
|
||||||
|
@ -15,76 +11,6 @@
|
||||||
font-size: 2em;
|
font-size: 2em;
|
||||||
background: inherit;
|
background: inherit;
|
||||||
}
|
}
|
||||||
</style>
|
|
||||||
|
|
||||||
<title>Starship Noise Generator</title>
|
|
||||||
<script>
|
|
||||||
function whiteNoise(audioCtx) {
|
|
||||||
var bufferSize = 17 * audioCtx.sampleRate,
|
|
||||||
noiseBuffer = audioCtx.createBuffer(1, bufferSize, audioCtx.sampleRate),
|
|
||||||
output = noiseBuffer.getChannelData(0);
|
|
||||||
for (var i = 0; i < bufferSize; i++) {
|
|
||||||
output[i] = Math.random() * 2 - 1;
|
|
||||||
}
|
|
||||||
var whiteNoise = audioCtx.createBufferSource();
|
|
||||||
whiteNoise.buffer = noiseBuffer;
|
|
||||||
whiteNoise.loop = true;
|
|
||||||
whiteNoise.start(0);
|
|
||||||
return whiteNoise;
|
|
||||||
}
|
|
||||||
|
|
||||||
function bandpassFilter(audioCtx, freq, gain) {
|
|
||||||
var filt = audioCtx.createBiquadFilter();
|
|
||||||
filt.type = "bandpass";
|
|
||||||
filt.frequency.value = freq;
|
|
||||||
filt.gain.value = gain;
|
|
||||||
return filt;
|
|
||||||
}
|
|
||||||
|
|
||||||
function init() {
|
|
||||||
var audioCtx = new window.AudioContext();
|
|
||||||
var synth = whiteNoise(audioCtx);
|
|
||||||
var filterA = bandpassFilter(audioCtx, 100, 20);
|
|
||||||
var filterB = bandpassFilter(audioCtx, 50, 20);
|
|
||||||
var gainA = audioCtx.createGain();
|
|
||||||
|
|
||||||
whiteNoise(audioCtx).connect(filterA);
|
|
||||||
filterA.connect(filterB);
|
|
||||||
filterB.connect(gainA);
|
|
||||||
gainA.connect(audioCtx.destination);
|
|
||||||
audioCtx.suspend();
|
|
||||||
|
|
||||||
function setFade() {
|
|
||||||
var faderPos = document.querySelector("#fader").value;
|
|
||||||
gainA.gain.value = faderPos;
|
|
||||||
}
|
|
||||||
document.querySelector("#fader").addEventListener("input", setFade);
|
|
||||||
setFade();
|
|
||||||
|
|
||||||
document.querySelector("#play").addEventListener("click", e => {
|
|
||||||
console.log(audioCtx.state);
|
|
||||||
if (audioCtx.state == 'running') {
|
|
||||||
audioCtx.suspend();
|
|
||||||
} else {
|
|
||||||
audioCtx.resume();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (document.readyState === "loading") {
|
|
||||||
document.addEventListener("DOMContentLoaded", init);
|
|
||||||
} else {
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<h1 id="title">
|
|
||||||
<span>Starship Noise Generator</span>
|
|
||||||
</h1>
|
|
||||||
|
|
||||||
<main id="content">
|
|
||||||
<div>
|
<div>
|
||||||
<button id="play">⏯️</button>
|
<button id="play">⏯️</button>
|
||||||
🔉
|
🔉
|
||||||
|
@ -92,20 +18,16 @@ if (document.readyState === "loading") {
|
||||||
🔊
|
🔊
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>I work in a building with no HVAC,
|
I work in a building with no HVAC,
|
||||||
which means we can hear <em>everything</em> people are saying,
|
which means we can hear <em>everything</em> people are saying,
|
||||||
anywhere in the building.</p>
|
anywhere in the building.
|
||||||
|
|
||||||
<p>This page is a low-CPU noise generator that runs entirely in JavaScript.
|
This page is a low-CPU noise generator that runs entirely in JavaScript.
|
||||||
Once it starts,
|
Once it starts,
|
||||||
you don’t need an Internet connection to keep it going.
|
you don’t need an Internet connection to keep it going.
|
||||||
You can leave it running forever, if you like.</p>
|
You can leave it running forever, if you like.
|
||||||
|
|
||||||
<p>For those interested,
|
For those interested,
|
||||||
it uses the new (in 2017) and seriously perfect for this application
|
it uses the new (in 2017) and seriously perfect for this application
|
||||||
<a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API">Web Audio API</a>.</p>
|
[Web Audio API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API)
|
||||||
</main>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"name": "Starship Noise Generator",
|
||||||
|
"short_name": "Starship",
|
||||||
|
"start_url": ".",
|
||||||
|
"display": "standalone",
|
||||||
|
"background_color": "#fff",
|
||||||
|
"description": "Generates brown noise similar to a futuristic starship engine (or a modern HVAC system)",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "icon.svg",
|
||||||
|
"sizes": "any"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
function whiteNoise(audioCtx) {
|
||||||
|
var bufferSize = 17 * audioCtx.sampleRate,
|
||||||
|
noiseBuffer = audioCtx.createBuffer(1, bufferSize, audioCtx.sampleRate),
|
||||||
|
output = noiseBuffer.getChannelData(0);
|
||||||
|
for (var i = 0; i < bufferSize; i++) {
|
||||||
|
output[i] = Math.random() * 2 - 1;
|
||||||
|
}
|
||||||
|
var whiteNoise = audioCtx.createBufferSource();
|
||||||
|
whiteNoise.buffer = noiseBuffer;
|
||||||
|
whiteNoise.loop = true;
|
||||||
|
whiteNoise.start(0);
|
||||||
|
return whiteNoise;
|
||||||
|
}
|
||||||
|
|
||||||
|
function bandpassFilter(audioCtx, freq, gain) {
|
||||||
|
var filt = audioCtx.createBiquadFilter();
|
||||||
|
filt.type = "bandpass";
|
||||||
|
filt.frequency.value = freq;
|
||||||
|
filt.gain.value = gain;
|
||||||
|
return filt;
|
||||||
|
}
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
var audioCtx = new window.AudioContext();
|
||||||
|
var synth = whiteNoise(audioCtx);
|
||||||
|
var filterA = bandpassFilter(audioCtx, 100, 20);
|
||||||
|
var filterB = bandpassFilter(audioCtx, 50, 20);
|
||||||
|
var gainA = audioCtx.createGain();
|
||||||
|
|
||||||
|
whiteNoise(audioCtx).connect(filterA);
|
||||||
|
filterA.connect(filterB);
|
||||||
|
filterB.connect(gainA);
|
||||||
|
gainA.connect(audioCtx.destination);
|
||||||
|
audioCtx.suspend();
|
||||||
|
|
||||||
|
function setFade() {
|
||||||
|
var faderPos = document.querySelector("#fader").value;
|
||||||
|
gainA.gain.value = faderPos;
|
||||||
|
}
|
||||||
|
document.querySelector("#fader").addEventListener("input", setFade);
|
||||||
|
setFade();
|
||||||
|
|
||||||
|
document.querySelector("#play").addEventListener("click", e => {
|
||||||
|
if (audioCtx.state == "running") {
|
||||||
|
audioCtx.suspend();
|
||||||
|
} else {
|
||||||
|
audioCtx.resume();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(navigator.serviceWorker);
|
||||||
|
console.log("moo");
|
||||||
|
if ("serviceWorker" in navigator) {
|
||||||
|
navigator.serviceWorker.register("sw.js");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document.readyState === "loading") {
|
||||||
|
document.addEventListener("DOMContentLoaded", init);
|
||||||
|
} else {
|
||||||
|
init();
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
var cacheName = "starship-v1";
|
||||||
|
var content = [
|
||||||
|
"index.html",
|
||||||
|
"starship.js"
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
self.addEventListener("install", e => {
|
||||||
|
e.waitUntil(caches.Open(cacheName).then(cache => cache.addAll(content)));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Have mercy, this is a horror show
|
||||||
|
self.addEventListener("fetch", e => {
|
||||||
|
e.respondWith(
|
||||||
|
caches.match(e.request).then(r => {
|
||||||
|
console.log("[Service Worker] Fetching resource:", e.request.url);
|
||||||
|
return r || fetch(e.request).then(response => {
|
||||||
|
return caches.open(cacheName).then(cache => {
|
||||||
|
console.log("[Service Worker] Caching new resource:", e.request.url);
|
||||||
|
cache.put(e.request, respone.clone());
|
||||||
|
return response;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
Loading…
Reference in New Issue