Digital Show & Tell

28 January 2015

Philo van Kemenade

@phivk

Tate Britain

Ticking Digitally

collaborative innovation

The city, The Web & Beyond

This Talk

My Clock Ticks Digitally

var canvas;
var cx, cy; // center
var n; // number of arms
var m; // milliseconds
var speed = 1;
var radius;
var scaler = 0.032;
var scalerMax = 0.5;
var scalerMin = 0.001;
var cDist;

var isPlaying = true;
var fromEpoch = false;
var rings = [
              {'show': false, 'over': false, 'index': 60-1},
              {'show': false, 'over': false, 'index': 60*60-1},
              {'show': false, 'over': false, 'index': 60*60*12-1},
              {'show': false, 'over': false, 'index': 60*60*24-1}
];
var showLines = false;
var showSettings = false;
var showHelp = false;

// colour constants
var RED;

function setup() {
    canvas = createCanvas(windowWidth, windowHeight);

	radius = min(width, height) / 2;
	cx = width / 2;
	cy = height / 2;

  n = 60*60*24; // 60 seconds, 60 minutes, 24 hours

  RED = color(204,17,17);

  // inputs
  var epochSwitch = getElement('second');
  epochSwitch.mousePressed(switchMode);

  canvas.mousePressed(onCanvasPressed);
}

function draw() {
	background(34,34,34);
  // update milliseconds
  if (isPlaying) {
    if (fromEpoch) {
      m = (new Date).getTime();
    } else {
      m = millis();
    }
  };
  // set speed
  m = m * pow(speed,2) * sign(speed);
  
  // draw rings
  for (var i = 0; i < rings.length; i++) {
    if (rings[i]['show']){
      drawRing(rings[i]['index'], color(255,255,255,128));  
    } 
    if (rings[i]['over']) {
      drawRing(rings[i]['index'], color(255,255,255,128));  
    };

  };
  
  // draw lines
  if (showLines) {
    for (var i = 0; i < 12; i++) {
      drawLine(PI/6.0 * i)
    };
  };

  // draw arms
  for (var i = 0; i < n; i++) {
    if (shouldDraw(i)) {
      drawArm(i, m);
    }; 
  };

  // draw help
  // if (showHelp) {
  //   drawHelp()
  // };
}

function shouldDraw (i) {
  var sampler = 1+floor((i)/60);
  return (1+i)%sampler==0;
} 

function drawArm(i, m) {
  var s = map(m*.001, 0, i+1, 0, TWO_PI) - HALF_PI;

  var r = calcLength(i);
  var rlast = calcLength(i-1);

  var startx = cx + cos(s) * rlast;
  var starty = cy + sin(s) * rlast;
  
  stroke(255);
  strokeWeight(1);
  
  // draw 1sec, first 60 minutes, first 24 hours in red
  if (i < (60*60)) {
    if (i==0 || (i+1)%60==0) {
      strokeWeight(3);
      stroke(RED);
    }
  } else if (i < (60*60*24)) {
    if ((i+1)%(60*60)==0) {
      strokeWeight(3);
      stroke(RED);
    }
  }
  line(startx, starty, cx + cos(s) * r, cy + sin(s) * r);
}

function drawRing (i, color) {
  stroke(color);
  strokeWeight(1);
  noFill();
  ellipseMode(RADIUS);
  ellipse(cx, cy, calcLength(i), calcLength(i));
}

function drawLine (rad) {
  stroke(128);
  strokeWeight(1);
  line(cx, cy, cx + cos(rad) * 2 *  radius, cy + sin(rad) * 2* radius);
}

function calcLength(i) {
  return radius * scaler * (sqrt(i + 1));
}

function zoom (wheelDelta) {
  var scroll = wheelToScroll(wheelDelta);
  if (sign(wheelDelta) > 0) { // zoom in
    if (scaler < scalerMax) {
      scaler = scaler * scroll ;      
    };
  } else { // zoom out
    if (scaler > scalerMin) {
      scaler = scaler * scroll ;      
    };
  }
}

function addSpeed (n) {
  speed = speed + n;
}

function addTime (n) {
  m = m + n;
}

function togglePlaying () {
  isPlaying = !isPlaying;
}

function toggleSettings () {
  showSettings = !showSettings;
}

function toggleHelp () {
  showHelp = !showHelp;
}

function toggleEpoch () {
  fromEpoch = !fromEpoch;
}

function toggleRings () {
  for (var i = 0; i < rings.length; i++) {
    rings[i]['show'] = !rings[i]['show'];
  };
}

function sign (number) {
  return number?number<0?-1:1:0;
}

function toggleLines () {
  showLines = !showLines;
}

function mouseMoved() {
  var cDist = dist(cx, cy, mouseX, mouseY);
  for (var i = 0; i < rings.length; i++) {
    rings[i]['over'] = false;
    if (i == 0) {
      if (cDist < calcLength(rings[i]['index'])){
        // set over for 1st ring
        rings[i]['over'] = true;
      }
    } else if (cDist < calcLength(rings[i]['index']) && cDist > calcLength(rings[i-1]['index'])){
      // set over for ring
      rings[i]['over'] = true;
    } else {
      rings[i]['over'] = false;
    }
  };
}

