1. Choose a form of discomfort (choose one of the four forms, and get more specific from there)
Visceral— sensory overload (fast-paced flashing lights and colors, visual obstruction, inability to concentrate)
2. Identify a goal that could be reached through this discomfort
Get participants to think about their attention spans and how they are captured and manipulated by external stimuli. Ideally would like to facilitate dialogue surrounding this topic to span more overarching issues regarding our visual landscape (for example the advertising industry, technology’s effects on our mental abilities).
3. Identify a design approach (must be different than Journey #1) that can utilize your chosen form of discomfort.
A web-based experience (the space which is most susceptible to such discomfort).
4. Prototype a “journey” using that approach, toward the goal, through the chosen form of discomfort.
A web-based experience where users are presented with the objective of reading an essay, but are subsequently confronted with increasing sensory distraction inhibiting their ability to finish it (they wouldn’t have read it in its entirety anyway, right?)
This prototype focuses on testing the following factors:
User interest/engagement (How far will they get? If not far, why not? Is it boring? Does it get too uncomfortable too quickly?)
Does the user understand the purpose of the experience?
Did the user find the experience worthwhile/rewarding? Does it actually facilitate dialogue/thought as per my design goals, or in any other way?
Based on the results for these research points, I’d like to move on to figuring out what contexts the experience(s) should be presented in (how will users stumble upon this?) then build more complex web-based experiences utilizing similar subtle, encroaching a/v annoyances.
When considering what I could do as my daily practice, I thought about the ways I’d like to grow over the next several weeks, and the biggest thing that came to mind was the amount of time I spend in front of the screen. I decided to draw for 30 minutes each day. Turning off my monitors and focusing on the page for this duration would be an exercise in leaving my comfort zone; I would have to fight impulses to check social media, surf the web, etc. Then, I would have to document my progress forcing me to publish/share my drawings.
My self portrait consists of a series of videos, which together compose an image of my head, that collectively follow the cursor as it moves left and right across the window. In order to achieve this, I first recorded a video of myself turning from one profile position to the other. The video lasts about 25 seconds. After recording I split the video vertically into 10 even pieces and added them to the DOM as 10 separate <video> elements. Then I used js to map the length of the video in seconds to the width of the window in pixels, and had the video fast-forward or rewind to the time that corresponds to the current mouse position, every time mouse movement is detected.
I split the portrait into several pieces so that I could play around with the variables that determine the number of frames and the time each video transition would take to fast-forward/rewind from one point to another. I like the resulting jumpy effect and the way my face gets abstracted at certain moments and then slowly pieces back together.
//src:
//[1] https://stackoverflow.com/a/7790764 - capturing mouse pos
//[2] https://stackoverflow.com/a/10756409 - range conversion
//[3] https://stackoverflow.com/a/36731430 - FF/RW video to given time
function init() { //all js that needs to happen after page has loaded
document.onmousemove = handleMouseMove; //[1]
function handleMouseMove(event) {
var dot, eventDoc, doc, body, pageX, pageY;
event = event || window.event; //IE
// If pageX/Y aren't available and clientX/Y are,
// calculate pageX/Y - logic taken from jQuery.
// (For old IE)
if (event.pageX == null && event.clientX != null) {
eventDoc = (event.target && event.target.ownerDocument) || document;
doc = eventDoc.documentElement;
body = eventDoc.body;
event.pageX = event.clientX +
(doc && doc.scrollLeft || body && body.scrollLeft || 0) -
(doc && doc.clientLeft || body && body.clientLeft || 0);
event.pageY = event.clientY +
(doc && doc.scrollTop || body && body.scrollTop || 0) -
(doc && doc.clientTop || body && body.clientTop || 0);
}
// console.log(event.pageX);
var width, vid_length_s, vid_timeToSkipTo;
// width = screen.width;
width = window.innerWidth;
vid_length = 25;
vid_timeToSkipTo = convertToRange(event.pageX, [0, width], [0, vid_length]);
console.log(vid_timeToSkipTo);
goToTime(Math.floor(vid_timeToSkipTo));
}
}
window.addEventListener('load', init);
function convertToRange(value, srcRange, dstRange) { //[2]
// value is outside source range return
if (value < srcRange[0] || value > srcRange[1]) {
return NaN;
}
var srcMax = srcRange[1] - srcRange[0],
dstMax = dstRange[1] - dstRange[0],
adjValue = value - srcRange[0];
return (adjValue * dstMax / srcMax) + dstRange[0];
}
function goToTime(time) { //[3]
var vid11 = document.getElementById('vid11'),
ticks11 = 10, // number of frames during fast-forward
frms11 = 100, // number of milliseconds between frames in fast-forward/rewind
endtime11 = time; // time to fast-forward/rewind to (in seconds)
// fast-forward/rewind video to end time
var tdelta11 = (endtime11 - vid11.currentTime) / ticks11;
var startTime11 = vid11.currentTime;
for (let i = 0; i < ticks11; ++i) {
(function(j) {
setTimeout(function() {
vid11.currentTime = startTime11 + tdelta11 * j;
}, j * frms11);
})(i);
}
var vid12 = document.getElementById('vid12'),
ticks12 = 10, // number of frames during fast-forward
frms12 = 150, // number of milliseconds between frames in fast-forward/rewind
endtime12 = time; // time to fast-forward/rewind to (in seconds)
// fast-forward/rewind video to end time
var tdelta12 = (endtime12 - vid12.currentTime) / ticks12;
var startTime12 = vid12.currentTime;
for (let i = 0; i < ticks12; ++i) {
(function(j) {
setTimeout(function() {
vid12.currentTime = startTime12 + tdelta12 * j;
}, j * frms12);
})(i);
}
var vid13 = document.getElementById('vid13'),
ticks13 = 10, // number of frames during fast-forward
frms13 = 200, // number of milliseconds between frames in fast-forward/rewind
endtime13 = time; // time to fast-forward/rewind to (in seconds)
// fast-forward/rewind video to end time
var tdelta13 = (endtime13 - vid13.currentTime) / ticks13;
var startTime13 = vid13.currentTime;
for (let i = 0; i < ticks13; ++i) {
(function(j) {
setTimeout(function() {
vid13.currentTime = startTime13 + tdelta13 * j;
}, j * frms13);
})(i);
}
var vid14 = document.getElementById('vid14'),
ticks14 = 10, // number of frames during fast-forward
frms14 = 250, // number of milliseconds between frames in fast-forward/rewind
endtime14 = time; // time to fast-forward/rewind to (in seconds)
// fast-forward/rewind video to end time
var tdelta14 = (endtime14 - vid14.currentTime) / ticks14;
var startTime14 = vid14.currentTime;
for (let i = 0; i < ticks14; ++i) {
(function(j) {
setTimeout(function() {
vid14.currentTime = startTime14 + tdelta14 * j;
}, j * frms14);
})(i);
}
var vid15 = document.getElementById('vid15'),
ticks15 = 10, // number of frames during fast-forward
frms15 = 300, // number of milliseconds between frames in fast-forward/rewind
endtime15 = time; // time to fast-forward/rewind to (in seconds)
// fast-forward/rewind video to end time
var tdelta15 = (endtime15 - vid15.currentTime) / ticks15;
var startTime15 = vid15.currentTime;
for (let i = 0; i < ticks15; ++i) {
(function(j) {
setTimeout(function() {
vid15.currentTime = startTime15 + tdelta15 * j;
}, j * frms15);
})(i);
}
var vid16 = document.getElementById('vid16'),
ticks16 = 10, // number of frames during fast-forward
frms16 = 350, // number of milliseconds between frames in fast-forward/rewind
endtime16 = time; // time to fast-forward/rewind to (in seconds)
// fast-forward/rewind video to end time
var tdelta16 = (endtime16 - vid16.currentTime) / ticks16;
var startTime16 = vid16.currentTime;
for (let i = 0; i < ticks16; ++i) {
(function(j) {
setTimeout(function() {
vid16.currentTime = startTime16 + tdelta16 * j;
}, j * frms16);
})(i);
}
var vid17 = document.getElementById('vid17'),
ticks17 = 10, // number of frames during fast-forward
frms17 = 300, // number of milliseconds between frames in fast-forward/rewind
endtime17 = time; // time to fast-forward/rewind to (in seconds)
// fast-forward/rewind video to end time
var tdelta17 = (endtime17 - vid17.currentTime) / ticks17;
var startTime17 = vid17.currentTime;
for (let i = 0; i < ticks17; ++i) {
(function(j) {
setTimeout(function() {
vid17.currentTime = startTime17 + tdelta17 * j;
}, j * frms17);
})(i);
}
var vid18 = document.getElementById('vid18'),
ticks18 = 10, // number of frames during fast-forward
frms18 = 250, // number of milliseconds between frames in fast-forward/rewind
endtime18 = time; // time to fast-forward/rewind to (in seconds)
// fast-forward/rewind video to end time
var tdelta18 = (endtime18 - vid18.currentTime) / ticks18;
var startTime18 = vid18.currentTime;
for (let i = 0; i < ticks18; ++i) {
(function(j) {
setTimeout(function() {
vid18.currentTime = startTime18 + tdelta18 * j;
}, j * frms18);
})(i);
}
var vid19 = document.getElementById('vid19'),
ticks19 = 10, // number of frames during fast-forward
frms19 = 200, // number of milliseconds between frames in fast-forward/rewind
endtime19 = time; // time to fast-forward/rewind to (in seconds)
// fast-forward/rewind video to end time
var tdelta19 = (endtime19 - vid19.currentTime) / ticks19;
var startTime19 = vid19.currentTime;
for (let i = 0; i < ticks19; ++i) {
(function(j) {
setTimeout(function() {
vid19.currentTime = startTime19 + tdelta19 * j;
}, j * frms19);
})(i);
}
var vid20 = document.getElementById('vid20'),
ticks20 = 10, // number of frames during fast-forward
frms20 = 150, // number of milliseconds between frames in fast-forward/rewind
endtime20 = time; // time to fast-forward/rewind to (in seconds)
// fast-forward/rewind video to end time
var tdelta20 = (endtime20 - vid20.currentTime) / ticks20;
var startTime20 = vid20.currentTime;
for (let i = 0; i < ticks20; ++i) {
(function(j) {
setTimeout(function() {
vid20.currentTime = startTime20 + tdelta20 * j;
}, j * frms20);
})(i);
}
}
The code is pretty sloppy and could probably be optimized a lot if given more time. The videos perform horribly on Firefox and Chrome, while working fine in Safari. In general, playing 10 videos at once obviously causes average-performing computers to increase in temperature at an unacceptable rate and would probably eventually cause the browser to crash. Instead, there is probably a way for one video file to be used that can be duplicated and cropped as necessary.
The controller I built consists of a two-axis joystick (`l`,`r`,`u`,`d`) and two buttons (one for `x`,and one that prints `in=andrew\n` on the first press, and just `i` on every subsequent press after that). I was unable to implement a Wifi101 or Ethernet shield, so the controller must be plugged in to function. All of this fit nicely into an iPhone case:
A video of it working:
The shell command is something like the following but with the appropriate usb input name and ip address:
Second Life is a massively multiplayer online role-playing sandbox game. Whether or not it’s to be considered a game is questionable as many users seem to take it as seriously as they would their normal lives, even going so far as to make and spend real money for virtual goods and services. One of the defining feature of SL is that it’s a 3d-rendered environment that functions in real-time, similarly to many other contemporary MMOs.
SL provides real-time visual and sound-related interactions with the environment and between users. A user can have their avatar perform actions with objects (sit in chairs, open doors, etc), and perform actions with other users (chat via text or microphone, have their avatars perform actions together, swap items, teleport to each other, etc).
But what’s most interesting about SL is the way it connects various parts of the WWW to its environments. Owners of a specific piece of land (a “parcel”) on a server (a “sim”) can stream music in the format of a radio station into the simulation for all visitors to hear. Some sims are designated shopping centers containing walls of objects that can be clicked on to purchase and download goods and services from https://marketplace.secondlife.com.
Seemingly any kind of web media can be embedded into the environment: