Resolves #19. Resolves #18. Resolves #17.

Creates an "advanced" screen with UI for explicitly declaring the number of loops.
This commit is contained in:
mmcwilliams 2020-05-19 18:40:19 -04:00
parent 7d779bc5c9
commit 05af031cba
7 changed files with 351 additions and 21 deletions

View File

@ -88,6 +88,7 @@
<button id="restart" onclick="restart();">RESTART</button>
<button id="update" onclick="update();">UPDATE</button>
</div>
<div id="version">v1.0.7 build cfb0a7be</div>
</div>
<!--<div id="mscript" class="page">
<h2>MSCRIPT</h2>
@ -107,7 +108,7 @@
<input type="number" class="fstop" placeholder="5.6" value="5.6" onchange="mobile.refreshExposure();" />
</div>
<div class="setting">
<div class="label">Rex-o-fader</div>
<div class="label">Variable Shutter</div>
<select class="angle">
<option value="133" selected>0 (Normal)</option>
<option value="66">1 Stop</option>
@ -157,6 +158,28 @@
</div>
</div>
</div>
<div id="advanced" class="page">
<h2>ADVANCED</h2>
<div>
<div class="label">Loops</div>
<input type="number" id="len" value="1" step="1" min="1" />
</div>
<div>
<div class="label">Frame Multiplier</div>
<input type="number" id="multiple" value="1" step="1" min="1" />
</div>
<div>
<div id="stats">
<div><label>Real time</label> <span id="realTime">0 s</span></div>
<div><label>Film time</label> <span id="filmTime">0 s</span></div>
<div><label>Frame end</label> <span id="frameEnd">0</span></div>
</div>
</div>
<div>
<button id="run" onclick="advanced();">RUN</button>
</div>
<div id="progress"></div>
</div>
<footer>
<div id="settingsIcon" onclick="settingsPage();" class="icon">
<div> </div>
@ -164,9 +187,9 @@
<div id="appIcon" onclick="appPage();" class="icon selected">
<div></div>
</div>
<!--<div id="mscriptIcon" onclick="mscriptPage();" class="icon">
<div id="advancedIcon" onclick="advancedPage();" class="icon">
<div></div>
</div>-->
</div>
<div id="cameraIcon" onclick="cameraPage();" class="icon">
<div class="cameraIcon"></div>
</div>

View File

