Last active
August 29, 2015 14:15
-
-
Save qgustavor/261a0902743f94027c08 to your computer and use it in GitHub Desktop.
Faster "Stronger"
This file contains hidden or 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
<!doctype html> | |
<!-- Use cdn.rawgit.com or htmlpreview.github.io to test --> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width"> | |
<meta property="og:title" content="Harder, Better, Faster, Stronger"/> | |
<meta property="og:url" content="http://davealger.c.mom/stronger/"/> | |
<meta property="og:image" content="http://davealger.com/stronger/punk_small.jpg"/> | |
<meta property="og:site_name" content="davealger.com"/> | |
<meta property="og:description" content="a daft punk sound pad."/> | |
<script src="//cdnjs.cloudflare.com/ajax/libs/paper.js/0.9.21/paper-full.min.js"></script> | |
<script src="//cdn.rawgit.com/IonDen/ion.sound/71e5c138eda7ff386ceefa1cd0f902567c7b6c57/js/ion.sound.min.js"></script> | |
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/normalize/3.0.2/normalize.min.css"> | |
<style>html,body{overflow:hidden;background:#111;}</style> | |
</head> | |
<body> | |
<!-- disabled facebook, I don't know how those social thing works also it was above touch input --> | |
<!-- pretty much everything is drawn dynamically using paper.js --> | |
<canvas id="strongerCanvas" resize></canvas> | |
<script type="text/paperscript" canvas="strongerCanvas"> | |
// Set color variables | |
var lightCell = '#CCC'; | |
var selectedCell = '#FF8'; | |
var selectedMode = '#FF0'; | |
var unselectedMode = '#880'; | |
var playCell = '#8F8'; | |
// Current playing mode | |
var mode = 0; | |
// Those variables change on resizing | |
var width, height; | |
// Width, height, margin and array of cells (or buttons) | |
var sW, sH; | |
var margin = 4; | |
var cells = []; | |
// Play/pause element | |
var isPlaying = false; | |
var playSegments = [[0, 0], [40, 20], [0, 40]]; | |
var pauseSegments = [[0, 0], [40, 0], [40, 40], [0, 40]]; // Actualy is more a stop: | |
var playElement; | |
// Help elements | |
var helpEl; | |
// Default keymapping is QWERTY: | |
var keymapping = { | |
'q': [0, 0], | |
'w': [1, 0], | |
'e': [2, 0], | |
'r': [3, 0], | |
'a': [0, 1], | |
's': [1, 1], | |
'd': [2, 1], | |
'f': [3, 1], | |
'y': [0, 2], | |
'u': [1, 2], | |
'i': [2, 2], | |
'o': [3, 2], | |
'h': [0, 3], | |
'j': [1, 3], | |
'k': [2, 3], | |
'l': [3, 3], | |
// mode buttons | |
'z': [4, 0], | |
'x': [4, 1], | |
'c': [4, 2], | |
'space': [4, 3] | |
}; | |
var customizingState = { | |
lastMode: null, | |
coords: null, | |
selectedCell: null, | |
textElements: [] | |
}; | |
initializePath(); | |
function initializePath() { | |
var box; | |
width = view.size.width; | |
height = view.size.height; | |
sW = width / 5; | |
sH = height / 4; | |
// remove already existing cells | |
cells.forEach(function (e) { | |
e.remove(); | |
}); | |
cells = []; | |
// Create array of cells | |
var index = 0; | |
for(var boxY = 0; boxY < 4; boxY++) { | |
for(var boxX = 0; boxX < 5; boxX++) { | |
// Creates a rounded rectangle with margin: | |
box = new Path.Rectangle( | |
new Rectangle( | |
boxX * sW + margin, boxY * sH + margin, | |
sW - 2 * margin, sH - 2 * margin), | |
margin * (boxX === 4 ? 4 : 2)); | |
box.fillColor = boxX === 4 ? ( | |
// Button is a mode button | |
boxY === 0 ? selectedMode : boxY === 3 ? playCell : unselectedMode | |
) : lightCell; | |
cells.push(box); | |
} | |
} | |
if (playElement) { | |
playElement.remove(); | |
} | |
playElement = new Path({ | |
segments: isPlaying ? pauseSegments : playSegments, | |
fillColor: 'black', | |
closed: true | |
}); | |
playElement.position = new Point(width - sW / 2, height - sH / 2); | |
} | |
function onMouseDown(event) { | |
var mX = event.point.x; | |
var mY = event.point.y; | |
var jR = Math.floor(mX / sW); | |
var jD = Math.floor(mY / sH); | |
var textElements = customizingState.textElements; | |
textElements.forEach(function (e) { | |
e.remove(); | |
}); | |
if (mode === 3) { | |
mode = customizingState.lastState; | |
customizingState.selectedCell.fillColor = lightCell; | |
customizingState.selectedCell = null; | |
} | |
if (mode === 2 && jD > 1) { | |
// Do something with the help | |
window.open('https://www.reddit.com/duplicates/2vq8t0'); | |
} else if (event.event.ctrlKey) { | |
customizingState.lastState = mode; | |
customizingState.coords = [jR, jD]; | |
customizingState.selectedCell = cells[jR + (jD * 5)]; | |
mode = 3; | |
for (var row = 0; row < 4; row++) { | |
for (var col = 0; col < 5; col++) { | |
for (var mapping in keymapping) { | |
if (keymapping[mapping][1] === row && keymapping[mapping][0] === col) { | |
textElements[row * 5 + col] = new PointText({ | |
point: [margin * 8 + col * sW, row * sH + margin * 8], | |
content: mapping, | |
fillColor: 'black', | |
fontFamily: 'Courier New', | |
fontWeight: 'bold', | |
fontSize: 18 | |
}); | |
if (row === jD && col === jR) { | |
customizingState.oldMapping = mapping; | |
} | |
break; | |
} | |
} | |
} | |
} | |
} else { | |
processInput(jR, jD); | |
} | |
} | |
function onKeyDown(evt) { | |
if (evt.event.shitKey || evt.event.ctrlKey || evt.event.altKey) {return;} | |
if (mode === 3) { | |
// key customizing mode | |
keymapping[evt.key] = customizingState.coords; | |
delete keymapping[customizingState.oldMapping]; | |
mode = customizingState.lastState; | |
customizingState.selectedCell = null; | |
var textElements = customizingState.textElements; | |
textElements.forEach(function (e) { | |
e.remove(); | |
}); | |
textElements = []; | |
} | |
var key = keymapping[evt.key]; | |
if (key) { | |
processInput(key[0], key[1]); | |
} | |
} | |
function processInput(jR, jD) { | |
var cellsum = jR + (jD * 5); | |
var punNum = jR + (jD * 4) + mode * 16 + 1; | |
var box = cells[cellsum]; | |
if (jR === 4) { | |
if (jD === 3) { | |
playBackBacking(); | |
} else { | |
for (var row = 0; row < 3; row++) { | |
cells[row * 5 + 4].fillColor = (row === jD) ? selectedMode : unselectedMode; | |
} | |
if (jD === 2) { | |
var helpBackground = new Path.Rectangle( | |
new Rectangle(margin, 2 * sH + margin, | |
sW * 4 - 2 * margin, sH * 2 - 2 * margin), | |
2 * margin); | |
helpBackground.fillColor = lightCell; | |
helpEl = new Group([helpBackground].concat([ | |
'You can use the keyboard, the mouse or touch to control', | |
'To change keyboard mappings hold ctrl then press a button', | |
'(I expect there is a ctrl in your keyboard)','', | |
'Future improvements:', | |
' - A better interface', | |
' - Animations, again', | |
' - Customizable samples', | |
' - Web MIDI input (maybe)','', | |
'Click here to visit reddit post' | |
].map(function (text, n) { | |
return new PointText({ | |
point: [margin * 8, 2 * sH + margin * 8 + n * 20], | |
content: text, | |
fillColor: 'black', | |
fontFamily: 'Courier New', | |
fontWeight: 'bold', | |
fontSize: 18 | |
}); | |
}))); | |
} else if (mode === 2) { | |
helpEl.remove(); | |
} | |
} | |
mode = jD; | |
} else if (punks[punNum]) { | |
box.fillColor = selectedCell; | |
ion.sound.play(punks[punNum].name); | |
setTimeout(function () { | |
box.fillColor = lightCell; | |
}, 250); | |
} | |
} | |
// Reposition the path whenever the window is resized: | |
function onResize() { | |
initializePath(); | |
} | |
function onFrame(evt) { | |
if (customizingState.selectedCell) { | |
customizingState.selectedCell.fillColor = Math.floor(evt.count / 30) % 2 ? | |
selectedMode: playCell; | |
} | |
} | |
function playBackBacking() { | |
if (isPlaying) { | |
isPlaying = false; | |
ion.sound.pause(punks[0].name); | |
playElement.segments = playSegments; | |
} else { | |
isPlaying = true; | |
ion.sound.play(punks[0].name); | |
playElement.segments = pauseSegments; | |
} | |
playElement.position = new Point(width - sW / 2, height - sH / 2); | |
} | |
setTimeout(playBackBacking, 1000); | |
var punks = ['beat', | |
'WorkIt1', 'MakeIt1', 'DoIt1', 'MakesUs1', 'Harder1', 'Better1', 'Faster1', 'Stronger1', | |
'MoreThan1', 'Hour1', 'Our1', 'Never1', 'Ever1', 'After1', 'WorkIs1', 'Over1', | |
'WorkIt2', 'MakeIt2', 'DoIt2', 'MakesUs2', 'Harder2', 'Better2', 'Faster2', 'Stronger2', | |
'MoreThan2', 'Hour2', 'Our2', 'Never2', 'Ever2', 'After2', 'WorkIs2', 'Over2', | |
'MoreThan3', 'Hour3', 'Our3', 'Never3', 'Ever3', 'After3', 'WorkIs3', 'Over3' | |
].map(function (punk) { | |
return {name: punk}; | |
}); | |
ion.sound({ | |
sounds: punks, | |
volume: 0.5, | |
// Seen that it doesn't support HTTPS | |
path: "http://s.cdpn.io/190177/", | |
preload: true | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment