<div class="container">
<h1 class="header-title">Redbox Tone Generator 🔊</h1>
<p>Click a button to play the corresponding tone</p>
<div class="buttons">
<button class="tone" onclick="playNickel()">Nickel</button>
<button class="tone" onclick="playDime()">Dime</button>
<button class="tone" onclick="playQuarter()">Quarter</button>
<button class="tone" onclick="playDollar()">Dollar</button>
</div>
</div>
@charset "UTF-8";
@import url("https://fonts.googleapis.com/css2?family=Press+Start+2P&family=IBM+Plex+Mono:ital,wght@0,500&display=swap");
:root {
font-size: 18px;
--font-family: "IBM Plex Mono";
--font-family-headline: "Press Start 2p";
--color-bg-image-1: #000;
--color-bg-image-2: #1bb;
--color-text: #b8afaa;
--color-bg: #000;
--color-link: #968a84;
--color-link-hover: #fff;
--page-padding: 1rem;
--color-highlight-start: #968a84;
--color-highlight-end: #968a84;
--color-highlight-end-alt: #968a84;
}
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html {
block-size: 100%;
}
body {
min-block-size: 100%;
margin: 0;
display: grid;
place-content: center;
gap: 1rem;
color: var(--color-text);
background-color: var(--color-bg);
font-family: var(--font-family), serif;
line-height: 1;
font-weight: 300;
font-feature-settings: "liga";
font-feature-settings: "liga";
font-feature-settings: "liga";
osx-font-smoothing: grayscale;
font-smoothing: antialiased;
text-rendering: optimizeLegibility;
text-transform: none;
word-wrap: normal;
font-size: 20px;
margin-block: 0;
margin-inline: 4px 0;
vertical-align: text-bottom;
height: 100vh;
background: linear-gradient(0.25turn, #3f87a6, #ebf8e1, #3f87a6);
}
h1.header-title {
font-size: 2rem;
font-family: var(--font-family-headline), sans-serif;
margin-bottom: 20px;
}
div.container {
text-align: center;
padding: 20px;
margin: 5px;
border: 1px solid #666;
background: rgba(0, 0, 0, 0.7);
border-radius: 8px;
backdrop-filter: blur(5px);
max-width: 458px;
}
div.buttons {
border: 1px inset #eee;
margin-top: 15px;
}
button.tone {
min-width: 150px;
padding: 15px 30px;
margin: 10px;
font-size: 16px;
cursor: pointer;
border: none;
border-radius: 0px;
/*green*/
/*
background-color: #4caf50;
background: linear-gradient(#4caf50,#61af4c);
border:2px ridge #5eba62;
*/
/*red*/
background-color: #bb0000;
background: linear-gradient(#dd0000, #bb0000, #9a0000);
border: 2px ridge #790001;
color: white;
}
button.tone:before {
transform: perspective(500px) translate3d(0px, 0, 0px);
}
button.tone:hover {
border: 2px ridge #790001;
text-shadow: 0px 0px 4px #ffffff;
text-shadow: 0px 0px 4px #ffffff;
text-shadow: 0px 0px 4px #ffffff;
}
button.tone:active {
transform: perspective(500px) translate3d(0px, 0, -70px);
}
button {
/* IOS fixes - Safari is the new IE */
appearance: none;
tap-highlight-color: transparent;
touch-callout: none;
user-select: none;
pointer-events: auto;
cursor: pointer;
touch-action: manipulation;
}
// IOS fixes - Safari is the new IE
document.querySelectorAll("button").forEach((button) => {
button.addEventListener("touchstart", () => button.classList.add("active"));
button.addEventListener("touchend", () => button.classList.remove("active"));
});
function playRedboxTone(
frequency1,
frequency2,
beepDuration,
beepCount,
pauseDuration,
repeatCount = 1
) {
const context = new (window.AudioContext || window.webkitAudioContext)();
function createOscillator(freq, startTime, duration) {
let osc = context.createOscillator();
let gainNode = context.createGain();
osc.frequency.setValueAtTime(freq, context.currentTime);
osc.type = "sine";
osc.connect(gainNode);
gainNode.connect(context.destination);
gainNode.gain.setValueAtTime(1, startTime);
gainNode.gain.setValueAtTime(0, startTime + duration);
osc.start(startTime);
osc.stop(startTime + duration);
}
let startTime = context.currentTime;
// Loop through beeps and create with pauses in between
for (let r = 0; r < repeatCount; r++) {
for (let i = 0; i < beepCount; i++) {
createOscillator(frequency1, startTime, beepDuration);
createOscillator(frequency2, startTime, beepDuration);
startTime += beepDuration + pauseDuration;
}
// longer pause between repetitions of the entire sequence
startTime += 0.5;
}
}
// Nickel: 1 beep
function playNickel() {
playRedboxTone(2200, 1700, 0.066, 1, 0, 1);
}
// Dime: 2 beeps with 66ms pause
function playDime() {
playRedboxTone(2200, 1700, 0.066, 2, 0.066, 1);
}
// Quarter: 5 beeps with 33ms pause, repeating
function playQuarter() {
playRedboxTone(2200, 1700, 0.033, 5, 0.033, 1);
}
// 4 Quarters
function playDollar() {
playRedboxTone(2200, 1700, 0.033, 5, 0.033, 4);
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.