Created
October 28, 2018 17:14
-
-
Save unixpickle/0c02dec3186257f1f0caeec47f247f10 to your computer and use it in GitHub Desktop.
Squircle smiley face VC
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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