Week 1: A Collective Start

The icebreakers that kicked off class this semester guided our discussion about group dynamics and many considerations for designing collective experiences. Through conversation we articulated that a collective engenders a sense of good and positive feelings, and on the other hand, we pinpointed an underlying discomfort when interacting with others.

Questions we identified and asked included: 
As a participant, what are your expectations for your level of involvement? 
How are those expectations and your participation altered by group size, context, setting, and behaviors?
How are you communicating with others? 
What impacts your decision to follow the group or abstain from activity? 
Are you judgmental, anxious, comfortable, preoccupied with strategizing? 
Do you sense tension, conflict, competitiveness, lack of interest?
Does the activity encourage or discourage leadership and how? 

I’m excited to explore these ideas further as we learn to work with web sockets to create collaborative experiences mediated by technology. It’s a lovely continuation of my investigations in Socially Engaged Art last semester.

After the icebreakers we covered some basic Terminal commands, ensured that Node and the Express and Socket.io packages were installed, and launched a local server on our laptops. My novice understanding is that Node is a JavaScript framework for creating web applications and Express routes all requests from a client to a public server-side directory. A socket acts like a pipe through which the server receives data from many clients and emits it back out. How the server handles that data (leave it as is or transform it) and to which clients it broadcasts the data (all, one, only a few?) allows for many possible permutations .

With my environment set and a local server running, we started with the simplest of designs in the provided example sketches (and similar to the architecture of my experiments last fall): a client sends data, and the server broadcasts it to all connected clients except the original one. In a shared canvas scenario, all clients are equally represented. For example, when drawing in a browser window that points to my local server, those marks appear in all other open windows at the same address and vice versa. The server.js file contains all the code for running the server and receiving and sending messages from clients via sockets, and the sketch.js file (in the public directory) holds all of the client code which sends and receives message to and from the server.

During class we practiced sending two different types of input: mouse position (X and Y coordinates) and text. As a class we brainstormed additional inputs to illustrate and for our assignment, wrote sketches for at least two of those inputs. I worked with changing canvas size and mouseClicked. Without changing any of the code in the server.js file, I modified one of the sample sketch.js files to write my own interpretations for both of these inputs.

Changing Canvas Size
I understand the flow of the changing canvas size sketch to work this way. When I open a new window at my local server, a canvas is rendered with dimensions determined by the window’s width and height in setup(). The same happens for any subsequent new windows (for clarity here I’ll call these remote clients even though technically they are still on my machine).

When I adjust the size of my local window using the windowResized() function, the canvas adjusts accordingly. At the same time, this emits an event, called data, to the server through a socket with two points of information—one for width and one for height:

function windowResized() {
  resizeCanvas(windowWidth, windowHeight);
  socket.emit('data', {w: windowWidth, h: windowHeight});

When a remote client receives this data event from the server, it simultaneously calls a drawCanvas() function (my own name). Through this callback function I pass the width and height inputs which I represent in an argument (of my own name) called “size”, so drawCanvas(size). Within this function, the createCanvas function is called with the new dimensions. Notice how the width (w) and height (h) data points (same as I used in the windowResized() function are appended to size as attributes.

function drawCanvas(size) {
  createCanvas(size.w, size.h);

Just for fun I added a dynamically-changing rectangle to this sketch for additional resizing reference.

Code on GitHub
RemixPlay on Glitch



In this example, every time the mouse is clicked it draws an ellipse at the mouse’s X and Y position with a random hue and alpha (degree of transparency). Here I learned that how to send even more data inputs through the socket in the bundled “data” message, in this case adding the variables h and a for hue and alpha respectively.

function mouseClicked() {
  let h = random(100);  // Define and initialize a variable for hue
  let a = random(100);  // Define and initialize a variable for alpha
  fill(h, 100, 100, a);
  ellipse(mouseX, mouseY, 100, 100);
  socket.emit('data', {x: mouseX, y: mouseY, h, a});

When additional clients receive the “data” message the drawEllipse() function is called to render circles in the same locations and with the same color values: 

function drawEllipse(data) {
  fill(data.h, 100, 100, data.a);
  ellipse(data.x, data.y, 100, 100);

Of note, I noticed greater transparency values for ellipses rendered on remote clients, and I'm not sure why that is.

Code on Github
RemixPlay on Glitch