<p id="text" contenteditable>yes!</p>
<canvas id="confetti"></canvas>

<small>Click to start</small>
html {
	height: 100%;
}

body {
	height: 100%;
  	background: linear-gradient(to left, #12c2e9, #c471ed, #f64f59);
}

p {
	--yest: 0;
	font-family: "Chee";
	font-variation-settings: 'yest' var(--yest);
	font-size: 18vw;
	color: #5c1181;
	
	// Positioning
	position: absolute;
	top: 50%;
	transform: translate(0, -50%);
	margin: 0;
	width: 100%;
	text-align: center;
}

#confetti {
	position: absolute;
	top: 0%;
	left: 0%;
	width: 100%;
	height: 100%;
	z-index: -1;
}

small {
	text-align: center;
	position: absolute;
	bottom: 0;
	width: 100%;
	color: white;
	font-weight: bold;
	margin-bottom: 20px;
	font-size: 20px;
	text-transform: uppercase;
}
View Compiled
// Audio code from Ruth's Demo!! - https://codepen.io/Rumyra/pen/jomXeG
console.clear;
// create audio context and make sure it gets activated
const audioCtx = new AudioContext();
let data = new Uint8Array(2);

// create analyser 
const analyserNode = new AnalyserNode(audioCtx, {
	fftSize: 64,
	maxDecibels: -25,
	minDecibels: -60,
	smoothingTimeConstant: 0.5,
});

function getAnalyserData() {
	requestAnimationFrame(getAnalyserData);
	analyserNode.getByteFrequencyData(data);
	
	const minAxisValue = 1000;
	const maxAxisValue = 0;

	const minEventValue = 0;
	const maxEventValue = 255;
	
	// Get the current event value
	const element = document.querySelector("p");
    element.style.setProperty("--yest", 0);
	
    if (data[0] === 255) {
		element.style.setProperty("--yest", 1000);
		return
	} else {
		fluidAxisVariation(minAxisValue, maxAxisValue, minEventValue, maxEventValue, data[0],"--yest", element);
    }
}

// set draw after stream has started
function getStreamData() {
	// pipe in analysing to getUserMedia
	return navigator.mediaDevices.getUserMedia({ audio: true, video: false })
		.then(stream => audioCtx.createMediaStreamSource(stream))
		.then(source => {
			source.connect(analyserNode);
		});
}

// resume
window.addEventListener("click", event => {
	audioCtx.resume();
	getStreamData().then(getAnalyserData);
})
























// Fluid Axis Variation
function fluidAxisVariation(minimumAxisValue, maximumAxisValue, minimumEventValue, maximumEventValue, eventValue, axisCustomPropertyName, element) {

	const minAxisValue = minimumAxisValue;
	const maxAxisValue = maximumAxisValue;
    const minEventValue = minimumEventValue;
	const maxEventValue = maximumEventValue;
	const currentEventValue = eventValue;

	const eventPercent = (currentEventValue - minEventValue) / (maxEventValue - minEventValue);
	const fontAxisScale = eventPercent * (minAxisValue - maxAxisValue) + maxAxisValue;

	const newAxisValue = currentEventValue > maxEventValue
	   ? minAxisValue
       : currentEventValue < minEventValue
   			? maxAxisValue
   			: fontAxisScale;

    element.style.setProperty(axisCustomPropertyName, newAxisValue);
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.