// these are DOM elements var main_canvas; var pos1_slider; var tilt1_slider; var pos2_slider; var tilt2_slider; var pos3_slider; var tilt3_slider; var sel_char; var sel_mode; // constant for initialization var canvasWidth = 960; var canvasHeight = 500; // this is the variable that holds all character objects var letterParams = null; var letterParamsDebug = { "A": { "box1": { "position": -174, "tilt": -47 }, "box2": { "position": -104, "tilt": -4 }, "box3": { "position": -121, "tilt": 58 } }, "B": { "box1": { "position": -191, "tilt": -90 }, "box2": { "position": -54, "tilt": -45 }, "box3": { "position": -12, "tilt": 6 } }, "C": { "box1": { "position": -163, "tilt": -84 }, "box2": { "position": -191, "tilt": 163 }, "box3": { "position": 0, "tilt": -27 } }, } // the sliders will write to this location var debugLetter = "9"; // Handy string of all letters available var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; // DrawMode can be "solo" or "alphabet" var initialDrawMode = "exhibit"; var curDrawMode; // these variables are used for animation var soloCurLetter = "1"; var soloPrevObj = null; var soloIsAnimating = false; var soloNumAnimationFrames = 60; var soloCurAnimationFrame = 0; var chosenLettersDebug = ["C", "C", "C", "C", "C", "C", "C", "C"]; var chosenLetters = ["C", "O", "N", "F", "E", "T", "T", "I"]; var chosenPrevObjs = [null, null, null, null, null, null, null, null]; var chosenIsAnimating = [false, false, false, false, false, false, false, false]; var chosenNumAnimationFrames = 30; var chosenCurAnimationFrame = [0, 0, 0, 0, 0, 0, 0, 0]; var curChosenLetter = 0; var lastKeyPressedTime; var secondsUntilSwapMode = 15; var lastWordSwappedTime; var isSwappingWords = true; var secondsPerWord = 8; var curSwapWord = 0; var swapWordsDebug = [ "CCCCCCCC", "AAAAAAAA", "BBBBBBBB" ] var swapWords = [ "CONFETTI", "ACTUALLY", "EXPECTED", "PROPERTY", "ADDITION", "FOLLOWED", "PROVIDED", "ALTHOUGH", "HAPPENED", "QUESTION", "AMERICAN", "INCREASE", "RECEIVED", "ANYTHING", "INDUSTRY", "RELIGION", "BUILDING", "INTEREST", "REMEMBER", "BUSINESS", "INVOLVED", "REQUIRED", "CHILDREN", "NATIONAL", "SERVICES", "COMPLETE", "ORGANIZE", "SOUTHERN", "CONSIDER", "PERSONAL", "STANDARD", "CONTINUE", "PLANNING", "STRENGTH", "ALPHABET", "POSITION", "STUDENTS", "DECISION", "POSSIBLE", "SUDDENLY", "DIRECTLY", "PRESSURE", "THINKING", "DISTRICT", "PROBABLY", "TOGETHER", "ECONOMIC", "PROBLEMS", "TRAINING", "EVIDENCE", "PROGRAMS" ] function preload() { // sometimes when debugging, letterParams is initialized locally if(letterParams == null) { letterParams = loadJSON('letters.json'); } } function make_interface() { // create two sliders pos1_slider = createSlider(-200, 200, 0); tilt1_slider = createSlider(-180, 180, 0); pos2_slider = createSlider(-200, 200, 0); tilt2_slider = createSlider(-180, 180, 0); pos3_slider = createSlider(-200, 200, 0); tilt3_slider = createSlider(-180, 180, 0); sel_char = createSelect(); for (var i = 0, len = letters.length; i < len; i++) { sel_char.option(letters[i]); } sel_char.changed(letterChangedEvent); sel_mode = createSelect(); sel_mode.option("alphabet"); sel_mode.option("solo"); sel_mode.option("exhibit"); sel_mode.changed(modeChangedEvent); sel_mode.value(initialDrawMode); button = createButton('show data'); button.mousePressed(buttonPressedEvent); // var button2 = createButton('random data'); // button2.mousePressed(randomData); pos1_slider.parent('slider1Container'); tilt1_slider.parent('slider2Container'); pos2_slider.parent('slider3Container'); tilt2_slider.parent('slider4Container'); pos3_slider.parent('slider5Container'); tilt3_slider.parent('slider6Container'); sel_char.parent('selectorContainer'); sel_mode.parent('modeContainer'); button.parent('buttonContainer'); // button2.parent(buttonContainer); dataObjectToSliders(letterParams[debugLetter]) } function setup () { // create the drawing canvas, save the canvas element main_canvas = createCanvas(canvasWidth, canvasHeight); // rotation in degrees (more slider friendly) angleMode(DEGREES); curDrawMode = initialDrawMode; var now = millis(); lastKeyPressedTime = now; lastWordSwappedTime = now; // position each element on the page main_canvas.parent('canvasContainer'); if(initialDrawMode != "exhibit") { make_interface(); } } // Generate a random set of letters. // This was useful to generate placeholders. // They are output to the html. function randomData() { var o = {}; for (var i = 0, len = letters.length; i < len; i++) { var obj = {} obj["box1"] = {}; obj["box1"]["position"] = Math.round(random(-20, 20)); obj["box1"]["tilt"] = Math.round(random(-30, 30)); obj["box2"] = {}; obj["box2"]["position"] = Math.round(random(-20, 20)); obj["box2"]["tilt"] = Math.round(random(-30, 30)); obj["box3"] = {}; obj["box3"]["position"] = Math.round(random(-20, 20)); obj["box3"]["tilt"] = Math.round(random(-30, 30)); o[letters[i]] = obj; } var text = select('#output'); var json = JSON.stringify(o, null, 2); text.html(json) } // Take all values from the slider and generate a data object // that represents one character in the alphabet. function sliderToDataObject() { var obj = {}; obj["box1"] = {}; obj["box1"]["position"] = pos1_slider.value(); obj["box1"]["tilt"] = tilt1_slider.value(); obj["box2"] = {}; obj["box2"]["position"] = pos2_slider.value(); obj["box2"]["tilt"] = tilt2_slider.value(); obj["box3"] = {}; obj["box3"]["position"] = pos3_slider.value(); obj["box3"]["tilt"] = tilt3_slider.value(); return obj; } // Given a data object representing a character, adjust // the sliders appropiately. function dataObjectToSliders(obj) { pos1_slider.value(obj["box1"]["position"]); tilt1_slider.value(obj["box1"]["tilt"]); pos2_slider.value(obj["box2"]["position"]); tilt2_slider.value(obj["box2"]["tilt"]); pos3_slider.value(obj["box3"]["position"]); tilt3_slider.value(obj["box3"]["tilt"]); } // Funcation called when DOM letter selector is changed function letterChangedEvent() { var item = sel_char.value(); dataObjectToSliders(letterParams[item]); } // Funcation called when DOM mode selector is changed function modeChangedEvent() { curDrawMode = sel_mode.value(); } // Function called when "show data" button is pressed. // Presents a single JSON object in the HTML. function buttonPressedEvent() { var obj = letterParams[debugLetter] var json = JSON.stringify(obj, null, 2); var text = select('#output'); text.html(json) } // global front and back colors var colorFront = [207, 222, 227]; var colorBack = [29, 42, 46]; // draws one of the three rectangles of a character function drawPart(y_offset, pos, tilt) { push(); translate(pos, y_offset); rotate(tilt); var scale = 10; fill(colorFront); rect(-20*scale, -3*scale, 20*scale, 3*scale); pop(); } // draws a single character given an object, position, and scale function drawFromDataObject(x, y, s, obj) { push(); translate(x, y); scale(s, s); drawPart(-50, obj["box1"]["position"], obj["box1"]["tilt"]); drawPart( 0, obj["box2"]["position"], obj["box2"]["tilt"]); drawPart( 50, obj["box3"]["position"], obj["box3"]["tilt"]); pop(); } function computeCurrentSoloChar() { // now figure out what object to draw var obj; if (soloIsAnimating) { nextObj = letterParams[soloCurLetter]; // interpolation logic here obj = {}; obj["box1"] = {}; obj["box1"]["position"] = map(soloCurAnimationFrame, 0, soloNumAnimationFrames, soloPrevObj["box1"]["position"], nextObj["box1"]["position"]) obj["box1"]["tilt"] = map(soloCurAnimationFrame, 0, soloNumAnimationFrames, soloPrevObj["box1"]["tilt"], nextObj["box1"]["tilt"]) obj["box2"] = {}; obj["box2"]["position"] = map(soloCurAnimationFrame, 0, soloNumAnimationFrames, soloPrevObj["box2"]["position"], nextObj["box2"]["position"]) obj["box2"]["tilt"] = map(soloCurAnimationFrame, 0, soloNumAnimationFrames, soloPrevObj["box2"]["tilt"], nextObj["box2"]["tilt"]) obj["box3"] = {}; obj["box3"]["position"] = map(soloCurAnimationFrame, 0, soloNumAnimationFrames, soloPrevObj["box3"]["position"], nextObj["box3"]["position"]) obj["box3"]["tilt"] = map(soloCurAnimationFrame, 0, soloNumAnimationFrames, soloPrevObj["box3"]["tilt"], nextObj["box3"]["tilt"]) } else { obj = letterParams[soloCurLetter]; } return obj; } function computeCurrentChosenChar(n) { // now figure out what object to draw var obj; if (chosenIsAnimating[n]) { if(chosenCurAnimationFrame[n] < 0) { obj = chosenPrevObjs[n]; } else { nextObj = letterParams[chosenLetters[n]]; // interpolation logic here obj = {}; obj["box1"] = {}; obj["box1"]["position"] = map(chosenCurAnimationFrame[n], 0, chosenNumAnimationFrames, chosenPrevObjs[n]["box1"]["position"], nextObj["box1"]["position"]) obj["box1"]["tilt"] = map(chosenCurAnimationFrame[n], 0, chosenNumAnimationFrames, chosenPrevObjs[n]["box1"]["tilt"], nextObj["box1"]["tilt"]) obj["box2"] = {}; obj["box2"]["position"] = map(chosenCurAnimationFrame[n], 0, chosenNumAnimationFrames, chosenPrevObjs[n]["box2"]["position"], nextObj["box2"]["position"]) obj["box2"]["tilt"] = map(chosenCurAnimationFrame[n], 0, chosenNumAnimationFrames, chosenPrevObjs[n]["box2"]["tilt"], nextObj["box2"]["tilt"]) obj["box3"] = {}; obj["box3"]["position"] = map(chosenCurAnimationFrame[n], 0, chosenNumAnimationFrames, chosenPrevObjs[n]["box3"]["position"], nextObj["box3"]["position"]) obj["box3"]["tilt"] = map(chosenCurAnimationFrame[n], 0, chosenNumAnimationFrames, chosenPrevObjs[n]["box3"]["tilt"], nextObj["box3"]["tilt"]) } } else { obj = letterParams[chosenLetters[n]]; } return obj; } // var lastKeyPressedTime; // var secondsUntilSwapMode = 30; // var lastWordSwappedTime; // var isSwappingWords = true; // var secondsPerWord = 5; // var curSwapWord = 0; // var swapWords = [ function draw () { // update debug letter from sliders if(curDrawMode != "exhibit") { letterParams[debugLetter] = sliderToDataObject(); } now = millis(); // check to see if we should go into swapping mode if(!isSwappingWords && lastKeyPressedTime + 1000 * secondsUntilSwapMode < now) { isSwappingWords = true; } if(isSwappingWords) { if(lastWordSwappedTime + 1000 * secondsPerWord < now) { lastWordSwappedTime = now; curSwapWord = (curSwapWord + 1) % swapWords.length; for(var i=0; i<8; i++) { var c = swapWords[curSwapWord][i]; swapExhibitLetter(i, c, 6*i); } } } background(colorBack); fill(colorFront); stroke(95, 52, 8); // shorthand variables to allow margin var o = 40 var w2 = width - 2 * o var h2 = height - 2 * o if (curDrawMode == "alphabet") { var cur_index = 0; var hw = (w2 / 9.0) / 2.0; var hh = (h2 / 4.0) / 2.0; for(var j=0; j<4; j++) { for(var i=0; i<9; i++) { var cur_letter = letters[cur_index]; var obj = letterParams[cur_letter]; drawFromDataObject(o + hw + i * w2/9.0, o + hh + j * h2/4.0, 0.20, obj) cur_index = cur_index + 1; } } } else if (curDrawMode == "solo") { // see if animation should be turned off if(soloIsAnimating && soloCurAnimationFrame >= soloNumAnimationFrames) { soloIsAnimating = false; } // if we are animating, increment the number of animation frames if(soloIsAnimating) { soloCurAnimationFrame = soloCurAnimationFrame + 1; } var obj = computeCurrentSoloChar(); drawFromDataObject(o + w2/2.0, o + h2/2.0, 1.0, obj) } else if (curDrawMode == "exhibit") { for(var i=0; i<8; i++) { // see if animation should be turned off if(chosenIsAnimating[i] && chosenCurAnimationFrame[i] >= chosenNumAnimationFrames) { chosenIsAnimating[i] = false; } // if we are animating, increment the number of animation frames if(chosenIsAnimating[i]) { chosenCurAnimationFrame[i] = chosenCurAnimationFrame[i] + 1; } var obj = computeCurrentChosenChar(i); drawFromDataObject(o + w2/10.0 + i*w2/8.0, o + h2/2.0, 0.25, obj) } } } function swapExhibitLetter(n, c, frameDelay) { chosenPrevObjs[n] = computeCurrentChosenChar(n); chosenLetters[n] = c; chosenIsAnimating[n] = true; chosenCurAnimationFrame[n] = 0 - frameDelay; } function keyTyped() { if (key == '!') { saveBlocksImages(); } else if (key == '@') { saveBlocksImages(true); } else { lastKeyPressedTime = millis(); if(isSwappingWords) { isSwappingWords = false; } upper_key = key.toUpperCase(); if (upper_key in letterParams) { if(curDrawMode == "solo") { soloPrevObj = computeCurrentSoloChar(); soloCurLetter = upper_key; soloIsAnimating = true; soloCurAnimationFrame = 0; } else if(curDrawMode == "alphabet") { sel_char.value(upper_key); dataObjectToSliders(letterParams[upper_key]); } else if(curDrawMode == "exhibit") { swapExhibitLetter(curChosenLetter, upper_key, 0); curChosenLetter = (curChosenLetter + 1) % 8; } } } }