Skip to content

Instantly share code, notes, and snippets.

@monfera

monfera/.block

Last active May 8, 2017
Embed
What would you like to do?
Device access on bl.ocks.org
license: mit
border: no
height: 560

Shows that bl.ocks.org is capable of running with https. Just change the URL to start with https:// or click here. The utility of https is that devices are accessible if the user permits. For example, this block from Curran Kelleher works similarly.

It's just a copy of a piece of code I used for an overly early talk about D3 4.0 (slides of historical interest are here). Don't look at the code as it uses v0.1 etc. deep pre-alpha versions of D3 4.0 code.

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3-path.v0.1.min.js"></script>
<script src="https://d3js.org/d3-timer.v0.2.min.js"></script>
</head>
<body>
<canvas></canvas>
<script>
// Grid 2
// Web Audio works w/ Chrome & FF
// Put https:// before the codepen URL
// as WebAudio needs SSL
/*
* D3 lookalike functionality
*/
// We don't have a d3 object as we selectively import plugins
const d3 = Object.assign(
{},
d3_path,
d3_timer
)
// We have no d3.select or d3.selectAll, so... no data binding
function select(s) {
return document.querySelector(s)
}
function attr(element, attribute, value) {
element.setAttribute(attribute, value)
}
function style(element, property, value) {
element.style[property] = value
}
/*
* Setup the canvas
*/
const width = document.documentElement.clientWidth
const height = document.documentElement.clientHeight
const aaMultiple = window.devicePixelRatio
const canvas = select('canvas')
attr(canvas, 'width', width * aaMultiple)
attr(canvas, 'height', height * aaMultiple)
style(canvas, 'width', 100 + '%')
style(canvas, 'height', 100 + '%')
const canvasContext = canvas.getContext('2d')
/*
* Render a circle
*/
const lineWidth = 0.5
const radius = 31
function render(context, x, y, radius, s) {
const r = radius * s
context.moveTo(x * s + r, y * s)
context.arc(x * s , y * s, r, 0, 2 * Math.PI)
}
/*
* Render the audio visualisation
*/
canvasContext.strokeStyle = 'rgba(0,0,0,1)'
canvasContext.fillStyle = 'rgba(255,255,255,.1)'
function renderOnCanvas(context, frequencyData) {
context.lineWidth = aaMultiple * lineWidth
context.fillRect(
0, 0,
width * aaMultiple, height * aaMultiple
)
context.beginPath()
for(let j = 0; j < 10; j++) {
for(let i = 0; i < 10; i++) {
render(
context,
(i + 1 ) * 2 * radius //,
+ (j % 2) * radius, // hex
-radius / 2 + (9 - j + 1) * 2 // * radius,
* (radius ** 2 - (radius / 2) ** 2) ** 0.5,
frequencyData[(i + 10 * j) * 2] * radius / 255,
aaMultiple
)
}
}
context.stroke()
}
/*
* Audio input and analyser
*/
navigator.getUserMedia = MediaDevices.getUserMedia
|| navigator.webkitGetUserMedia
|| navigator.mozGetUserMedia
const audioApi = new AudioContext()
function makeAnalyser(source) {
const analyser = audioApi.createAnalyser()
analyser.fftSize = 2048
analyser.smoothingTimeConstant = 0.5
source.connect(analyser)
return analyser
}
function onStream(stream) {
const source = audioApi.createMediaStreamSource(stream)
const analyser = makeAnalyser(source)
const frequencyData = new Uint8Array(1024)
d3.timer(t => {
// side effect: refresh frequencyData
analyser.getByteFrequencyData(frequencyData)
// side effect: rerender on canvas
renderOnCanvas(canvasContext, frequencyData)
})
}
navigator.getUserMedia(
{audio:true},
onStream,
function(error) {
console.log("Error: " + error)
}
)
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment