Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

interaction optimization #3

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
26 changes: 17 additions & 9 deletions src/audio-controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,28 @@ module.exports = function createAudioControls (audio, tracks) {
tracks.map((track, i) => {
const trackEl = trackSelector.appendChild(document.createElement('li'))
trackEl.classList.add('track')
let togglePlay = true
trackEl.addEventListener('click', () => {
setTrack(tracks[i])
audio.play()
if (togglePlay || !audio.src.endsWith(tracks[i].path)) {
setTrack(tracks[i])
audio.play()
} else {
audio.pause()
}
togglePlay = !togglePlay
})
trackEl.innerHTML = '<span>0' + (1 + i) + '.</span> ' + track.title
track.el = trackEl
})

function setTrack (track) {
audio.src = track.path
tracks.forEach(t => t.el.classList.remove('selected'))
track.el.classList.add('selected')
titleEl.innerText = track.title
artistEl.innerText = track.artist
if (!audio.src.endsWith(track.path)) {
audio.src = track.path
tracks.forEach(t => t.el.classList.remove('selected'))
track.el.classList.add('selected')
titleEl.innerText = track.title
artistEl.innerText = track.artist
}
}

setTrack(tracks[0])
Expand All @@ -48,7 +56,7 @@ module.exports = function createAudioControls (audio, tracks) {
audio.currentTime = t * audio.duration
})

window.addEventListener('keypress', (e) => {
window.addEventListener('keypress', e => {
if (e.key === ' ') {
togglePlay()
}
Expand All @@ -69,7 +77,7 @@ module.exports = function createAudioControls (audio, tracks) {
}

function formatSeconds (seconds) {
const minutes = seconds / 60 | 0
const minutes = (seconds / 60) | 0
seconds = '' + (seconds % 60 | 0)
if (seconds.length === 1) {
seconds = `0${seconds}`
Expand Down
Binary file added src/audio/friendship-era.mp3
Binary file not shown.
140 changes: 98 additions & 42 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,36 @@ const createRenderGrid = require('./render-grid')
const titleCard = createTitleCard()
const canvas = document.querySelector('canvas.viz')
const resize = fit(canvas)
window.addEventListener('resize', () => {
resize()
if (hasSetUp) setup()
titleCard.resize()
}, false)
window.addEventListener(
'resize',
() => {
resize()
if (hasSetUp) setup()
titleCard.resize()
},
false
)
const camera = createCamera(canvas, [2.5, 2.5, 2.5], [0, 0, 0])
const regl = createRegl(canvas)

let analyser, delaunay, points, positions, positionsBuffer, renderFrequencies,
renderGrid, blurredFbo, renderToBlurredFBO

const getFrameBuffer = (width, height) => (
let analyser,
delaunay,
points,
positions,
positionsBuffer,
renderFrequencies,
renderGrid,
blurredFbo,
renderToBlurredFBO

const getFrameBuffer = (width, height) =>
regl.framebuffer({
color: regl.texture({
shape: [width, height, 4]
}),
depth: false,
stencil: false
})
)

const fbo = getFrameBuffer(512, 512)
const freqMapFBO = getFrameBuffer(512, 512)
Expand All @@ -52,17 +62,45 @@ const renderBloom = createRenderBloom(regl, canvas)
const renderBlur = createRenderBlur(regl)

const tracks = [
{title: '715 - CRΣΣKS', artist: 'Bon Iver', path: 'src/audio/715-creeks.mp3'},
{title: 'Another New World', artist: 'Punch Brothers', path: 'src/audio/another-new-world.mp3'},
{title: 'The Wilder Sun', artist: 'Jon Hopkins', path: 'src/audio/the-wilder-sun.mp3'},
{title: 'Lost It To Trying', artist: 'Son Lux', path: 'src/audio/lost-it-to-trying.mp3'},
{title: 'Adagio for Strings', artist: 'Samuel Barber', path: 'src/audio/adagio-for-strings.mp3'}
{
title: '715 - CRΣΣKS',
artist: 'Bon Iver',
path: 'src/audio/715-creeks.mp3'
},
{
title: 'Another New World',
artist: 'Punch Brothers',
path: 'src/audio/another-new-world.mp3'
},
{
title: 'The Wilder Sun',
artist: 'Jon Hopkins',
path: 'src/audio/the-wilder-sun.mp3'
},
{
title: 'Lost It To Trying',
artist: 'Son Lux',
path: 'src/audio/lost-it-to-trying.mp3'
},
{
title: 'Adagio for Strings',
artist: 'Samuel Barber',
path: 'src/audio/adagio-for-strings.mp3'
},
{
title: 'friendship-era',
artist: "I'm singer",
path: 'src/audio/friendship-era.mp3'
}
]

const audio = createPlayer(tracks[0].path)
audio.on('load', function () {
window.audio = audio
analyser = createAnalyser(audio.node, audio.context, { audible: true, stereo: false })
analyser = createAnalyser(audio.node, audio.context, {
audible: true,
stereo: false
})
const audioControls = createAudioControls(audio.element, tracks)

function loop () {
Expand All @@ -83,7 +121,8 @@ audio.on('load', function () {
const renderLoop = startLoop()
setTimeout(renderLoop.cancel.bind(renderLoop), 1000)

titleCard.show()
titleCard
.show()
.then(() => new Promise(resolve => setTimeout(resolve, 1000)))
.then(() => {
css(audioControls.el, {
Expand Down Expand Up @@ -135,16 +174,28 @@ css(gui.domElement.parentElement, {
opacity: 0
})
const fabricGUI = gui.addFolder('fabric')
fabricGUI.add(settings, 'dampening', 0.01, 1).step(0.01).onChange(setup)
fabricGUI.add(settings, 'stiffness', 0.01, 1).step(0.01).onChange(setup)
fabricGUI.add(settings, 'connectedNeighbors', 0, 7).step(1).onChange(setup)
fabricGUI
.add(settings, 'dampening', 0.01, 1)
.step(0.01)
.onChange(setup)
fabricGUI
.add(settings, 'stiffness', 0.01, 1)
.step(0.01)
.onChange(setup)
fabricGUI
.add(settings, 'connectedNeighbors', 0, 7)
.step(1)
.onChange(setup)
fabricGUI.add(settings, 'neighborWeight', 0.8, 1).step(0.01)
const bloomGUI = gui.addFolder('bloom')
bloomGUI.add(settings, 'blurRadius', 0, 20).step(1)
bloomGUI.add(settings, 'blurWeight', 0, 2).step(0.01)
bloomGUI.add(settings, 'originalWeight', 0, 2).step(0.01)
const gridGUI = gui.addFolder('grid')
gridGUI.add(settings, 'gridLines', 10, 300).step(1).onChange(setup)
gridGUI
.add(settings, 'gridLines', 10, 300)
.step(1)
.onChange(setup)
gridGUI.add(settings, 'linesAnimationOffset', 0, 100).step(1)
gridGUI.add(settings, 'gridMaxHeight', 0.01, 0.8).step(0.01)
// gui.add(settings, 'motionBlur')
Expand All @@ -166,10 +217,7 @@ function setup () {
for (let q = 0; q < frequenciesCount; q += settings.connectedBinsStride) {
const mag = Math.pow(rand(), 1 - q / frequenciesCount) * 0.9
const rads = rand() * Math.PI * 2
const position = [
Math.cos(rads) * mag,
Math.sin(rads) * mag
]
const position = [Math.cos(rads) * mag, Math.sin(rads) * mag]
const id = points.length
const point = createPoint(id, position)
point.frequencyBin = q
Expand All @@ -186,11 +234,15 @@ function setup () {
position: position,
id: id,
neighbors: new Set(), // gonna fill this up with the results of delaunay
spring: createSpring(settings.dampening * settings.stiffness, settings.stiffness, 0)
spring: createSpring(
settings.dampening * settings.stiffness,
settings.stiffness,
0
)
}
}

delaunay = new Delaunator(points.map((pt) => pt.position))
delaunay = new Delaunator(points.map(pt => pt.position))
for (let j = 0; j < delaunay.triangles.length; j += 3) {
const pt1 = delaunay.triangles[j]
const pt2 = delaunay.triangles[j + 1]
Expand All @@ -205,7 +257,10 @@ function setup () {
}

points.forEach(pt => {
pt.neighbors = shuffle(Array.from(pt.neighbors)).slice(0, settings.connectedNeighbors)
pt.neighbors = shuffle(Array.from(pt.neighbors)).slice(
0,
settings.connectedNeighbors
)
})

positions = new Float32Array(delaunay.triangles.length * 3)
Expand Down Expand Up @@ -249,7 +304,9 @@ function update () {
const neighborSum = neighbors.reduce((total, ptID) => {
return total + points[ptID].spring.tick(1, false)
}, 0)
const neighborAverage = neighbors.length ? neighborSum / neighbors.length : 0
const neighborAverage = neighbors.length
? neighborSum / neighbors.length
: 0
value = Math.max(value, neighborAverage * settings.neighborWeight)

pt.spring.updateValue(value)
Expand All @@ -269,13 +326,14 @@ function update () {

const renderGlobals = regl({
uniforms: {
projection: ({viewportWidth, viewportHeight}) => mat4.perspective(
[],
Math.PI / 4,
viewportWidth / viewportHeight,
0.01,
1000
),
projection: ({ viewportWidth, viewportHeight }) =>
mat4.perspective(
[],
Math.PI / 4,
viewportWidth / viewportHeight,
0.01,
1000
),
view: () => camera.getMatrix(),
time: ({ time }) => time
}
Expand Down Expand Up @@ -313,11 +371,7 @@ const renderColoredQuad = regl({
color: regl.prop('color')
},
attributes: {
position: [
-1, -1,
-1, 4,
4, -1
]
position: [-1, -1, -1, 4, 4, -1]
},
count: 3,
primitive: 'triangles'
Expand All @@ -343,7 +397,9 @@ function startLoop () {
})
renderToBlurredFBO(() => {
if (settings.motionBlur) {
renderColoredQuad({ color: [0.18, 0.18, 0.18, settings.motionBlurAmount] })
renderColoredQuad({
color: [0.18, 0.18, 0.18, settings.motionBlurAmount]
})
} else {
regl.clear({
color: [0.18, 0.18, 0.18, 1],
Expand Down