Skip to content

Instantly share code, notes, and snippets.

@unixpickle
Created October 28, 2018 17:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save unixpickle/0c02dec3186257f1f0caeec47f247f10 to your computer and use it in GitHub Desktop.
Save unixpickle/0c02dec3186257f1f0caeec47f247f10 to your computer and use it in GitHub Desktop.
Squircle smiley face VC
function(canvas, video) {
function setupAudioLevel() {
window.HACK_VOLUME_LEVEL = 0.0;
navigator.mediaDevices.getUserMedia({ audio: true, video: false }).then((stream) => {
const ctx = new AudioContext();
const source = ctx.createMediaStreamSource(stream);
const node = ctx.createScriptProcessor(4096, 1, 1);
node.onaudioprocess = (event) => {
const buffer = event.inputBuffer.getChannelData(0);
let sum = 0;
for (let i = 0; i < buffer.length; ++i) {
sum += Math.abs(buffer[i]);
}
window.HACK_VOLUME_LEVEL = sum / buffer.length;
};
source.connect(node);
node.connect(ctx.destination);
});
}
if ('undefined' === typeof window.HACK_VOLUME_LEVEL) {
setupAudioLevel();
window.HACK_ROLLING_MAX = [];
}
window.HACK_ROLLING_MAX.push(window.HACK_VOLUME_LEVEL);
while (window.HACK_ROLLING_MAX.length > 100) {
window.HACK_ROLLING_MAX.shift();
}
const maxVolume = window.HACK_ROLLING_MAX.reduce((a, b) => Math.max(a, b), 0.01);
window.HACK_EYE_INTENSITY = (window.HACK_EYE_INTENSITY || 0) + 0.02;
const intensity = Math.pow(Math.sin(window.HACK_EYE_INTENSITY), 2);
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
const scale = Math.min(canvas.width, canvas.height);
const cx = canvas.width / 2;
const cy = canvas.height / 2;
ctx.lineWidth = scale / 50;
ctx.lineJoin = 'round';
function drawSquircle(cx, cy, radius) {
var size = radius * 2;
var sideLength = size / Math.sqrt(2);
var offset = (size - sideLength) / 2;
ctx.save();
ctx.translate(cx - radius, cy - radius);
ctx.beginPath();
if (intensity < 0.01) {
ctx.moveTo(offset, offset);
ctx.lineTo(offset + sideLength, offset);
ctx.lineTo(offset + sideLength, offset + sideLength);
ctx.lineTo(offset, offset + sideLength);
} else {
var radius = (size / 2) / intensity;
var y = offset + Math.sqrt(radius * radius - Math.pow(sideLength, 2) / 4);
var angleSize = Math.asin(sideLength / (2*radius));
ctx.arc(size / 2, y, radius, 3 * Math.PI / 2 - angleSize,
3 * Math.PI / 2 + angleSize, false);
ctx.arc(size - y, size / 2, radius, -angleSize, angleSize, false);
ctx.arc(size / 2, size - y, radius, Math.PI / 2 - angleSize,
Math.PI / 2 + angleSize, false);
ctx.arc(y, size / 2, radius, Math.PI - angleSize, Math.PI + angleSize, false);
}
ctx.closePath();
ctx.fill();
ctx.stroke();
ctx.restore();
}
// Face
ctx.strokeStyle = 'brown';
ctx.fillStyle = 'yellow';
drawSquircle(cx, cy, scale / 2 - scale / 50);
// Eyes
ctx.strokeStyle = 'black';
ctx.fillStyle = 'rgba(' + Math.round(intensity * 255) + ', 0, 0, 1.0)';
drawSquircle(cx - scale * 0.15, cy - scale * 0.1, scale * 0.1);
drawSquircle(cx + scale * 0.15, cy - scale * 0.1, scale * 0.1);
// Mouth
ctx.strokeStyle = 'red';
ctx.fillStyle = 'white';
const mouthHeight = scale * 0.1 * (0.5 + window.HACK_VOLUME_LEVEL / maxVolume);
ctx.beginPath();
ctx.rect(cx - scale * 0.12, cy + scale * 0.175 - mouthHeight / 2, scale * 0.24, mouthHeight);
ctx.fill();
ctx.stroke();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment