Skip to content

Instantly share code, notes, and snippets.

@scottgwald
Last active August 29, 2015 13:56
Show Gist options
  • Save scottgwald/8872296 to your computer and use it in GitHub Desktop.
Save scottgwald/8872296 to your computer and use it in GitHub Desktop.
[wearscript] periodically record a video
<!--
App with multiple modes that are driven by sensor callbacks
TODO: think about what to do in order to support drawing
triggered in different ways, such as animation
-->
<html style="width:100%; height:100%; overflow:hidden">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.0/zepto.min.js"></script>
<!--
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore-min.js">
</script>-->
</head>
<body style="width:100%; height:100%; overflow:hidden; margin:0">
<canvas id="wearCanvas" width="640" height="360" style="display:block"></canvas>
<script>
var WearENV = (function () {
var isActive = false, mode = 'colors';
var DBG = true; var log = false;
var modes = [];
var modePointer = 0;
var modeInit = false;
var errorLogged = false;
var modeHandlerMapping = {};
var serverConnected = false;
var welcomeHandlerName = 'welcome';
var envStarted = false;
// BEGIN GENERIC BOILERPLATE
function extend(a, b) {
for( var i in b ) {
a[i] = b[i];
}
}
function startEnv() {
var handler = modeHandlerMapping[welcomeHandlerName];
handler.config.start();
}
function startMode() {
var handler = modeHandlerMapping[modes[modePointer]];
handler.config.start();
}
function finishMode() {
var handler = modeHandlerMapping[modes[modePointer]];
handler.config.finish();
}
function nextMode() {
finishMode();
modePointer += 1;
modePointer %= modes.length;
startMode();
}
function prevMode() {
finishMode();
modePointer -= 1;
// %= operator doesn't move negatives into 0, modes.length-1
if (modePointer < 0) {
modePointer += modes.length;
}
startMode();
}
// TODO: switchMode(toModeName);
function cb(data) {
try {
var handler = modeHandlerMapping[modes[modePointer]];
handler.handle(data);
} catch(err) {
if (!errorLogged) {
WS.log("Invalid mode at index " + modePointer);
console.log(err);
errorLogged = true;
}
}
}
function onGesture(gesture) {
WS.log("WearENV.onGesture: " + gesture);
if (gesture === 'SWIPE_LEFT') {
prevMode();
} else if (gesture === 'SWIPE_RIGHT') {
nextMode();
} else if (gesture === 'TAP') {
WS.say("TAP");
} else if (gesture === 'TWO_TAP') {
togglePlaygroundSensorLog();
WS.log("Toggle remote sensor log, now " + log);
} else {
WS.say(gesture.replace('_', ' '));
}
}
function ModeHandler(name, options) {
this.config = {
name: name,
prettyName: name,
showMode: true,
drawCallback: function() {},
start: this.defaultStart,
finish: this.defaultFinish,
parentHandler: this
};
if (options !== undefined) {
extend(this.config, options);
}
console.log("Set prettyName to " + this.config.prettyName);
registerModeHandler(this);
}
ModeHandler.prototype.handle = function(data) {
this.config.drawCallback(data);
if (this.config.showMode) drawModeName(this.config.prettyName);
}
function registerModeHandler(modeHandler) {
WS.log("Registering mode " + modeHandler.config.name);
modes.push(modeHandler.config.name);
modeHandlerMapping[modeHandler.config.name] = modeHandler;
}
// DRAWING
function clearCanvas() {
context.fillStyle = "rgb(0, 0, 0)";
context.fillRect(0, 0, 640, 360);
}
function drawModeName(name) {
upperBase = 40;
context.fillStyle = "rgb(200,200,200)";
context.font = '28pt Calibri';
context.textAlign = 'left';
context.fillText(name, 10, upperBase);
}
// TODO: make title and subtitle ENV parameters
function drawTitlePage() {
var upperBase = 40;
var titleBase = 170;
var subtitleBase = 240;
context.fillStyle = '#000000';
context.fillRect(0, 0, 640, 360);
context.font = '64pt Calibri';
context.fillStyle = '#FFFFFF';
context.fillText('Sensor Explorer', 35, titleBase);
context.font = '28pt Calibri';
context.fillText('Swipe through to explore!', 175, subtitleBase);
}
function togglePlaygroundSensorLog() {
if (log) {
WS.say("Playground sensor log off");
WS.log("Turning off playground sensor logging.");
log = false;
WS.dataLog(false, log, .15);
} else {
WS.say("Playground sensor log on");
WS.log("Turning on playground sensor logging.");
log = true;
if (!serverConnected) {
WS.serverConnect('{{WSUrl}}', 'WearENV.server');
} else {
WS.dataLog(false, log, .15);
}
}
}
// I don't see a way to disconnect? Maybe call connect with null args?
function server() {
serverConnected = true;
WS.dataLog(false, log, .15);
}
// END GENERIC BOILERPLATE
// BEGIN APP STUFF INCLUDING OVERRIDES
function eyeMain() {
WS.cameraPhotoPath('WearENV.camCB');
canvas = document.getElementById('wearCanvas');
context = canvas.getContext('2d');
}
function eyeFinish() {
clearInterval(interval);
}
function camCB(path) {
WS.log(path);
var imageObj = new Image();
var k = 0;
var xsteps = 4;
var ysteps = 3;
var xstep = (2528 - 640) / (xsteps - 1);
var ystep = (1856 - 360) / (ysteps - 1);
var interval;
var startInterval = 3000;
var repeatInterval = 3000;
var points = [];
imageObj.onload = function() {
//2528 x 1856
clearInterval(interval);
context.drawImage(imageObj, 0, 0, 640, 360);
window.setTimeout(function () {
interval = window.setInterval(function () {
if (k) {
points.push([x, y, EYETRACKER_VALUE[0][0], EYETRACKER_VALUE[0][1]]);
}
if (k >= xsteps * ysteps) {
clearInterval(interval);
WS.sound('SUCCESS')
WS.log(JSON.stringify(points));
return;
}
WS.sound('TAP')
i = Math.floor(k / xsteps);
j = k % xsteps;
x = j * xstep + 320;
y = i * ystep + 240;
xScaled = x * screenWidth / imageWidth;
yScaled = y * screenHeight / imageHeight;
WS.log("x is: " + Math.floor(x) + ", and y is: " + Math.floor(y));
WS.say("x is " + Math.floor(x));
//context.drawImage(imageObj, -j * xstep, -i * ystep);
context.drawImage(imageObj, 0, 0, 640, 360);
context.beginPath();
context.arc(xScaled, yScaled, 15, 0, 2 * Math.PI, false);
//context.arc(320, 180, 30, 0, 2 * Math.PI, false);
context.fillStyle = 'green';
context.fill();
context.lineWidth = 5;
context.strokeStyle = '#003300';
context.stroke();
k += 1;
}, repeatInterval);
}, startInterval);
};
imageObj.src = 'file://' + path;
}
// "this" refers to the config object of the Handler
function sensorStartFn(sensorName) {
return function() {
canvas = document.getElementById('wearCanvas');
context = canvas.getContext('2d');
WS.sensorOn(WS.sensor(sensorName), .15, 'WearENV.cb');
if (log) {
WS.serverConnect('{{WSUrl}}', 'WearENV.server');
}
console.log(this.parentHandler);
if (DBG) console.log("Initializing " + this.prettyName + " mode 2345234");
WS.say(this.prettyName + "mode");
clearCanvas();
drawModeName(this.prettyName);
modeInit = true;
errorLogged = false;
}
}
function sensorFinishFn(sensorName) {
return function() {
if (DBG) console.log("Turning off sensor " + sensorName);
WS.sensorOff(WS.sensor(sensorName));
modeInit = false;
}
}
// this is really the default for an orientation SensorModeHandler
//@override
ModeHandler.prototype.defaultStart = function() {
canvas = document.getElementById('wearCanvas');
context = canvas.getContext('2d');
WS.sensorOn(WS.sensor('orientation'), .15, 'WearENV.cb');
if (log) {
WS.serverConnect('{{WSUrl}}', 'WearENV.server');
}
console.log(this);
if (DBG) console.log("Initializing " + this.config.prettyName + " mode 2345234");
WS.say(this.config.prettyName + "mode");
clearCanvas();
drawModeName(this.config.prettyName);
modeInit = true;
errorLogged = false;
};
//@override
ModeHandler.prototype.defaultFinish = function() {
WS.sensorOff(WS.sensor('orientation'));
modeInit = false;
}
// welcomeHandlerName is special because it's called by
// startEnv
new ModeHandler(welcomeHandlerName, {
prettyName: "Welcome!",
start: function() {
canvas = document.getElementById('wearCanvas');
context = canvas.getContext('2d');
drawTitlePage();
if (!envStarted) {
WS.say("Starting Sensor Explorer");
WS.sound('SUCCESS');
}
envStarted = true;
},
finish: function() {}
});
var orientationDrawCB = function(data) {
if (data['type'] == WS.sensor('orientation')) {
context.fillStyle = 'hsl(' + data['values'][0] + ', 90%, 50%)'
context.fillRect(0, 0, 640, 120);
context.fillStyle = 'hsl(' + data['values'][1] + ', 90%, 50%)'
context.fillRect(0, 120, 640, 120);
context.fillStyle = 'hsl(' + data['values'][2] + ', 90%, 50%)'
context.fillRect(0, 240, 640, 120);
}
}
new ModeHandler("orientation", {
prettyName: "Orientation explorer",
drawCallback: orientationDrawCB,
start: function() {
// other stuff you might want to do HERE
// note that including "start" here does nothing unless
// you add other stuff.
this.parentHandler.defaultStart();
},
});
new ModeHandler("accelerometer", {
// in here, "this" refers to the config object
// and if you want to get to the Handler itself, this.parentHandler
prettyName: "Accelerometer explorer",
start: sensorStartFn('accelerometer'),
drawCallback: function(data) {
if (data['type'] == WS.sensor('accelerometer')) {
context.fillStyle = 'hsl(' + Math.floor(15 * Math.abs(data['values'][0])) + ', 90%, 50%)';
context.fillRect(0, 0, 640, 120);
context.fillStyle = 'hsl(' + Math.floor(15 * Math.abs(data['values'][1])) + ', 90%, 50%)';
context.fillRect(0, 120, 640, 120);
context.fillStyle = 'hsl(' + Math.floor(15 * Math.abs(data['values'][2])) + ', 90%, 50%)';
context.fillRect(0, 240, 640, 120);
}
},
finish: sensorFinishFn('accelerometer')
});
new ModeHandler("magnetometer", {
// in here, "this" refers to the config object
// and if you want to get to the Handler itself, this.parentHandler
prettyName: "Magnetic field explorer",
start: sensorStartFn('magneticField'),
drawCallback: function(data) {
if (data['type'] == WS.sensor('magneticField')) {
context.fillStyle = 'hsl(' + data['values'][0] + ', 90%, 50%)';
context.fillRect(0, 0, 640, 120);
context.fillStyle = 'hsl(' + data['values'][1] + ', 90%, 50%)';
context.fillRect(0, 120, 640, 120);
context.fillStyle = 'hsl(' + data['values'][2] + ', 90%, 50%)';
context.fillRect(0, 240, 640, 120);
}
},
finish: sensorFinishFn('magneticField')
});
new ModeHandler("light", {
prettyName: "Light Sensor Explorer",
start: sensorStartFn('light'),
drawCallback: function(data) {
if (data['type'] == WS.sensor('light')) {
context.fillStyle = 'hsl(153, 90%, ' + Math.floor(10 * Math.log(data['values'][0])) + '%)';
context.fillRect(0, 0, 640, 360);
}
},
finish: sensorFinishFn('light')
});
new ModeHandler("eye", {
prettyName: "Eye Tracker Calibration",
start: eyeMain,
finish: eyeFinish
});
return {
camCB: camCB,
onGesture: onGesture,
start: startEnv,
cb: cb,
server: server
};
})();
$(function () {
if (WS.scriptVersion(0)) return;
WS.displayWebView();
WS.gestureCallback('onGesture', 'WearENV.onGesture');
WearENV.start();
});
</script>
</body>
</html>
{
"name": "WearDiary"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment