├── example ├── text │ └── hello.txt ├── media │ ├── audio │ │ ├── pno.mp3 │ │ └── pnoc3.mp3 │ ├── video │ │ ├── ride.mp4 │ │ └── tree.mp4 │ └── images │ │ └── mcluhan.jpg ├── bt.js ├── index.html ├── -photo.html ├── -hack.html ├── -film.html ├── -paper.html ├── -cassette.html ├── space.html ├── -wall.html ├── css │ ├── space.css │ └── style.css └── js │ └── theNewAesthetic.js ├── .gitignore ├── lib ├── media │ ├── index.js │ ├── gif.js │ ├── wiki.js │ ├── hack.js │ ├── log.js │ ├── textmessage.js │ ├── voice.js │ ├── cassette.js │ ├── dj.js │ ├── presence.js │ ├── window.js │ ├── paper.js │ ├── map.js │ ├── photo.js │ ├── film.js │ └── wall.js ├── guides │ ├── client.js │ └── static.js ├── core │ ├── medium.js │ └── manager.js └── utils │ └── bt.js ├── bower_components └── glitch-canvas │ ├── bower.json │ ├── .bower.json │ └── dist │ ├── glitch-canvas.min.js │ └── glitch-canvas.js ├── package.json ├── README.md ├── gulpfile.js ├── index.js └── cheatsheet └── index.html /example/text/hello.txt: -------------------------------------------------------------------------------- 1 | Hello Digital World -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | bower_components -------------------------------------------------------------------------------- /example/media/audio/pno.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taylorbf/mcluhan-js/HEAD/example/media/audio/pno.mp3 -------------------------------------------------------------------------------- /example/media/audio/pnoc3.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taylorbf/mcluhan-js/HEAD/example/media/audio/pnoc3.mp3 -------------------------------------------------------------------------------- /example/media/video/ride.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taylorbf/mcluhan-js/HEAD/example/media/video/ride.mp4 -------------------------------------------------------------------------------- /example/media/video/tree.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taylorbf/mcluhan-js/HEAD/example/media/video/tree.mp4 -------------------------------------------------------------------------------- /example/media/images/mcluhan.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taylorbf/mcluhan-js/HEAD/example/media/images/mcluhan.jpg -------------------------------------------------------------------------------- /example/bt.js: -------------------------------------------------------------------------------- 1 | exports.rand = function(scale) { 2 | 3 | } 4 | /* 5 | exports.SmartMatrix = function(rows,cols) { 6 | 7 | this.rows = rows; 8 | this.cols = cols; 9 | 10 | this.row = 0; 11 | this.col = 0; 12 | 13 | 14 | 15 | //have a 'translate index to row' func, same for col 16 | //have a 'step through' function that returns an object with next row/col 17 | //have a 'step row' that goes to next in row, then cycles around 18 | //have a 'steo col' that goes through col and cycles around 19 | 20 | } 21 | 22 | */ -------------------------------------------------------------------------------- /lib/media/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | cassette: require('./cassette'), 3 | dj: require('./dj'), 4 | film: require('./film'), 5 | gif: require('./gif'), 6 | hack: require('./hack'), 7 | log: require('./log'), 8 | map: require('./map'), 9 | paper: require('./paper'), 10 | photo: require('./photo'), 11 | presence: require('./presence'), 12 | textmessage: require('./textmessage'), 13 | voice: require('./voice'), 14 | wiki: require('./wiki'), 15 | window: require('./window'), 16 | wall: require('./wall') 17 | } -------------------------------------------------------------------------------- /bower_components/glitch-canvas/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "glitch-canvas", 3 | "version": "0.1.4", 4 | "authors": [ 5 | "Georg Fischer " 6 | ], 7 | "description": "JavaScript library for applying a glitch effect to a canvas element", 8 | "main": "dist/glitch-canvas.js", 9 | "moduleType": [ 10 | "amd", 11 | "globals" 12 | ], 13 | "keywords": [ 14 | "glitch", 15 | "effect", 16 | "fx", 17 | "javascript", 18 | "canvas" 19 | ], 20 | "license": "MIT", 21 | "homepage": "https://github.com/snorpey/glitch-canvas", 22 | "ignore": [ 23 | "**/.*", 24 | "node_modules", 25 | "bower_components", 26 | "test", 27 | ".travis.yml", 28 | "build", 29 | "src", 30 | "bower.json", 31 | "*.md", 32 | "*.png", 33 | "LICENSE", 34 | "example" 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /lib/media/gif.js: -------------------------------------------------------------------------------- 1 | var util = require('util'); 2 | var Medium = require('../core/medium') 3 | 4 | /** 5 | * @class Gif 6 | * @constructor 7 | * @description Performative GIF media element 8 | * @extends Medium 9 | * @param {object} Params (see Params) 10 | * @return {Photo} 11 | */ 12 | var GIF = module.exports = function(params) { 13 | 14 | this.defaultSize = { w: 800 } 15 | this.type = "img"; 16 | 17 | //separate item constructor "Medium" with properties for placement, animation, remove, make dom element, styling element based on json 18 | Medium.call(this, params); 19 | 20 | } 21 | 22 | util.inherits(GIF, Medium); 23 | 24 | 25 | /** 26 | * Load a GIF from /images (no .gif file extension necessary). 27 | */ 28 | GIF.prototype.load = function(src) { 29 | 30 | this.setAll("src","media/images/"+src+".gif") 31 | return this 32 | 33 | } 34 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mcluhan.js", 3 | "description": "Live web art performance platform", 4 | "author": "Ben Taylor ", 5 | "repository": { 6 | "type": "git", 7 | "url": "http://github.com/taylorbf/mcluhan-js/" 8 | }, 9 | "dependencies": { 10 | "tone": "0.4.x", 11 | "nexusui": "1.0.x", 12 | "nprogress": "^0.1.6" 13 | }, 14 | "devDependencies": { 15 | "gulp": "3.8.x", 16 | "gulp-rename": "1.2.x", 17 | "gulp-uglify": "0.2.x", 18 | "gulp-less": "1.2.x", 19 | "gulp-util": "3.0.x", 20 | "browserify": "5.12.x", 21 | "run-sequence": "0.3.x", 22 | "eventemitter2": "0.4.x", 23 | "vinyl-source-stream": "1.0.x", 24 | "jsdox": "0.2.x", 25 | "extend": "2.0.x", 26 | "gulp-jsdoc": "^0.1.4" 27 | }, 28 | "engine": "node >= 0.10.0", 29 | "version": "0.0.1", 30 | "license": "New BSD License" 31 | } 32 | -------------------------------------------------------------------------------- /lib/media/wiki.js: -------------------------------------------------------------------------------- 1 | var util = require('util'); 2 | var Medium = require('../core/medium') 3 | 4 | /** 5 | * @class Wiki 6 | * @constructor 7 | * @description Performative WIKIPEDIA media element 8 | * @extends Medium 9 | * @param {object} Params (see Params) 10 | * @return {Photo} 11 | */ 12 | var Wiki = module.exports = function(params) { 13 | 14 | this.defaultSize = { w: 1200, h: 1200 } 15 | this.type = "iframe"; 16 | 17 | //separate item constructor "Medium" with properties for placement, animation, remove, make dom element, styling element based on json 18 | Medium.call(this, params); 19 | 20 | this.elementsLoaded = 0; 21 | for (var i=0;i" 6 | ], 7 | "description": "JavaScript library for applying a glitch effect to a canvas element", 8 | "main": "dist/glitch-canvas.js", 9 | "moduleType": [ 10 | "amd", 11 | "globals" 12 | ], 13 | "keywords": [ 14 | "glitch", 15 | "effect", 16 | "fx", 17 | "javascript", 18 | "canvas" 19 | ], 20 | "license": "MIT", 21 | "homepage": "https://github.com/snorpey/glitch-canvas", 22 | "ignore": [ 23 | "**/.*", 24 | "node_modules", 25 | "bower_components", 26 | "test", 27 | ".travis.yml", 28 | "build", 29 | "src", 30 | "bower.json", 31 | "*.md", 32 | "*.png", 33 | "LICENSE", 34 | "example" 35 | ], 36 | "_release": "0.1.4", 37 | "_resolution": { 38 | "type": "version", 39 | "tag": "0.1.4", 40 | "commit": "c7d6fcf625a61add013861ac89b3aafe4c3e9a6e" 41 | }, 42 | "_source": "git://github.com/snorpey/glitch-canvas.git", 43 | "_target": "~0.1.4", 44 | "_originalSource": "glitch-canvas", 45 | "_direct": true 46 | } -------------------------------------------------------------------------------- /example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 24 | 25 | 28 | 29 |

McLuhan.js Demos

30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 |
Ben Taylor © 2015-2016
44 | 45 | 46 | -------------------------------------------------------------------------------- /example/-photo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 56 | 57 |
58 |
59 | 60 |

PHOTO

61 | 62 | 63 | 64 |
Lovingly made with McLuhan.js
65 | 66 |
67 |
68 | 69 | 70 | -------------------------------------------------------------------------------- /example/-hack.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 56 | 57 |
58 |
59 | 60 |

HACK

61 | 62 | 63 | 64 |
Lovingly made with McLuhan.js
65 | 66 |
67 |
68 | 69 | 70 | -------------------------------------------------------------------------------- /lib/media/hack.js: -------------------------------------------------------------------------------- 1 | var util = require('util'); 2 | var Medium = require('../core/medium') 3 | 4 | /** 5 | * @class Hack 6 | * @constructor 7 | * @description Performative IFRAME media element 8 | * @extends Medium 9 | * @param {object} Params (see Params) 10 | * @return {Photo} 11 | */ 12 | var Hack = module.exports = function(params) { 13 | 14 | this.defaultSize = { w: 1200, h: 1200 } 15 | this.type = "iframe"; 16 | 17 | //separate item constructor "Medium" with properties for placement, animation, remove, make dom element, styling element based on json 18 | Medium.call(this, params); 19 | 20 | this.elementsLoaded = 0; 21 | for (var i=0;i 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 60 | 61 |
62 |
63 | 64 |

FILM

65 | 66 | 67 | 68 |
Lovingly made with McLuhan.js
69 | 70 |
71 |
72 | 73 | 74 | -------------------------------------------------------------------------------- /example/-paper.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 59 | 60 |
61 |
62 | 63 |

PAPER

64 | 65 | 66 | 67 |
Lovingly made with McLuhan.js
68 | 69 |
70 |
71 | 72 | 73 | -------------------------------------------------------------------------------- /example/-cassette.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 63 | 64 |
65 |
66 | 67 |

CASSETTE

68 | 69 | 70 | 71 |
Lovingly made with McLuhan.js
72 | 73 |
74 |
75 | 76 | 77 | -------------------------------------------------------------------------------- /example/space.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | dream 5 | 6 | 7 | 8 | 9 | 10 | 11 | 57 | 58 |
59 | 60 | 61 | 62 | 63 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp') 2 | , rename = require('gulp-rename') 3 | 4 | , gutil = require('gulp-util') 5 | , browserify = require('browserify') 6 | , source = require('vinyl-source-stream') 7 | 8 | , runSequence = require('run-sequence') 9 | var path = require('path'); 10 | var jsdoc = require("gulp-jsdoc"); 11 | var shell = require("gulp-shell"); 12 | 13 | 14 | var watcher = gulp.watch(['index.js','./lib/**/*.js', './lib/*.js'], ['default']) 15 | watcher.on('change', function(event) { 16 | console.log('File '+event.path+' was '+event.type+', running tasks...') 17 | }) 18 | 19 | gulp.task('browserify', function() { 20 | return browserify({ entries: './index.js' }) 21 | .bundle() 22 | .on('error', gutil.log) 23 | .pipe(source('mcluhan.js')) 24 | .pipe(gulp.dest('./dist/')) 25 | .pipe(gulp.dest('../mcluhan-perf/pages/js/')) 26 | }) 27 | 28 | //gulp.task('jsdoc', function() { 29 | //gulp.src("./lib/**/*.js") 30 | /* .pipe(jsdoc('./api/',{ 31 | path: 'ink-docstrap', 32 | systemName : "McLuhan.js", 33 | footer : "McLuhan.js", 34 | copyright : "Ben Taylor © 2015", 35 | navType : "vertical", 36 | theme : "benly", 37 | linenums : true, 38 | collapseSymbols : false, 39 | inverseNav : false 40 | })) 41 | 42 | }) */ 43 | 44 | //gulp.task('jsdoc', function() { 45 | // gulp.src("./lib/**/*.js") 46 | /* .pipe(jsdoc.parser()) 47 | .pipe(gulp.dest('./somewhere')) 48 | }) */ 49 | 50 | //jsdoc **/*.js -t templates/haruki -d console -q format=json > ../cheatsheet/all.json 51 | gulp.task('jsdoc', shell.task([ 52 | 'jsdoc lib/**/*.js -t templates/haruki -d console -q format=json > cheatsheet/all.json' 53 | ])) 54 | 55 | gulp.task('default', function(done) { 56 | //,'jsdoc' 57 | runSequence('browserify','jsdoc',done) 58 | }) 59 | 60 | 61 | -------------------------------------------------------------------------------- /example/-wall.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 74 | 75 |
76 |
77 | 78 |

WALL

79 | 80 | 81 | 82 |
Lovingly made with McLuhan.js
83 | 84 |
85 |
86 | 87 | 88 | -------------------------------------------------------------------------------- /example/css/space.css: -------------------------------------------------------------------------------- 1 | 2 | .textmessage { 3 | width: 95%; 4 | left:2%; 5 | right:2%; 6 | position:fixed; 7 | bottom:0px; 8 | overflow:auto; 9 | top:auto !important; 10 | } 11 | 12 | .from-me, .from-them { 13 | font-family: "Helvetica Neue" !important; 14 | font-size: 16px !important; 15 | font-weight: 200; 16 | max-width: 255px; 17 | word-wrap: break-word; 18 | margin-bottom: 20px; 19 | line-height: 1.3em; 20 | position:relative !important; 21 | display:none; 22 | } 23 | 24 | .textmessage p { 25 | margin:0px !important; 26 | } 27 | 28 | .clear { 29 | clear: both; 30 | position:relative !important; 31 | } 32 | .from-me { 33 | position:relative; 34 | padding:10px 14px; 35 | color:white; 36 | background:#0B93F6; 37 | border-radius:25px; 38 | -webkit-border-radius:25px; 39 | float: right; 40 | } 41 | 42 | .from-me::before { 43 | content:""; 44 | position:absolute; 45 | z-index:-1; 46 | bottom:-2px; 47 | right:-7px; 48 | height:20px; 49 | border-right:20px solid #0B93F6; 50 | border-bottom-left-radius: 16px 14px; 51 | -webkit-transform:translate(0, -2px); 52 | } 53 | 54 | .from-me::after { 55 | content:""; 56 | position:absolute; 57 | z-index:1; 58 | bottom:-2px; 59 | right:-56px; 60 | width:26px; 61 | height:20px; 62 | background:white; 63 | border-bottom-left-radius: 10px; 64 | -webkit-transform:translate(-30px, -2px); 65 | } 66 | 67 | .from-them { 68 | position:relative; 69 | padding:10px 14px; 70 | background:#E5E5EA; 71 | border-radius:25px; 72 | -webkit-border-radius:25px; 73 | color: black; 74 | float: left; 75 | } 76 | 77 | .from-them::before { 78 | content:""; 79 | position:absolute; 80 | z-index:2; 81 | bottom:-2px; 82 | left:-7px; 83 | height:20px; 84 | border-left:20px solid #E5E5EA; 85 | border-bottom-right-radius: 16px 14px; 86 | -webkit-transform:translate(0, -2px); 87 | } 88 | 89 | .from-them::after { 90 | content:""; 91 | position:absolute; 92 | z-index:3; 93 | bottom:-2px; 94 | left:4px; 95 | width:26px; 96 | height:20px; 97 | background:white; 98 | border-bottom-right-radius: 10px; 99 | -webkit-transform:translate(-30px, -2px); 100 | } -------------------------------------------------------------------------------- /bower_components/glitch-canvas/dist/glitch-canvas.min.js: -------------------------------------------------------------------------------- 1 | //! glitch-canvas by snorpey, MIT License 2 | !function(a,b){"function"==typeof define&&define.amd?define(b):"object"==typeof exports?module.exports=b():a.glitch=b()}(this,function(){function a(a,k,l){if(i(a)&&j(k,"parameters","object")&&j(l,"callback","function")){for(n=h(k),b(v,a),b(w,a),o=d(a,n.quality),p=f(o),q=e(p),t=0,u=n.iterations;u>t;t++)c(p,q,n.seed,n.amount,t,n.iterations);r=new Image,r.onload=function(){x.drawImage(r,0,0),s=x.getImageData(0,0,a.width,a.height),l(s)},r.src=g(p)}}function b(a,b){a.width!==b.width&&(a.width=b.width),a.height!==b.height&&(a.height=b.height)}function c(a,b,c,d,e,f){var g=a.length-b-4,h=parseInt(g/f*e,10),i=parseInt(g/f*(e+1),10),j=i-h,k=parseInt(h+j*c,10);k>g&&(k=g);var l=Math.floor(b+k);a[l]=Math.floor(256*d)}function d(a,b){var c="number"==typeof b&&1>b&&b>0?b:.1;y.putImageData(a,0,0);var d=w.toDataURL("image/jpeg",c);switch(d.length%4){case 3:d+="=";break;case 2:d+="==";break;case 1:d+="==="}return d}function e(a){var b=417;for(t=0,u=a.length;u>t;t++)if(255===a[t]&&218===a[t+1]){b=t+2;break}return b}function f(a){var b,c,d,e=[];for(t=23,u=a.length;u>t;t++){switch(c=B[a.charAt(t)],b=(t-23)%4){case 1:e.push(d<<2|c>>4);break;case 2:e.push((15&d)<<4|c>>2);break;case 3:e.push((3&d)<<6|c)}d=c}return e}function g(a){var b,c,d,e=["data:image/jpeg;base64,"];for(t=0,u=a.length;u>t;t++){switch(c=a[t],b=t%3){case 0:e.push(A[c>>2]);break;case 1:e.push(A[(3&d)<<4|c>>4]);break;case 2:e.push(A[(15&d)<<2|c>>6]),e.push(A[63&c])}d=c}return 0===b?(e.push(A[(3&d)<<4]),e.push("==")):1===b&&(e.push(A[(15&d)<<2]),e.push("=")),e.join("")}function h(a){return{seed:(a.seed||0)/100,quality:(a.quality||0)/100,amount:(a.amount||0)/100,iterations:a.iterations||0}}function i(a){return j(a,"image_data","object")&&j(a.width,"image_data.width","number")&&j(a.height,"image_data.height","number")&&j(a.data,"image_data.data","object")&&j(a.data.length,"image_data.data.length","number")&&k(a.data.length,"image_data.data.length",l,"> 0")?!0:!1}function j(a,b,c){return typeof a===c?!0:(m(a,"typeof "+b,'"'+c+'"','"'+typeof a+'"'),!1)}function k(a,b,c,d){return c(a)===!0?!0:(m(a,b,d,"not"),void 0)}function l(a){return a>0}function m(a,b,c,d){throw new Error("glitch(): Expected "+b+" to be "+c+", but it was "+d+".")}var n,o,p,q,r,s,t,u,v=document.createElement("canvas"),w=document.createElement("canvas"),x=v.getContext("2d"),y=w.getContext("2d"),z="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",A=z.split(""),B={};return A.forEach(function(a,b){B[a]=b}),a}); -------------------------------------------------------------------------------- /example/css/style.css: -------------------------------------------------------------------------------- 1 | 2 | /* demo links */ 3 | 4 | body { 5 | margin:0; 6 | padding:0; 7 | height:100%; 8 | width:100%; 9 | background-color:#19d; 10 | font-family:"Quicksand", helvetica neue; 11 | text-align:center; 12 | } 13 | 14 | h1, button, footer { 15 | font-family:"Quicksand", helvetica neue; 16 | font-weight:100; 17 | color:white; 18 | text-align:center; 19 | margin:35px auto; 20 | } 21 | 22 | h1 { 23 | margin:70px auto 35px; 24 | font-size:25pt; 25 | letter-spacing:1px; 26 | } 27 | 28 | button { 29 | border:solid 2px #19d; 30 | padding:8px 32px; 31 | background-color:#fff; 32 | color:#19d; 33 | font-size:16pt; 34 | cursor:pointer; 35 | width:180px; 36 | text-align:center; 37 | -webkit-transition: border .2s; 38 | transition: border .2s; 39 | } 40 | button:hover { 41 | border:solid 2px #fff; 42 | } 43 | button:active { 44 | background-color:#19d; 45 | color:#fff; 46 | } 47 | 48 | footer { 49 | margin:50px auto; 50 | font-size:11pt; 51 | width:100%; 52 | } 53 | 54 | 55 | 56 | /* start page */ 57 | 58 | #shell { 59 | position:absolute; 60 | top:0px; 61 | width:100%; 62 | height:100%; 63 | } 64 | 65 | .guides { 66 | margin:0 auto; 67 | height:400px; 68 | width:400px; 69 | position:relative; 70 | top: 50%; 71 | transform: translateY(-50%); 72 | } 73 | 74 | .bguide, .sguide { 75 | position:absolute; 76 | background-color:white; 77 | color:#19d; 78 | text-align:center; 79 | padding:80px 40px; 80 | box-sizing:border-box; 81 | top:-65px; 82 | height:100%; 83 | width:100%; 84 | font-size:16pt; 85 | opacity:1; 86 | border:dashed 4px #19d; 87 | } 88 | 89 | .sguide { 90 | background-color:#333; 91 | } 92 | 93 | #sgarrow { 94 | -ms-transform: rotate(20deg); 95 | -webkit-transform: rotate(20deg); 96 | transform: rotate(20deg); 97 | -webkit-transition: transform .5s; 98 | transition: all .5s; 99 | font-size:100px; 100 | } 101 | 102 | 103 | /* progress bar */ 104 | 105 | #nprogress { 106 | position:absolute; 107 | top:0px; 108 | } 109 | 110 | #nprogress .bar { 111 | background:white !important; 112 | height:3px !important; 113 | opacity:1; 114 | transition: transform 2s ease !important; 115 | -webkit-transition: -webkit-transform 2s ease !important; 116 | } 117 | #nprogress .peg { 118 | box-shadow:none !important; 119 | transition: transform 2s ease !important; 120 | -webkit-transition: -webkit-transform 2s ease !important; 121 | } 122 | 123 | #nprogress .spinner-icon { 124 | border-top-color: #fff !important; 125 | border-left-color: #fff !important; 126 | } 127 | 128 | /* splash */ 129 | 130 | #splash { 131 | width:100%; 132 | height:100%; 133 | position:absolute; 134 | top:0px; 135 | background-color:#19d; 136 | color:#fff; 137 | font:300 100px 'Quicksand'; 138 | z-index:10; 139 | text-align:center; 140 | display:table; 141 | } 142 | 143 | #splash span { 144 | display: table-cell; 145 | vertical-align: middle; 146 | } 147 | 148 | -------------------------------------------------------------------------------- /lib/media/log.js: -------------------------------------------------------------------------------- 1 | var util = require('util'); 2 | var Medium = require('../core/medium') 3 | 4 | /** 5 | * @class Log 6 | * @constructor 7 | * @description Visually log code 8 | * @extends Medium 9 | * @param {object} Params (see Params) 10 | * @return {Log} 11 | */ 12 | var Log = module.exports = function(params) { 13 | 14 | this.defaultSize = { w: 200, h: 200 } 15 | this.type = "div" 16 | 17 | this.fulltext = "" 18 | this.tickInterval = false 19 | this.currentLine = 0 20 | 21 | this.boundTick = this.tick.bind(this) 22 | 23 | //separate item constructor "Medium" with properties for placement, animation, remove, make dom element, styling element based on json 24 | Medium.call(this, params) 25 | 26 | for (var i=0;i5000) { 53 | var len = this.element[i].innerHTML.length 54 | this.element[i].innerHTML = this.element[i].innerHTML.slice( len-3000, len ) 55 | } 56 | } 57 | } 58 | return this; 59 | } 60 | 61 | /** 62 | * Load a text file via URL (i.e. "client.html") and print it line by line as a code log 63 | */ 64 | Log.prototype.load = function(path) { 65 | $.get(path, function(data) { 66 | if (data) { 67 | data = data.replace(//g,">") 69 | data = data.replace(/"/g,"\"") 70 | data = data.replace(/'/g,"\'") 71 | this.fulltext = data.split("\n") 72 | this.start() 73 | } 74 | }.bind(this)) 75 | 76 | return this; 77 | } 78 | 79 | /** 80 | * Log the next line of text 81 | */ 82 | Log.prototype.tick = function() { 83 | this.write(this.fulltext[this.currentLine]) 84 | this.currentLine++ 85 | if (this.currentLine >= this.fulltext.length) { 86 | this.currentLine = 0 87 | } 88 | } 89 | 90 | /** 91 | * Start an interval that prints a line every 50 ms 92 | */ 93 | Log.prototype.start = function(path) { 94 | if (this.tickInterval) { 95 | clearInterval(this.tickInterval) 96 | } 97 | this.tickInterval = setInterval(this.boundTick, 50) 98 | return this; 99 | } 100 | /** 101 | * Stop the interval 102 | */ 103 | Log.prototype.stop = function(path) { 104 | 105 | clearInterval(this.tickInterval) 106 | return this; 107 | } 108 | 109 | 110 | Log.prototype._destroy = function() { 111 | this.stop() 112 | } 113 | 114 | -------------------------------------------------------------------------------- /lib/guides/client.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | var ClientProject = module.exports = function() { 4 | 5 | this.showbguide = true; 6 | this.smoothguide = 0; 7 | window.NProgress = require('nprogress') 8 | 9 | this.wwid = window.screen.availWidth; 10 | this.whgt = window.screen.availHeight; 11 | 12 | } 13 | 14 | ClientProject.prototype.setup = function() { 15 | 16 | var htmlstr = '' 20 | + '
' 21 | + 'Please resize your browser to the size of this box.' 22 | + '
' 23 | 24 | $(".guides").append(htmlstr) 25 | 26 | var htmlstr = '
' 27 | + 'The Last Cloud' 28 | + '
' 29 | 30 | $("body").append(htmlstr) 31 | 32 | 33 | //NProgress.start(); 34 | //NProgress.inc(); 35 | 36 | 37 | $("", { 38 | rel: "stylesheet", 39 | type: "text/css", 40 | href: "../node_modules/nprogress/nprogress.css" 41 | }).appendTo("head"); 42 | 43 | projectwid = $(".guides").width() 44 | projecthgt = $(".guides").height() 45 | 46 | window.addEventListener("resize",this.checkSize.bind(this)) 47 | 48 | this.checkSize() 49 | /* 50 | setTimeout("NProgress.set(0.39)", 2000); 51 | setTimeout("NProgress.set(0.99)", 4000); 52 | setTimeout(NProgress.done, 6000); 53 | setTimeout("$('#splash').fadeOut()", 6000); */ 54 | 55 | window.addEventListener("beforeunload", function() { 56 | m.deck(m.spaceLimit); 57 | }); 58 | } 59 | 60 | ClientProject.prototype.checkSize = function() { 61 | var winwid = window.innerWidth; 62 | var winhgt = window.innerHeight; 63 | if (winwid < projectwid + 10 && winwid > projectwid - 10 && winhgt < projecthgt + 10 && winhgt > projecthgt - 10) { 64 | 65 | if (this.showbguide) { 66 | this.showbguide = false; 67 | $(".bguide").fadeOut(this.smoothguide) 68 | $(".sguide").fadeIn(0) 69 | this.watchWindow(); 70 | } 71 | } else { 72 | this.smoothguide = 500; 73 | } 74 | } 75 | 76 | ClientProject.prototype.watchWindow = function() { 77 | this.sguide = setInterval(this.pingWindow.bind(this), 100) 78 | } 79 | 80 | 81 | ClientProject.prototype.pingWindow = function() { 82 | var winx = window.screenLeft; 83 | var winy = window.screenTop; 84 | var winwid2 = window.outerWidth; 85 | var winhgt2 = window.outerHeight; 86 | 87 | var distx = winx + (winwid2/2) - (this.wwid/2) 88 | var disty = winy + (winhgt2/2) - (this.whgt/2) 89 | 90 | var polar = toPolar(distx,disty) 91 | var degrees = Math.round((polar.angle/(Math.PI*2)) * 360) + 180; 92 | //var size = (Math.round(polar.radius)/8)+30 93 | 94 | $("#sgarrow").css("-ms-transform", "rotate("+degrees+"deg)") 95 | $("#sgarrow").css("-webkit-transform", "rotate("+degrees+"deg)") 96 | $("#sgarrow").css("transform", "rotate("+degrees+"deg)") 97 | //$("#sgarrow").css("font-size", size+"px") 98 | 99 | if (Math.abs(distx) < 20 && Math.abs(disty) < 20 ) { 100 | $(".sguide").fadeOut(this.smoothguide) 101 | clearInterval(this.sguide) 102 | } else { 103 | this.smoothguide = 500 104 | } 105 | 106 | } 107 | 108 | ClientProject.prototype.begin = function() { 109 | 110 | $("#shell").fadeOut(500) 111 | 112 | } 113 | 114 | 115 | -------------------------------------------------------------------------------- /lib/guides/static.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | var StaticProject = module.exports = function() { 4 | 5 | this.showbguide = true; 6 | this.smoothguide = 0; 7 | window.NProgress = require('nprogress') 8 | 9 | this.wwid = window.screen.availWidth; 10 | this.whgt = window.screen.availHeight; 11 | 12 | } 13 | 14 | StaticProject.prototype.setup = function() { 15 | 16 | var htmlstr = '' 20 | + '
' 21 | + 'Please resize your browser to the size of this box.' 22 | + '
' 23 | 24 | $(".guides").append(htmlstr) 25 | 26 | var htmlstr = '
' 27 | + 'M' 28 | + '
' 29 | 30 | $("body").append(htmlstr) 31 | 32 | 33 | NProgress.start(); 34 | //NProgress.inc(); 35 | 36 | 37 | $("", { 38 | rel: "stylesheet", 39 | type: "text/css", 40 | href: "../node_modules/nprogress/nprogress.css" 41 | }).appendTo("head"); 42 | 43 | projectwid = $(".guides").width() 44 | projecthgt = $(".guides").height() 45 | 46 | window.addEventListener("resize",this.checkSize.bind(this)) 47 | 48 | this.checkSize() 49 | 50 | setTimeout("NProgress.set(0.39)", 2000); 51 | setTimeout("NProgress.set(0.99)", 4000); 52 | setTimeout(NProgress.done, 6000); 53 | setTimeout("$('#splash').fadeOut()", 6000); 54 | 55 | window.addEventListener("beforeunload", function() { 56 | m.deck(m.spaceLimit); 57 | }); 58 | } 59 | 60 | StaticProject.prototype.checkSize = function() { 61 | var winwid = window.innerWidth; 62 | var winhgt = window.innerHeight; 63 | if (winwid < projectwid + 10 && winwid > projectwid - 10 && winhgt < projecthgt + 10 && winhgt > projecthgt - 10) { 64 | 65 | if (this.showbguide) { 66 | this.showbguide = false; 67 | $(".bguide").fadeOut(this.smoothguide) 68 | $(".sguide").fadeIn(0) 69 | this.watchWindow(); 70 | } 71 | } else { 72 | this.smoothguide = 500; 73 | } 74 | } 75 | 76 | StaticProject.prototype.watchWindow = function() { 77 | this.sguide = setInterval(this.pingWindow.bind(this), 100) 78 | } 79 | 80 | 81 | StaticProject.prototype.pingWindow = function() { 82 | var winx = window.screenLeft; 83 | var winy = window.screenTop; 84 | var winwid2 = window.outerWidth; 85 | var winhgt2 = window.outerHeight; 86 | 87 | var distx = winx + (winwid2/2) - (this.wwid/2) 88 | var disty = winy + (winhgt2/2) - (this.whgt/2) 89 | 90 | var polar = toPolar(distx,disty) 91 | var degrees = Math.round((polar.angle/(Math.PI*2)) * 360) + 180; 92 | //var size = (Math.round(polar.radius)/8)+30 93 | 94 | $("#sgarrow").css("-ms-transform", "rotate("+degrees+"deg)") 95 | $("#sgarrow").css("-webkit-transform", "rotate("+degrees+"deg)") 96 | $("#sgarrow").css("transform", "rotate("+degrees+"deg)") 97 | //$("#sgarrow").css("font-size", size+"px") 98 | 99 | if (Math.abs(distx) < 20 && Math.abs(disty) < 20 ) { 100 | $(".sguide").fadeOut(this.smoothguide) 101 | clearInterval(this.sguide) 102 | } else { 103 | this.smoothguide = 500 104 | } 105 | 106 | } 107 | 108 | StaticProject.prototype.begin = function() { 109 | 110 | $("#shell").fadeOut(500) 111 | $("body").css("background-color","white") 112 | 113 | m.start(0,1000); 114 | 115 | } 116 | 117 | 118 | -------------------------------------------------------------------------------- /lib/media/textmessage.js: -------------------------------------------------------------------------------- 1 | var util = require('util'); 2 | var Medium = require('../core/medium') 3 | 4 | /** 5 | * @class TextMessage 6 | * @constructor 7 | * @description Performative TEXT MESSAGE media element 8 | * @extends Medium 9 | * @param {object} Params (see Params) 10 | * @return {TextMessage} 11 | */ 12 | var TextMessage = module.exports = function(params) { 13 | 14 | this.defaultSize = { w: 300, h: 700 } 15 | this.type = "div"; 16 | 17 | //separate item constructor "Medium" with properties for placement, animation, remove, make dom element, styling element based on json 18 | Medium.call(this, params); 19 | 20 | for (var i=0;i 80 ) { 60 | $([this.element[i].inner]).children().slice(0,20).remove() 61 | } 62 | 63 | } 64 | 65 | this.me = !this.me 66 | 67 | if (!skiplog) { 68 | this.history.push(msg) 69 | } 70 | return this 71 | 72 | } 73 | 74 | /** 75 | * Start rapid texting (recycling past text) 76 | */ 77 | TextMessage.prototype.scroll = function() { 78 | 79 | this.scrolling = true; 80 | this.oneScroll() 81 | return this 82 | 83 | } 84 | /** 85 | * Stop rapid texting 86 | */ 87 | TextMessage.prototype.unscroll = function(msg) { 88 | 89 | this.scrolling = false; 90 | return this 91 | 92 | } 93 | 94 | /* 95 | * . 96 | */ 97 | TextMessage.prototype.oneScroll = function() { 98 | 99 | this.histIndex = cycle(this.histIndex,0,this.history.length) 100 | 101 | this.text(this.history[this.histIndex],true) 102 | 103 | if (this.scrolling) { 104 | setTimeout(this.oneScroll.bind(this),50) 105 | } 106 | return this 107 | 108 | } 109 | 110 | /** 111 | * Create collection of texts from a text file 112 | * @param {STring} filename Name of .txt file in /text 113 | */ 114 | TextMessage.prototype.read = function(text) { 115 | if (journal[text]) { 116 | this.history = journal[text].split(" ") 117 | } 118 | return this; 119 | } 120 | 121 | 122 | /* Leftover from TEXT widget, may be useful if adapted.... */ 123 | /* eventually move this to happen at start up for all files in 124 | /media/text folder, and to make them stored in journals object 125 | with filname as object key */ 126 | TextMessage.prototype.readFile = function(file,callback) { 127 | file = file ? file : "hello" 128 | this.text 129 | $.get("text/"+file+'.txt', function(text) { 130 | this.text = text ? text : "null" 131 | this.words = this.text.split(" "); 132 | this.letters = this.text.split(""); 133 | var bc = callback.bind(this) 134 | bc(data); 135 | }.bind(this), 'text'); 136 | return this 137 | } 138 | 139 | -------------------------------------------------------------------------------- /lib/media/voice.js: -------------------------------------------------------------------------------- 1 | var util = require('util'); 2 | var meSpeak = require("mespeak") 3 | 4 | /** 5 | * @class Voice 6 | * @constructor 7 | * @description Performative Text-To-Speech media element 8 | * @param {object} Params (see Params) 9 | * @return {Voice} 10 | */ 11 | 12 | var Voice = module.exports = function(params) { 13 | 14 | this.text = "hello world" 15 | 16 | this.element = new Tone.Player().connect(m.fx) 17 | 18 | meSpeak.loadConfig(require("mespeak/src/mespeak_config.json")) 19 | 20 | //Select english/american voice 21 | meSpeak.loadVoice(require("mespeak/voices/en/en-us.json")) 22 | 23 | } 24 | 25 | /** 26 | * Speak a phrase using a computer voice 27 | * @param {String} phrase The phrase to speak 28 | */ 29 | Voice.prototype.say = function(phrase) { 30 | 31 | this.text = phrase; 32 | this.speed = 175; 33 | this.pitch = 50; 34 | 35 | var speechBuffer = meSpeak.speak(phrase, { 'rawdata': true }); 36 | 37 | Tone.context.decodeAudioData( speechBuffer, function( result ) { 38 | 39 | this.element._buffer.set(result) 40 | this.element.playbackRate = 1 41 | this.element.retrigger = true 42 | this.element.loop = false 43 | this.element.start() 44 | 45 | }.bind(this)); 46 | 47 | } 48 | 49 | 50 | /** 51 | * Play audio file 52 | * @param {float} rate Playback rate of audio file (0.25 - 4). DOES NOT CHANGE PITCH. 53 | */ 54 | Voice.prototype.play = function(rate) { 55 | this.rate = rate ? rate : this.rate; 56 | this.speed(this.rate) 57 | this.element.start() 58 | return this 59 | } 60 | 61 | /** 62 | * Pause audio playback 63 | */ 64 | Voice.prototype.stop = function() { 65 | this.element.stop() 66 | return this 67 | } 68 | 69 | /** 70 | * Turn audio looping on or off 71 | * @param {boolean} on Looping on (true) or off (false) 72 | */ 73 | Voice.prototype.loop = function(on) { 74 | if (on===false || on===0) { 75 | this.element.loop = false 76 | } else { 77 | this.element.loop = true 78 | } 79 | return this 80 | } 81 | 82 | /** 83 | * Loop audio between two points 84 | * @param {float} start starting loop position 85 | * @param {float} stop ending loop position 86 | */ 87 | Voice.prototype.skip = function(start,stop) { 88 | this.start = start ? start : 1; 89 | this.stop = stop ? stop : this.start + 0.2; 90 | 91 | this.element.setLoopPoints(this.start * 1000, this.stop*1000) 92 | this.element.loop = true 93 | 94 | this.skipping = true; 95 | return this; 96 | } 97 | 98 | /** 99 | * Stop skipping the audio file 100 | */ 101 | Voice.prototype.unskip = function() { 102 | this.element.loop = false 103 | return this 104 | } 105 | 106 | /** 107 | * Change the audio file's playback rate (does not change pitch!) 108 | * @param {float} rate Playback rate (0.25 - 4) 109 | */ 110 | Voice.prototype.speed = function(rate) { 111 | if (rate) { 112 | this.element.playbackRate = rate 113 | this.rate = rate; 114 | } 115 | return this; 116 | } 117 | 118 | /** 119 | * Change the audio file's playback rate (does not change pitch!) 120 | * @param {float} rate Playback rate (0.25 - 4) 121 | */ 122 | Voice.prototype.volume = function(level) { 123 | if (level || level === 0) { 124 | this.element.volume = level 125 | this.level = level; 126 | } 127 | return this; 128 | } 129 | 130 | /** 131 | * If the element is hidden, show it. 132 | */ 133 | Voice.prototype.bomb = function(dur) { 134 | setTimeout( this.kill.bind(this), dur ? dur : 1000) 135 | return this 136 | } 137 | 138 | /** 139 | * Remove this element and destroy all references to it 140 | */ 141 | Voice.prototype.kill = function() { 142 | this._destroy() 143 | m.media.splice(m.media.indexOf(this)) 144 | } 145 | 146 | 147 | Voice.prototype._destroy = function(level) { 148 | this.element.disconnect() 149 | this.element = null 150 | } 151 | 152 | 153 | -------------------------------------------------------------------------------- /lib/media/cassette.js: -------------------------------------------------------------------------------- 1 | var util = require('util'); 2 | var Medium = require('../core/medium') 3 | 4 | /** 5 | * @constructor 6 | * @description Performative AUDIO media element 7 | * @extends Medium 8 | * @param {object} Params (see Params) 9 | * @return {Cassette} 10 | */ 11 | var Cassette = module.exports = function(params) { 12 | 13 | this.defaultSize = { w: 300 } 14 | this.src = false; 15 | this.type = "audio" 16 | 17 | //separate item constructor "Medium" with properties for placement, animation, remove, make dom element, styling element based on json 18 | Medium.call(this, params); 19 | 20 | this.interval = false; 21 | this.rate = 1; 22 | 23 | this.setAll("controls", true); 24 | this.setAll("volume", 0.75); 25 | this.loop(); 26 | 27 | } 28 | 29 | util.inherits(Cassette, Medium); 30 | 31 | /** 32 | * Load an audio file via source string. 33 | * @param {String} src name of .mp3 file in /media folder. For example, .load("piano") will load "/media/piano.mp3" 34 | */ 35 | Cassette.prototype.load = function(src) { 36 | src ? this.setAll("src","media/audio/"+src+".mp3") : false; 37 | this.all("play"); 38 | return this; 39 | } 40 | 41 | /** 42 | * Play audio file 43 | * @param {float} rate Playback rate of audio file (0.25 - 4). DOES NOT CHANGE PITCH. 44 | */ 45 | Cassette.prototype.play = function(rate) { 46 | this.rate = rate ? rate : this.rate; 47 | this.all("play") 48 | this.speed(this.rate) 49 | return this 50 | } 51 | 52 | /** 53 | * Pause audio playback 54 | */ 55 | Cassette.prototype.stop = function() { 56 | this.all("pause") 57 | return this 58 | } 59 | 60 | /** 61 | * Mute all players except for the player in window 1. This is useful if .skip() is causing too many pops and clicks (a pop for each of 4 players). 62 | */ 63 | Cassette.prototype.solo = function() { 64 | for (var i=1;i 99) { 142 | callback = callback ? callback : function() { } 143 | var obj = { 144 | x: this.element.screenX, 145 | y: this.element.screenY, 146 | } 147 | $(obj).animate({x: x, y: y}, { 148 | duration: time, 149 | easing: "linear", 150 | step: function() { 151 | this.element.moveTo(obj.x,obj.y) 152 | }.bind(this) 153 | // complete: callback 154 | }) 155 | } else { 156 | this.element.moveTo(x,y) 157 | } 158 | this.x = x; 159 | this.y = y; 160 | if (this.autoscroll) { 161 | this.xray(); 162 | } 163 | 164 | } 165 | 166 | /** 167 | * Resize the window 168 | */ 169 | Window.prototype.size = function(w,h,time) { 170 | if (time && time > 99) { 171 | callback = callback ? callback : function() { } 172 | var obj = { 173 | w: this.element.outerWidth, 174 | h: this.element.outerHeight, 175 | } 176 | $(obj).animate({w: w, h: h}, { 177 | duration: time, 178 | easing: "linear", 179 | step: function() { 180 | this.element.resizeTo(obj.w,obj.h) 181 | }.bind(this), 182 | complete: callback 183 | }) 184 | } else { 185 | this.element.resizeTo(w,h) 186 | } 187 | this.w = w; 188 | this.h = h; 189 | 190 | } 191 | -------------------------------------------------------------------------------- /lib/media/paper.js: -------------------------------------------------------------------------------- 1 | var util = require('util'); 2 | var Medium = require('../core/medium') 3 | 4 | /** 5 | * @class Paper 6 | * @constructor 7 | * @description Performative TEXT media element 8 | * @extends Medium 9 | * @param {object} Params (see Params) 10 | * @return {Paper} 11 | */ 12 | var Paper = module.exports = function(params) { 13 | 14 | this.defaultSize = { w: 300 } 15 | this.type = "div"; 16 | 17 | //separate item constructor "Medium" with properties for placement, animation, remove, make dom element, styling element based on json 18 | Medium.call(this, params); 19 | 20 | this.flipSpace = 0 21 | this.flipWord = 0 22 | this.time = 100; 23 | this.washWord = 0 24 | this.mode = "default" 25 | 26 | for (var i=0;i=this.spaces.length) { 133 | this.flipSpace=0; 134 | } 135 | this.flipWord++; 136 | if (this.flipWord>=this.words.length) { 137 | this.flipWord=0; 138 | } 139 | return this 140 | } 141 | 142 | /** 143 | * Strobes the text in all windows at once (use with interval) 144 | */ 145 | Paper.prototype.flash = function() { 146 | if (this.mode != "flash") { 147 | this.mode = "flash" 148 | for (var i=0;i=this.words.length) { 177 | this.washWord = 0; 178 | } 179 | return this 180 | } 181 | 182 | 183 | -------------------------------------------------------------------------------- /lib/media/map.js: -------------------------------------------------------------------------------- 1 | var util = require('util'); 2 | var Medium = require('../core/medium') 3 | 4 | /** 5 | * @class Map 6 | * @constructor 7 | * @description Performative GOOGLE MAP media element 8 | * @extends Medium 9 | * @param {object} Params (see Params) 10 | * @return {Paper} 11 | */ 12 | var Map = module.exports = function(params) { 13 | 14 | this.defaultSize = { w: m.stage.w, h: m.stage.h } 15 | this.type = "div"; 16 | 17 | //separate item constructor "Medium" with properties for placement, animation, remove, make dom element, styling element based on json 18 | Medium.call(this, params); 19 | 20 | this.map = [] 21 | this.directionsDisplay = [] 22 | 23 | /* create map */ 24 | var mapOptions = { 25 | zoom: 8, 26 | center: new google.maps.LatLng(0, 0), 27 | disableDefaultUI: true 28 | }; 29 | 30 | for (var i=0;i 0) { 119 | if (routes[arguments[0]]) { 120 | arguments = routes[arguments[0]] 121 | } 122 | 123 | start = arguments[0] 124 | end = arguments[arguments.length-1] 125 | 126 | var request = { 127 | origin:start, 128 | destination:end, 129 | travelMode: google.maps.TravelMode.DRIVING 130 | }; 131 | 132 | if (arguments.length > 2) { 133 | var waypoints = [] 134 | for (var i=1;i888'; 196 | 197 | for (var i=0;i