WIP proper help and options panel

Keypresses not working. TweeningFns inputs are not synced.
This commit is contained in:
Tyler Hallada 2017-08-12 18:50:51 -04:00
parent ce38957abe
commit e97a4ee3ec
3 changed files with 378 additions and 233 deletions

View File

@ -4,19 +4,52 @@
} }
html { html {
overflow: hidden; background-color: #1e1e1e;
} }
#help { button {
display: flex; background-color: #2e2e2e;
justify-content: center; border-color: #4a4a4a;
background-color: black; color: #fafafa;
padding: 2px;
}
td, th {
padding: 2px 5px;
}
input {
color: white;
background-color: #2e2e2e;
border-color: #4a4a4a;
}
input[type=number] {
padding: 3px;
}
div.panel {
background-color: rgba(0, 0, 0, 0.6);
border: 2px solid #1e1e1e;
color: white; color: white;
position: absolute; position: absolute;
top: 0; top: 26px;
left: 0; left: 0;
z-index: 11;
padding: 5px;
}
#help h2 {
text-align: center;
} }
#help table { #help table {
color: white; color: white;
} }
#options {
position: fixed;
top: 0;
left: 0;
z-index: 10;
}

View File

@ -1,114 +1,134 @@
<html lang="en"> <html lang="en">
<head> <head>
<title>Proximity Structures</title> <title>Proximity Structures</title>
<link rel="stylesheet" href="css/style.css"> <link rel="stylesheet" href="css/style.css">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- open graph tags --> <!-- open graph tags -->
<meta property="og:title" content="Proximity Structures" /> <meta property="og:title" content="Proximity Structures" />
<meta property="og:url" content="http://proximity.hallada.net/" /> <meta property="og:url" content="http://proximity.hallada.net/" />
<meta property="og:image" content="http://proximity.hallada.net/img/proximity-300-zoomed.png" /> <meta property="og:image" content="http://proximity.hallada.net/img/proximity-300-zoomed.png" />
<meta property="og:image:type" content="image/png" /> <meta property="og:image:type" content="image/png" />
<meta property="og:image:width" content="300" /> <meta property="og:image:width" content="300" />
<meta property="og:image:height" content="300" /> <meta property="og:image:height" content="300" />
<meta property="og:image:alt" content="Screenshot of the animation in action" /> <meta property="og:image:alt" content="Screenshot of the animation in action" />
<meta property="og:description" content="A procedurally generated and interactive animation created with PixiJS" /> <meta property="og:description" content="A procedurally generated and interactive animation created with PixiJS" />
</head> </head>
<body> <body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.2.2/pixi.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.2.2/pixi.min.js"></script>
<script src="js/proximity.js"></script> <script src="js/proximity.js"></script>
<div id="help" style="display: none;"> <div id="options">
<h2>Help</h2> <button id="toggle-help">Help</button>
<table> <button id="toggle-controls">Controls</button>
<tr> </div>
<th>Interaction</th> <div id="help" class="panel" style="display: none;">
<th>Action</th> <h2>Help</h2>
</tr> <table>
<tr> <tr>
<td>mouse hover</td> <th>Interaction</th>
<td>push points away from cursor</td> <th>Action</th>
</tr> </tr>
<tr> <tr>
<td>mouse/touch click and hold</td> <td>mouse hover</td>
<td>attract points to cursor, then explode outwards</td> <td>push points away from cursor</td>
</tr> </tr>
<tr> <tr>
<td>mouse wheel scroll down</td> <td>mouse/touch click and hold</td>
<td>slow down time</td> <td>attract points to cursor, then explode outwards</td>
</tr> </tr>
<tr> <tr>
<td>mouse wheel scroll up</td> <td>mouse wheel scroll down</td>
<td>speed up time</td> <td>slow down time</td>
</tr> </tr>
<tr> <tr>
<td>left</td> <td>mouse wheel scroll up</td>
<td>hold to restrict points to the left of the screen</td> <td>speed up time</td>
</tr> </tr>
<tr> <tr>
<td>right</td> <td><code>&larr;</code> (left)</td>
<td>hold to restrict points to the right of the screen</td> <td>hold to restrict points to the left of the screen</td>
</tr> </tr>
<tr> <tr>
<td>up</td> <td><code>&rarr;</code> (right)</td>
<td>hold to restrict points to the top of the screen</td> <td>hold to restrict points to the right of the screen</td>
</tr> </tr>
<tr> <tr>
<td>down</td> <td><code>&uarr;</code> (up)</td>
<td>hold to restrict points to the bottom of the screen</td> <td>hold to restrict points to the top of the screen</td>
</tr> </tr>
<tr> <tr>
<td>1</td> <td><code>&darr;</code> (down)</td>
<td>makes points move linearly</td> <td>hold to restrict points to the bottom of the screen</td>
</tr> </tr>
<tr> <tr>
<td>2</td> <td><code>1</code></td>
<td>makes points meander</td> <td>makes points move linearly</td>
</tr> </tr>
<tr> <tr>
<td>3</td> <td><code>2</code></td>
<td>makes points snappy</td> <td>makes points meander</td>
</tr> </tr>
<tr> <tr>
<td>4</td> <td><code>3</code></td>
<td>makes points bouncy</td> <td>makes points snappy</td>
</tr> </tr>
<tr> <tr>
<td>5</td> <td><code>4</code></td>
<td>makes points elastic</td> <td>makes points bouncy</td>
</tr> </tr>
<tr> <tr>
<td>6</td> <td><code>5</code></td>
<td>makes points overshoot</td> <td>makes points elastic</td>
</tr> </tr>
<tr> <tr>
<td>f</td> <td><code>6</code></td>
<td>toggle FPS counter</td> <td>makes points overshoot</td>
</tr> </tr>
<tr> <tr>
<td>d</td> <td><code>f</code></td>
<td>toggles debug mode (including FPS counter)</td> <td>toggle FPS counter</td>
</tr> </tr>
<tr> <tr>
<td>n</td> <td><code>d</code></td>
<td>toggles display of nodes</td> <td>toggles debug mode (including FPS counter)</td>
</tr> </tr>
<tr> <tr>
<td>l</td> <td><code>n</code></td>
<td>toggles display of lines</td> <td>toggles display of nodes</td>
</tr> </tr>
<tr> <tr>
<td>?</td> <td><code>l</code></td>
<td>toggles this help modal</td> <td>toggles display of lines</td>
</tr> </tr>
</table> <tr>
</div> <td><code>?</code></td>
</body> <td>toggles this help modal</td>
</tr>
</table>
</div>
<div id="controls" class="panel" style="display: none;">
<form action="">
<label>Time:
<input type="range" name="timeRange" min="1" max="360" value="0" oninput="this.form.timeInput.value=this.value" />
<input type="number" name="timeInput" min="1" max="360" value="0" oninput="this.form.timeRange.value=this.value" />
</label><br />
<label>Point tweening:
<label><input type="radio" name="tweening" value="linear" /> Linear</label>
<label><input type="radio" name="tweening" value="meandering" checked /> Meandering</label>
<label><input type="radio" name="tweening" value="snappy" /> Snappy</label>
<label><input type="radio" name="tweening" value="bouncy" /> Bouncy</label>
<label><input type="radio" name="tweening" value="elastic" /> Elastic</label>
<label><input type="radio" name="tweening" value="back" /> Overshoot</label>
</label>
</form>
</div>
</body>
<!-- Google Analytics --> <!-- Google Analytics -->
<script> <script>
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date; window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
ga('create', 'UA-39880341-1', 'auto'); ga('create', 'UA-39880341-1', 'auto');
ga('send', 'pageview'); ga('send', 'pageview');
</script> </script>
<script async src='https://www.google-analytics.com/analytics.js'></script> <script async src='https://www.google-analytics.com/analytics.js'></script>
<!-- End Google Analytics --> <!-- End Google Analytics -->
</html> </html>

View File

@ -248,6 +248,38 @@ function easeInOutCirc (t, b, c, d) {
/* UTILITY FUNCTIONS */ /* UTILITY FUNCTIONS */
function toggleHelp () {
var help, controls;
help = document.getElementById('help');
controls = document.getElementById('controls');
if (help.style.display === 'none') {
help.style.display = 'block';
// hide controls if open (only want one panel open at a time)
if (controls.style.display === 'block') {
controls.style.display = 'none';
}
} else {
help.style.display = 'none';
}
}
function toggleControls () {
var help, controls;
help = document.getElementById('help');
controls = document.getElementById('controls');
if (controls.style.display === 'none') {
controls.style.display = 'block';
// hide help if open (only want one panel open at a time)
if (help.style.display === 'block') {
help.style.display = 'none';
}
} else {
controls.style.display = 'none';
}
}
function randomInt (min, max) { function randomInt (min, max) {
// inclusive of min and max // inclusive of min and max
return Math.floor(Math.random() * (max - min + 1)) + min; return Math.floor(Math.random() * (max - min + 1)) + min;
@ -644,6 +676,12 @@ function loop () {
} }
scrollDelta = 0; scrollDelta = 0;
polygonPoints = redistributeCycles(polygonPoints, oldCycleDuration, cycleDuration); polygonPoints = redistributeCycles(polygonPoints, oldCycleDuration, cycleDuration);
// Update control inputs
var timeRange = document.getElementsByName('timeRange')[0];
var timeInput = document.getElementsByName('timeInput')[0];
timeRange.value = cycleDuration;
timeInput.value = cycleDuration;
} }
// Tell the `renderer` to `render` the `stage` // Tell the `renderer` to `render` the `stage`
@ -694,6 +732,10 @@ function loopStart () {
scrollDelta = 0; scrollDelta = 0;
// Try to fix bug where click initializes to a bogus value
click = null;
hover = null;
window.requestAnimationFrame(loop); window.requestAnimationFrame(loop);
} }
@ -702,132 +744,182 @@ window.PIXI.loader
.add(nodeImg) .add(nodeImg)
.load(loopStart); .load(loopStart);
/* MOUSE AND TOUCH EVENTS */ window.onload = function () {
var tweeningInputs;
tweeningInputs = document.getElementsByName('tweening');
/* MOUSE AND TOUCH EVENTS */
window.addEventListener('mousewheel', function (e) { window.addEventListener('mousewheel', function (e) {
scrollDelta = scrollDelta + ((e.deltaY / 100) * 3); if (e.target.tagName !== 'CANVAS') return;
}); scrollDelta = scrollDelta + ((e.deltaY / 100) * 3);
});
window.addEventListener('touchstart', function (e) { window.addEventListener('touchstart', function (e) {
click = getMousePos(e.changedTouches[0], resolution); if (e.target.tagName !== 'CANVAS') return;
clickEnd = false;
});
window.addEventListener('touchmove', function (e) {
if (click !== null) {
click = getMousePos(e.changedTouches[0], resolution); click = getMousePos(e.changedTouches[0], resolution);
} clickEnd = false;
}); });
window.addEventListener('touchend', function (e) { window.addEventListener('touchmove', function (e) {
clickEnd = true; if (e.target.tagName !== 'CANVAS') return;
}); if (click !== null) {
click = getMousePos(e.changedTouches[0], resolution);
window.addEventListener('touchcancel', function (e) {
clickEnd = true;
});
window.addEventListener('mousedown', function (e) {
click = getMousePos(e, resolution);
clickEnd = false;
});
window.addEventListener('mousemove', function (e) {
var pos = getMousePos(e, resolution);
if (click !== null) {
click = pos;
}
hover = pos;
});
window.addEventListener('mouseup', function (e) {
clickEnd = true;
hover = null;
lastHover = null;
});
window.addEventListener('mouseleave', function (e) {
clickEnd = true;
hover = null;
lastHover = null;
});
document.addEventListener('mouseleave', function (e) {
clickEnd = true;
hover = null;
lastHover = null;
});
/* KEYBOARD EVENTS */
window.addEventListener('keydown', function (e) {
var i, help;
if (e.keyCode === 37) { // left
pointShiftBiasX = -1;
} else if (e.keyCode === 38) { // up
pointShiftBiasY = -1;
} else if (e.keyCode === 39) { // right
pointShiftBiasX = 1;
} else if (e.keyCode === 40) { // down
pointShiftBiasY = 1;
} else if (e.keyCode === 49) { // 1
tweeningFns = tweeningSets.linear;
} else if (e.keyCode === 50) { // 2
tweeningFns = tweeningSets.meandering;
} else if (e.keyCode === 51) { // 3
tweeningFns = tweeningSets.snappy;
} else if (e.keyCode === 52) { // 4
tweeningFns = tweeningSets.bouncy;
} else if (e.keyCode === 53) { // 5
tweeningFns = tweeningSets.elastic;
} else if (e.keyCode === 54) { // 6
tweeningFns = tweeningSets.back;
} else if (e.keyCode === 70) { // f
// toggle fpsCounter
if (fpsEnabled) {
stage.removeChild(fpsGraphic);
fpsEnabled = false;
} else {
stage.addChild(fpsGraphic);
fpsEnabled = true;
lastLoop = new Date();
} }
} else if (e.keyCode === 68) { // d });
// toggle debug
if (debug) { window.addEventListener('touchend', function (e) {
if (e.target.tagName !== 'CANVAS') return;
clickEnd = true;
});
window.addEventListener('touchcancel', function (e) {
if (e.target.tagName !== 'CANVAS') return;
clickEnd = true;
});
window.addEventListener('mousedown', function (e) {
if (e.target.tagName !== 'CANVAS') return;
click = getMousePos(e, resolution);
clickEnd = false;
});
window.addEventListener('mousemove', function (e) {
if (e.target.tagName !== 'CANVAS') return;
var pos = getMousePos(e, resolution);
if (click !== null) {
click = pos;
}
hover = pos;
});
window.addEventListener('mouseup', function (e) {
if (e.target.tagName !== 'CANVAS') return;
clickEnd = true;
hover = null;
lastHover = null;
});
window.addEventListener('mouseleave', function (e) {
if (e.target.tagName !== 'CANVAS') return;
clickEnd = true;
hover = null;
lastHover = null;
});
document.addEventListener('mouseleave', function (e) {
if (e.target.tagName !== 'CANVAS') return;
clickEnd = true;
hover = null;
lastHover = null;
});
/* KEYBOARD EVENTS */
window.addEventListener('keydown', function (e) {
var i;
if (e.target.tagName !== 'CANVAS' || e.target.tagName !== 'BODY') return;
if (e.keyCode === 37) { // left
pointShiftBiasX = -1;
} else if (e.keyCode === 38) { // up
pointShiftBiasY = -1;
} else if (e.keyCode === 39) { // right
pointShiftBiasX = 1;
} else if (e.keyCode === 40) { // down
pointShiftBiasY = 1;
} else if (e.keyCode === 49) { // 1
tweeningFns = tweeningSets.linear;
tweeningInputs[0].checked = true;
} else if (e.keyCode === 50) { // 2
tweeningFns = tweeningSets.meandering;
tweeningInputs[1].checked = true;
} else if (e.keyCode === 51) { // 3
tweeningFns = tweeningSets.snappy;
tweeningInputs[2].checked = true;
} else if (e.keyCode === 52) { // 4
tweeningFns = tweeningSets.bouncy;
tweeningInputs[3].checked = true;
} else if (e.keyCode === 53) { // 5
tweeningFns = tweeningSets.elastic;
tweeningInputs[4].checked = true;
} else if (e.keyCode === 54) { // 6
tweeningFns = tweeningSets.back;
tweeningInputs[5].checked = true;
} else if (e.keyCode === 70) { // f
// toggle fpsCounter
if (fpsEnabled) { if (fpsEnabled) {
stage.removeChild(fpsGraphic); stage.removeChild(fpsGraphic);
} fpsEnabled = false;
debug = false; } else {
fpsEnabled = debug;
} else {
if (!fpsEnabled) {
stage.addChild(fpsGraphic); stage.addChild(fpsGraphic);
fpsEnabled = true;
lastLoop = new Date();
} }
debug = true; } else if (e.keyCode === 68) { // d
fpsEnabled = debug; // toggle debug
lastLoop = new Date(); if (debug) {
} if (fpsEnabled) {
} else if (e.keyCode === 78) { // n stage.removeChild(fpsGraphic);
if (drawNodes) { }
for (i = 0; i < sprites.length; i++) { debug = false;
sprites[i].visible = false; fpsEnabled = debug;
} else {
if (!fpsEnabled) {
stage.addChild(fpsGraphic);
}
debug = true;
fpsEnabled = debug;
lastLoop = new Date();
} }
drawNodes = false; } else if (e.keyCode === 78) { // n
} else { if (drawNodes) {
for (i = 0; i < sprites.length; i++) { for (i = 0; i < sprites.length; i++) {
sprites[i].visible = true; sprites[i].visible = false;
}
drawNodes = false;
} else {
for (i = 0; i < sprites.length; i++) {
sprites[i].visible = true;
}
drawNodes = true;
} }
drawNodes = true; } else if (e.keyCode === 76) { // l
} drawLines = !drawLines;
} else if (e.keyCode === 76) { // l } else if (e.keyCode === 191) { // ?
drawLines = !drawLines; toggleHelp();
} else if (e.keyCode === 191) { // ?
help = document.getElementById('help');
if (help.style.display === 'none') {
help.style.display = 'flex';
} else {
help.style.display = 'none';
} }
});
/* BUTTON EVENTS */
document.getElementById('toggle-help').addEventListener('click', function () {
toggleHelp();
}, false);
document.getElementById('toggle-controls').addEventListener('click', function () {
toggleControls();
}, false);
var timeRange, timeInput;
timeRange = document.getElementsByName('timeRange')[0];
timeRange.value = cycleDuration;
timeRange.addEventListener('input', function (e) {
var oldCycleDuration = cycleDuration;
cycleDuration = parseInt(this.value, 10);
polygonPoints = redistributeCycles(polygonPoints, oldCycleDuration, cycleDuration);
});
timeInput = document.getElementsByName('timeInput')[0];
timeInput.value = cycleDuration;
timeInput.addEventListener('input', function (e) {
var oldCycleDuration = cycleDuration;
cycleDuration = parseInt(this.value, 10);
polygonPoints = redistributeCycles(polygonPoints, oldCycleDuration, cycleDuration);
});
var i;
for (i = 0; i < tweeningInputs.length; i++) {
tweeningInputs[i].addEventListener('change', function (e) {
tweeningFns = tweeningSets[this.value];
});
} }
}); };