function keyPressed() {
  if (key === ' ') {
    togglePlaying();
  } else if (key === 'S') {
    toggleSettings();
  } else if (key === 'H') {
    toggleHelp();
  } else if (key === 'R') {
    toggleRings();
  } else if (key === 'L') {
    toggleLines();
  } else if (key === 'E') {
    toggleEpoch();
  } else if (keyCode == UP_ARROW) {
    addSpeed(1);
  } else if (keyCode == DOWN_ARROW) {
    addSpeed(-1);
  } else if (keyCode == RIGHT_ARROW) {
    addTime(1000);
  } else if (keyCode == LEFT_ARROW) {
    addTime(-1000);
  } 
  return false; // prevent default
}

function onCanvasPressed () {
  // toggle directly surrounding circle or lines
  var cDist = dist(cx, cy, mouseX, mouseY);
  for (var i = 0; i < rings.length; i++) {
    if (cDist < calcLength(rings[i]['index'])){
      // toggle ring
      rings[i]['show'] = !rings[i]['show'];
      break;
    };
  };

  if (cDist > calcLength(rings[rings.length-1]['index'])){
    toggleLines();
  };

  console.log("***");
  console.log(cDist);
  console.log(scaler);
}

function switchMode () {
  fromEpoch = !getElement('cmn-toggle-4').elt.checked;
}

function windowResized() {
  resizeCanvas(windowWidth, windowHeight);
  radius = min(width, height) / 2;
  cx = width / 2;
  cy = height / 2;
}

window.ondblclick=function(){
  var fs = fullscreen();
  fullscreen(!fs);
};

$(window).mousewheel(function(event, delta, deltaX, deltaY) {
    zoom(deltaY);
});

function wheelToScroll (delta) {
  // transform mousewheel speed to scroll speed
  var scrollMax = .1;
  
  // using inverse hyperbolic sine function sinh^-1(x) == log(x+sqrt(x^2 + 1))
  // http://www.wolframalpha.com/input/?i=y+%3D+15+*+log%28x%2Bsqrt%28x%5E2+%2B+1%29%29+%28x+from+-500+to+500%29
  var scrollSpeed = 1 + (scrollMax / 6 ) * Math.log(delta+Math.sqrt(Math.pow(delta,2) + 1));
  
  // using double logistic sigmoid function
  // http://www.wolframalpha.com/input/?i=plot+y%3D+100+*+sgn%28x%29*%281+-+e%5E%28-%280.02x%29%5E2%29%29+%28x+from+-300+to+300%29
  // var scrollSpeed = 100 * sign(controlDelta) * (1 - Math.exp( - Math.pow( 0.02 * controlDelta, 2)));
  // *not responsive enough on start of scroll
  // console.log('scrollspeed: ', scrollSpeed);
  return scrollSpeed;
};

My clock is made

of 288 lines of JavaScript

zero to prototype

Standing on the shoulders of giants

reaching out, feeding back

Digital Making









Filmmaking is a bit like sculpting

Webmaking is more like Lego

Innovating together


From D.I.Y.

to D.I.T.



Message: 1

Date: Tue, 05 Feb 2013 19:48:28 +0000

From: Webdoc

To: community-popcorn@mozilla.org

Subject: [Popcorn] Hackathon soon in Europe?

Message-ID: <5111620C.10500@budgetparticipatif.info>

Content-Type: text/plain; charset=ISO-8859-1; format=flowed

Hello !

I'm living in Lisbon, in Portugal and I'm starting a documentary movie called "Learning to count" about a democratic innovation called "Participatory budgeting".

We are looking for some support , since we don't have yet anyone in the team really able to contribute to Popcorn.js

I've just seen that a popcorn workshop few weeks ago in Barcelona. But I was wondering if any of you were aware of anything in Europe in the next months. I'm really interested into organizing/being part of hackathon in june.

One of our perspective is carrying on this project next year with more youngsters involved. We've made a short video for a crowfunding campaign : http://vimeo.com/57984836

We are shooting until december in Europe, mainly in France, Portugal and the UK and we are looking to develop a webnative project with a collaborative platform ( we want our documentary to be open source with pictures or videos from local communities thanks to free workshops and using free code). One model would be Land of opportunity...

Thank you for your consideration.

Gilles

An Email

 A Workshop

Participatory

productive

Purposeful

Web-Native Storytelling

Enabling an experience

 

using the capability of the web

as a mechanism for narration

 

from the start of the authoring process

6 countries

12 events

236 participants

37 prototypes

waiting to be told

The web is full of stories

Eva Domínguez, Gerado García, Juan Gomis, Andreu Meixide, Berto Yáñez

The City

The Web

& Beyond

Documenting

urban complexity

[...] the urban database documentary, a mode of media art practice that uses structural systems to uncover new perspectives on the lived experience of place.

[...]

While particularly prominent in recent decades, I argue that the genre of the urban database documentary arises at the turn of the 20th century in response to the rise of the metropolis and the widespread adoption of new media technologies such as photography, cinema, and radio.

A Serendipitous symphony

 Irene Gil, Océane Apffel-Font, Andrea Traldi, Lucia Andújar, Cláudio Silva and Berto Yáñez  

Navigating space & time

Enrica Colusso, Jason DaPonte, Philo van Kemenade

Storytelling beyond the screen?

Immersive Storytelling

@ MIT Media Lab

Design Innovation Workshop 2015

Ahemdabad, India

Thank you

@phivk

popathon.org

fromtimetoti.me