@ -237,6 +237,11 @@ button.focus{
.cameraIcon{
background: url(data:image/svg+xml;utf8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTguMS4xLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDEwMCAxMDAiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDEwMCAxMDA7IiB4bWw6c3BhY2U9InByZXNlcnZlIiB3aWR0aD0iMzJweCIgaGVpZ2h0PSIzMnB4Ij4KPGc+Cgk8Zz4KCQk8cGF0aCBkPSJNNTAsNDBjLTguMjg1LDAtMTUsNi43MTgtMTUsMTVjMCw4LjI4NSw2LjcxNSwxNSwxNSwxNWM4LjI4MywwLDE1LTYuNzE1LDE1LTE1ICAgIEM2NSw0Ni43MTgsNTguMjgzLDQwLDUwLDQweiBNOTAsMjVINzhjLTEuNjUsMC0zLjQyOC0xLjI4LTMuOTQ5LTIuODQ2bC0zLjEwMi05LjMwOUM3MC40MjYsMTEuMjgsNjguNjUsMTAsNjcsMTBIMzMgICAgYy0xLjY1LDAtMy40MjgsMS4yOC0zLjk0OSwyLjg0NmwtMy4xMDIsOS4zMDlDMjUuNDI2LDIzLjcyLDIzLjY1LDI1LDIyLDI1SDEwQzQuNSwyNSwwLDI5LjUsMCwzNXY0NWMwLDUuNSw0LjUsMTAsMTAsMTBoODAgICAgYzUuNSwwLDEwLTQuNSwxMC0xMFYzNUMxMDAsMjkuNSw5NS41LDI1LDkwLDI1eiBNNTAsODBjLTEzLjgwNywwLTI1LTExLjE5My0yNS0yNWMwLTEzLjgwNiwxMS4xOTMtMjUsMjUtMjUgICAgYzEzLjgwNSwwLDI1LDExLjE5NCwyNSwyNUM3NSw2OC44MDcsNjMuODA1LDgwLDUwLDgweiBNODYuNSw0MS45OTNjLTEuOTMyLDAtMy41LTEuNTY2LTMuNS0zLjVjMC0xLjkzMiwxLjU2OC0zLjUsMy41LTMuNSAgICBjMS45MzQsMCwzLjUsMS41NjgsMy41LDMuNUM5MCw0MC40MjcsODguNDMzLDQxLjk5Myw4Ni41LDQxLjk5M3oiIGZpbGw9IiNGRkZGRkYiLz4KCTwvZz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8L3N2Zz4K) no-repeat;
}
#advancedIcon > div {
filter: invert(1);
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAABmJLR0QA/wD/AP+gvaeTAAAD3UlEQVRoge3Zz28VVRQH8E9LWzRRo9S6wJqYKBASXWgtAmowGv8CDabBjSGGhf8G/sBl8ddSA7oxblAkoDExxhj8sRETjRgMaJUqrkRqacNzce84j/Y93rtzZ6pEvsnkvndnzvecM/fcH+cMV/D/wQj24GfM4LnYd9nhebSWXM/+qxZVxIxg/BZsjb9nmlI21BSxMozOtvUNN6VsVVPEuBWTuB4P4E68jvca1NkIxjGHC/Gai32NoM7QGsS92IZNuE0Y8YF4fxUO4nt8ho9wVJg7/wmMCyvUT5avUr2uH4Vl+eYVt7oNY3gR55WGHY99U7gLa4QJPozR2DeFl4SRKeTOYxo3rqgH2I4z0YgF7MPmCjxbsD9ytPAbHqvJxktiGC8r3+RB3F4D73ocauPdq8Gt4ao2ZX/iyT7ljuLTPp/dGblbeBerE23siSFh/W/htBDr/aJ4y/1iArNKZ2odmVeUTqxPlE11RNRROLM3UbYrHleGU8pIFKjiCGFkzkXZRyvIX4Qx/B7J+p0TS1HVEXhKuZqNVuRAGVI556McR+BwlJ+uSnCLsFEtyFticx3ZgEXMY20VgiIx2pdhBPmOwBsqJmaDyrNTlR27HXU4UiRmpwTbkgWPZxpAPY4M4ETk2dTpgW7ebYvt4UwD6kILR+LvBzs90M2Rydh+UrNBOfg4tkkjsi6232QoHsHutv8vyMvZC1vWXfKpJSg2wZxNaLflidSeDL6xyHEmRWg+CuUU1E5Z7sgvGXyrI8d8p5tJS1kiOnEPdOhLRccVsJsjRS3q2orKxoTdeCleq8gH18X2jxShrwXPq5x2b8KxKH9SKDCcFuZHzmSfiJxfpQi9HYWmEpW1O3Es/q8LT0Tetzrd7BZaX8b2/gRFY/gAd+BbPIJfE+R7obDlixShzcojSj8TtMmREG34IfJP9nj2IgwKsV1U03vhc805Afcp51zHKOoWWheEehM83YeiRSEcH1ZvOBUobNgv2JaEcWHzWZBecKgTG4UXNadiYkVZjDtUk1FV8L7MVJdw1ipKoztrMCoVu6LuWdyQS9ZeDprIJUvApBBOLTXWg4sQm7Uy82WDsGhkh9RSDOEdpTNNjsyk0okDGihmX6105pxQPKsbu5ThdCDqbARDwkeaIr84IoRBLjYqV6cinJr84vwPtiuHf1GoO22Vlm8MCDv2m5GjCNsV+dDTjjVCpfwv5Zs8IZRZd+BuYfkeideoMLd24FXl2aklhNO0GpbYHKzFMzqntr2uk0JuX3nHLlBH6llgEPfgIeHNbxC+1l4T758VqpffCUfxD4XzWfLZ6QouB/wNDUkks50hozcAAAAASUVORK5CYII=) no-repeat;
background-size: 33px 33px;
}
button i {
display: block;
@ -255,8 +260,8 @@ footer{
}
footer .icon {
/*width: 33.33%;*/
width: 50%;
width: 33.33%;
/*width: 50%;*/
height: 50px;
float: left;
box-sizing: border-box;
@ -264,8 +269,8 @@ footer .icon {
}
body.mobile footer .icon{
/*width: 25%;*/
width: 33.33%;
width: 25%;
/*width: 33.33%;*/
}
footer .icon:last-child{
@ -441,3 +446,24 @@ body.mobile footer{
text-shadow: 1px 1px 0px #999;
font-size: 24px;
}
#version{
bottom: 70px;
position: absolute;
color: #666;
}
#stats{
margin: 10px 0;
font-size: 18px;
}
#stats label {
color: #666;
width: 100px;
display: inline-block;
}
#stats span{
color: #fff;
}

View File

@ -13,7 +13,8 @@ const STATE = {
scale : 'ms',
delayScale : 'ms',
counter : 0,
sequence : false
sequence : false,
advanced : 0
};
//functions
@ -27,6 +28,7 @@ window.sequence = null;
window.reset = null;
window.restart = null;
window.update = null;
window.advanced = null;
//ms
var shutter = function (exposure) {
@ -183,6 +185,8 @@ var setState = function (res) {
document.getElementById('delayScale').value = delayScale;
setDelayScale();
calcStats();
if (res.sequence == true) {
if (mobile.ble) mobile.ble.active = true;
if (pwa.wble) pwa.wble.active = true;
@ -195,18 +199,28 @@ var setState = function (res) {
};
var seqState = function (state) {
const elem = document.getElementById('seq')
const elem = document.getElementById('seq');
const advancedElem = document.getElementById('run');
if (state) {
if (!elem.classList.contains('focus')) {
elem.classList.add('focus');
}
if (!advancedElem.classList.contains('focus')) {
advancedElem.classList.add('focus');
}
elem.innerHTML = 'STOP SEQUENCE';
advancedElem.innerHTML = 'STOP';
STATE.sequence = true;
} else {
if (elem.classList.contains('focus')) {
elem.classList.remove('focus');
}
if (advancedElem.classList.contains('focus')) {
advancedElem.classList.remove('focus');
}
elem.innerHTML = 'START SEQUENCE';
advancedElem.innerHTML = 'RUN';
STATE.sequence = false;
}
};
@ -232,11 +246,87 @@ var cameraPage = function () {
document.getElementById('camera').classList.add('selected');
document.getElementById('cameraIcon').classList.add('selected');
};
var advancedPage = function () {
unsetPages();
document.getElementById('advanced').classList.add('selected');
document.getElementById('advancedIcon').classList.add('selected');
};
var isNumeric = function (n) {
return !isNaN(parseFloat(n)) && isFinite(n);
};
var calcStats = function () {
const extraFwd = BOLEX.expected;
const extraBwd = BOLEX.expected + 150;
const total = parseInt(document.getElementById('len').value);
const multiple = parseInt(document.getElementById('multiple').value);
const filmTime = (total * multiple) / 24;
const delays = total - 1;
const frameEnd = STATE.counter + (STATE.dir ? total * multiple : -total * multiple);
let exp;
let realTime;
let realTimePartial;
let realTimeDisplay;
let filmTimeDisplay;
if (STATE.exposure > BOLEX.expected) {
exp = STATE.exposure + (STATE.dir ? extraFwd : extraBwd);
} else {
exp = BOLEX.expected;
}
realTime = (exp * total * multiple) + (delays * STATE.delay);
STATE.advanced = realTime;
if (realTime < 60 * 1000) { //1min
realTimeDisplay = Math.floor(realTime * 100) / 100000;
realTimeDisplay += ' sec';
} else if (realTime >= 60 * 1000 && realTime < 60 * 60 * 1000) { //1hr
realTimePartial = Math.floor(realTime * 100) / (60 * 100000);
realTimeDisplay = Math.floor(realTimePartial);
realTimeDisplay += ' min';
if (realTimePartial > Math.floor(realTimePartial)) {
realTimeDisplay += ' ' + Math.round((realTimePartial - Math.floor(realTimePartial) ) * 60);
realTimeDisplay += ' sec'
}
} else if (realTime >= 60 * 60 * 1000 && realTime < 24 * 60 * 60 * 1000) { //1day
realTimePartial = Math.floor(realTime * 100) / (60 * 60 * 100000);
realTimeDisplay = Math.floor(realTimePartial);
realTimeDisplay += ' hr';
if (realTimePartial > Math.floor(realTimePartial)) {
realTimeDisplay += ' ' + Math.round((realTimePartial - Math.floor(realTimePartial) ) * 60);
realTimeDisplay += ' min'
}
} else if (realTime >= 24 * 60 * 60 * 1000 && realTime < 24 * 60 * 60 * 1000) { //1day
realTimePartial = Math.floor(realTime * 100) / (60 * 60 * 100000);
realTimeDisplay = Math.floor(realTimePartial);
realTimeDisplay += ' day';
if (realTimePartial > Math.floor(realTimePartial)) {
realTimeDisplay += ' ' + Math.round((realTimePartial - Math.floor(realTimePartial) ) * 24);
realTimeDisplay += ' hr'
}
}
if (filmTime < 60 * 1000) { //1min
filmTimeDisplay = Math.floor(filmTime * 100) / 100;
filmTimeDisplay += ' sec';
} else if (filmTime >= 60 * 1000) {
filmTimePartial = Math.floor(filmTime * 100) / (60 * 100000);
filmTimeDisplay = Math.floor(filmTimePartial);
filmTimeDisplay += ' min';
if (filmTimePartial > Math.floor(filmTimePartial)) {
filmTimeDisplay += ' ' + Math.round((filmTimePartial - Math.floor(filmTimePartial) ) * 60);
filmTimeDisplay += ' sec'
}
}
document.getElementById('realTime').innerHTML = realTimeDisplay;
document.getElementById('filmTime').innerHTML = filmTimeDisplay;
document.getElementById('frameEnd').innerHTML = frameEnd;
};
var UI = {};
UI.overlay = {
@ -319,4 +409,6 @@ var init = function () {
document.querySelector('.fstop').oninput = function () {
BOLEX.fstop = parseFloat(this.value);
};
document.getElementById('len').oninput = calcStats;
document.getElementById('multiple').oninput = calcStats;
};

View File

@ -151,6 +151,7 @@ mobile.init = function () {
window.getWifi = mobile.getWifi;
window.setWifi = mobile.setWifi;
window.editWifi = mobile.editWifi;
window.advanced = mobile.advanced;
//show ble-specific fields in settings
for (let i of bleInputs) {
@ -173,6 +174,7 @@ mobile.getState = function () {
mobile.stateSuccess,
mobile.ble.onError);
};
mobile.stateSuccess = function (data) {
let str = bytesToString(data);
let res = JSON.parse(str);
@ -205,13 +207,13 @@ mobile.frameSuccess = function () {
console.log('Frame finished, getting state.');
mobile.ble.active = false;
document.getElementById('frame').classList.remove('focus');
mobile.getState();
getState();
} else {
setTimeout(() => {
console.log('Frame finished, getting state.');
mobile.ble.active = false;
document.getElementById('frame').classList.remove('focus');
mobile.getState();
getState();
}, STATE.exposure + 500)
}
}
@ -230,7 +232,7 @@ mobile.setDir = function () {
};
mobile.dirSuccess = function () {
console.log('Set direction');
mobile.getState();
getState();
setTimeout(() => {
setDirLabel(STATE.dir);
}, 50);
@ -255,7 +257,7 @@ mobile.setExposure = function () {
};
mobile.exposureSuccess = function () {
console.log('Set exposure');
mobile.getState();
getState();
};
mobile.setDelay = function () {
@ -275,7 +277,7 @@ mobile.setDelay = function () {
mobile.delaySuccess = function () {
console.log('Set delay');
mobile.getState();
getState();
};
mobile.setCounter = function () {
@ -307,7 +309,7 @@ mobile.setCounter = function () {
mobile.counterSuccess = function () {
console.log('Set counter');
mobile.getState();
getState();
};
mobile.sequence = function () {
@ -334,18 +336,75 @@ mobile.sequence = function () {
mobile.sequenceSuccess = function () {
console.log('Sequence state changed');
mobile.getState();
getState();
setTimeout(() => {
if (STATE.sequence) {
mobile.ble.active = true;
seqState(true);
} else {
mobile.ble.active = false;
seqState(false);
}
}, 20);
}, 42);
};
mobile.advanced = function () {
const len = parseInt(document.getElementById('len').value);
const multiple = parseInt(document.getElementById('multiple').value);
const opts = {
type : 'sequence',
len,
multiple
};
if (!opts.len) {
return mobile.alert('You must set a total frame count.');
}
if (!opts.multiple) {
return mobile.alert('You must set a frame multiple value.');
}
const elem = document.getElementById('run');
if (!mobile.ble.connected) {
return mobile.alert('Not connected to an INTVAL3 device.');
}
ble.write(mobile.ble.device.id,
mobile.ble.SERVICE_ID,
mobile.ble.CHAR_ID,
stringToBytes(JSON.stringify(opts)), //check length?
mobile.advanceSuccess,
mobile.ble.onError);
if (!elem.classList.contains('focus')) {
elem.classList.add('focus');
}
mobile.ble.active = true;
};
mobile.advancedSuccess = function () {
console.log('Sequence state changed');
getState();
setTimeout(() => {
if (STATE.sequence) {
seqState(true);
} else {
seqState(false);
}
document.getElementById('seq').blur();
document.getElementById('run').blur();
}, 42);
setTimeout(() => {
console.log('Sequence complete');
getState();
setTimeout(() => {
if (STATE.sequence) {
seqState(true);
} else {
seqState(false);
}
}, 42);
}, STATE.advanced + 1000);
};
//retreive object with list of available Wifi APs,
//and state of current connection, if available
@ -471,6 +530,23 @@ mobile.setWifiSuccess = function () {
console.log('Set new wifi credentials');
setTimeout(mobile.getWifi, 100);
};
mobile.getInfo = function () {
const opts = {
type : 'info'
};
ble.write(mobile.ble.device.id,
mobile.ble.SERVICE_ID,
mobile.ble.CHAR_ID,
stringToBytes(JSON.stringify(opts)), //check length?
mobile.dirSuccess,
mobile.ble.onError);
};
mobile.infoSuccess = function () {
console.dir()
};
mobile.exif = {}
mobile.getCamera = function () {
@ -671,7 +747,7 @@ mobile.reset = function () {
mobile.resetSuccess = function () {
console.log('Reset to default settings');
setTimeout(() => {
mobile.getState();
getState();
}, 100)
};

View File

@ -263,6 +263,7 @@ pwa.init = function () {
window.getWifi = pwa.getWifi;
window.setWifi = pwa.setWifi;
window.editWifi = pwa.editWifi;
window.advanced = pwa.advanced;
//show ble-specific fields in settings
for (let i of bleInputs) {
@ -481,6 +482,67 @@ pwa.sequenceSuccess = function () {
};
pwa.advanced = async function () {
const len = parseInt(document.getElementById('len').value);
const multiple = parseInt(document.getElementById('multiple').value);
const opts = {
type : 'sequence',
len,
multiple
};
if (!opts.len) {
return pwa.alert('You must set a total frame count.');
}
if (!opts.multiple) {
return pwa.alert('You must set a frame multiple value.');
}
const elem = document.getElementById('run');
if (!pwa.wble.connected) {
return pwa.alert('Not connected to an INTVAL3 device.');
}
try {
await pwa.wble.write(pwa.wble.CHAR_ID, opts);
} catch (err) {
console.error(err);
pwa.wble.onError(err.message);
return false;
}
pwa.advancedSuccess();
if (!elem.classList.contains('focus')) {
elem.classList.add('focus');
}
pwa.wble.active = true;
};
pwa.advancedSuccess = function () {
console.log('Sequence state changed');
pwa.getState();
setTimeout(() => {
if (STATE.sequence) {
seqState(true);
} else {
seqState(false);
}
document.getElementById('seq').blur();
}, 42);
setTimeout(() => {
console.log('Sequence complete');
getState();
setTimeout(() => {
if (STATE.sequence) {
seqState(true);
} else {
seqState(false);
}
}, 42);
}, STATE.advanced + 1000);
};
//retreive object with list of available Wifi APs,
//and state of current connection, if available
pwa.getWifi = async function () {

View File

@ -160,6 +160,56 @@ web.sequenceSuccess = function (res) {
mobile.getState();
}
};
web.advanced = function () {
const len = parseInt(document.getElementById('len').value);
const multiple = parseInt(document.getElementById('multiple').value);
const params = {
len,
multiple
}
const opts = {
method : 'POST',
headers : web._header,
body : JSON.stringify(params)
}
if (!params.len) {
return alert('You must set a total frame count.');
}
if (!params.multiple) {
return alert('You must set a frame multiple value.');
}
fetch('/sequence', opts)
.then(web.useJson)
.then(web.advancedSuccess)
.catch(err => {
console.error('Error getting /sequence');
console.error(err);
})
};
web.advancedSuccess = function (res) {
if (res.started && res.started != false) {
STATE.sequence = true;
document.getElementById('seq').focus();
seqState(true);
} else if (res.stopped) {
STATE.sequence = false;
document.getElementById('seq').blur();
seqState(false);
getState();
}
setTimeout(() => {
console.log('Sequence complete');
getState();
setTimeout(() => {
if (STATE.sequence) {
seqState(true);
} else {
seqState(false);
}
}, 42);
}, STATE.advanced + 1000);
};
web.reset = function () {
const opts = {
method : 'POST',
@ -228,5 +278,6 @@ web.init = function () {
window.reset = web.reset;
window.restart = web.restart;
window.update = web.update;
window.advanced = web.advanced;
console.log('started web')
};