├── .eslintignore ├── README.md ├── sketches ├── starfield │ ├── sketch.js │ ├── star.js │ └── field.js ├── noise │ └── noise.js ├── dotwave.js └── waves │ ├── waves.js │ └── FlowField.js ├── p5experiments.sublime-project ├── .gitignore ├── index.html ├── LICENSE └── package.json /.eslintignore: -------------------------------------------------------------------------------- 1 | lib/* 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # p5-live 2 | Live Coding for p5.js 3 | -------------------------------------------------------------------------------- /sketches/starfield/sketch.js: -------------------------------------------------------------------------------- 1 | const size = 800; 2 | let field; 3 | 4 | function setup() { 5 | createCanvas(size, size); 6 | background(0); 7 | field = new Field(200); 8 | } 9 | 10 | function draw() { 11 | background(0); 12 | // fill(0, 10); 13 | // rect(0, 0, width, height); 14 | field.draw(); 15 | } 16 | -------------------------------------------------------------------------------- /p5experiments.sublime-project: -------------------------------------------------------------------------------- 1 | { 2 | "folders": 3 | [ 4 | { 5 | "file_exclude_patterns": 6 | [ 7 | "*.sublime-workspace" 8 | ], 9 | "folder_exclude_patterns": 10 | [ 11 | ], 12 | "path": "." 13 | } 14 | ], 15 | "settings": 16 | { 17 | "FuzzyFilePath": 18 | { 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sketches/noise/noise.js: -------------------------------------------------------------------------------- 1 | function setup() { 2 | createCanvas(400, 400); 3 | } 4 | 5 | function draw() { 6 | const increment = 0.01; 7 | // noiseDetail(8, 0.65); 8 | loadPixels(); 9 | let xoff = frameCount * 0.5; 10 | for (let x = 0; x < width; x++) { 11 | xoff += increment; 12 | let yoff = 0; 13 | for (let y = 0; y < height; y++) { 14 | yoff += increment; 15 | const bright = noise(xoff, yoff) * 255; 16 | set(x, y, color(bright)); 17 | } 18 | } 19 | updatePixels(); 20 | } 21 | -------------------------------------------------------------------------------- /sketches/starfield/star.js: -------------------------------------------------------------------------------- 1 | const rand = n => randomGaussian() * n - n / 2; 2 | class Star { 3 | constructor(x = random(width), y = random(height), vx = rand(2), vy = rand(2)) { 4 | this.pos = new p5.Vector(x, y); 5 | this.speed = new p5.Vector(vx, vy); 6 | } 7 | draw() { 8 | stroke(200); 9 | point(this.pos.x, this.pos.y); 10 | this.update(); 11 | } 12 | update() { 13 | this.pos.add(this.speed); 14 | this.pos.x = (this.pos.x + width) % width; 15 | this.pos.y = (this.pos.y + height) % height; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 18 | .grunt 19 | 20 | # node-waf configuration 21 | .lock-wscript 22 | 23 | # Compiled binary addons (http://nodejs.org/api/addons.html) 24 | build/Release 25 | 26 | # Dependency directory 27 | node_modules 28 | 29 | # Optional npm cache directory 30 | .npm 31 | 32 | # Optional REPL history 33 | .node_repl_history 34 | 35 | # Sublime 36 | *.sublime-workspace 37 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Yang Su 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /sketches/starfield/field.js: -------------------------------------------------------------------------------- 1 | const THRESHOLD = 100; 2 | const ring = (stars, r, m) => { 3 | const cx = width / 2; 4 | const cy = height / 2; 5 | for (let i = 0, step = TWO_PI / m; i <= TWO_PI; i += step) { 6 | stars.push(new Star(cos(i) * r + cx, sin(i) * r + cy, 0, 0)); 7 | } 8 | }; 9 | 10 | class Field { 11 | constructor(n, m = 12) { 12 | this.stars = []; 13 | ring(this.stars, 50, 6); 14 | ring(this.stars, 100, 8); 15 | ring(this.stars, 150, 12); 16 | for (let i = 0; i < n; i++) { 17 | this.stars.push(new Star()); 18 | } 19 | } 20 | draw() { 21 | this.stars.forEach(star => { 22 | star.draw(); 23 | this.stars.forEach(otherStar => { 24 | if (star !== otherStar) { 25 | const d = star.pos.dist(otherStar.pos); 26 | if (d <= THRESHOLD) { 27 | const color = map(d, 0, THRESHOLD, 200, 0); 28 | const width = map(d, 0, THRESHOLD, 3, 0); 29 | strokeWeight(width); 30 | stroke(50, 150, 255, color); 31 | line(star.pos.x, star.pos.y, otherStar.pos.x, otherStar.pos.y); 32 | } 33 | } 34 | }); 35 | }); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /sketches/dotwave.js: -------------------------------------------------------------------------------- 1 | const xspacing = 16; // Distance between each horizontal location 2 | let theta = 0.0; // Start angle at 0 3 | const amplitude = 10.0; // Height of wave 4 | const period = 20.0; // How many pixels before the wave repeats 5 | let w; // Width of entire wave 6 | let dx; // Value for incrementing x 7 | let yvalues; // Using an array to store height values for the wave 8 | 9 | function setup() { 10 | createCanvas(800, 400); 11 | w = width + 8; 12 | dx = (TWO_PI / period) * xspacing; 13 | yvalues = new Array(floor(w / xspacing)); 14 | } 15 | 16 | function draw() { 17 | background(10); 18 | calcWave(); 19 | renderWave(); 20 | } 21 | 22 | function calcWave() { 23 | // Increment theta (try different values for 24 | // 'angular velocity' here 25 | theta += 0.5; 26 | 27 | // For every x value, calculate a y value with sine function 28 | let x = theta; 29 | for (let i = 0; i < yvalues.length; i++) { 30 | yvalues[i] = sin(x) * amplitude; 31 | x += dx; 32 | } 33 | } 34 | 35 | function renderWave() { 36 | noStroke(); 37 | fill(250); 38 | // A simple way to draw the wave with an ellipse at each location 39 | for (let x = 0; x < yvalues.length; x++) { 40 | ellipse(x * xspacing, height / 2 + yvalues[x], 16, 16); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "start": "NODE_DEBUG=amok,amok-compiler amok --compiler babel --browser chrome --hot sketches/*" 5 | }, 6 | "dependencies": { 7 | "acorn": "^3.0.4", 8 | "escodegen": "^1.8.0", 9 | "p5": "^0.4.23" 10 | }, 11 | "eslintConfig": { 12 | "extends": [ 13 | "airbnb", 14 | "p5js" 15 | ], 16 | "globals": { 17 | "p5": true, 18 | "acorn": true, 19 | "escodegen": true, 20 | "sketch": true 21 | }, 22 | "rules": { 23 | "new-cap": 0, 24 | "no-eval": 0, 25 | "vars-on-top": 0, 26 | "func-names": 0, 27 | "space-before-function-paren": [ 28 | 1, 29 | "never" 30 | ], 31 | "no-param-reassign": [ 32 | 2, 33 | { 34 | "props": false 35 | } 36 | ], 37 | "no-unused-vars": [ 38 | 2, 39 | { 40 | "varsIgnorePattern": "setup|draw|mouseMoved" 41 | } 42 | ], 43 | "no-use-before-define": 0 44 | }, 45 | "ignores": [ 46 | "lib/*" 47 | ] 48 | }, 49 | "devDependencies": { 50 | "babel-core": "^6.7.4", 51 | "babel-loader": "^6.2.4", 52 | "babel-preset-es2015": "^6.6.0", 53 | "eslint": "^2.5.1", 54 | "eslint-config-airbnb": "^6.2.0", 55 | "eslint-config-p5js": "^1.0.0", 56 | "eslint-plugin-react": "^4.2.3" 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /sketches/waves/waves.js: -------------------------------------------------------------------------------- 1 | const size = 800; 2 | const fieldDensity = 40; 3 | const noiseMultiplier = 0.05; 4 | let field; 5 | let maxDist; 6 | let maxArrowSize; 7 | let x = 0; 8 | let y = 0; 9 | 10 | function setup() { 11 | createCanvas(size, size); 12 | field = new FlowField(fieldDensity, fieldDensity, (i, j) => { 13 | const theta = map(noise(i * noiseMultiplier, j * noiseMultiplier), 0, 1, 0, TWO_PI); 14 | return new p5.Vector(cos(theta), sin(theta)); 15 | }); 16 | maxDist = pow(dist(0, 0, width, height) / 2, 2); 17 | const cellSize = size / fieldDensity; 18 | maxArrowSize = dist(0, 0, cellSize, cellSize) / 2; 19 | background(0); 20 | } 21 | 22 | function draw() { 23 | // noiseDetail(3, 0.45); 24 | background(0); 25 | // fill(0, 10); 26 | // rect(0, 0, width, height); 27 | x += map(noise(frameCount * 0.05), 0, 1, -2, 2); 28 | y += map(noise(frameCount * 0.05 + 10000), 0, 1, -2, 2); 29 | field.update((direction, position, i, j) => { 30 | const theta = map(noise((i + x * 2) * noiseMultiplier, (j + y * 2) * noiseMultiplier), 0, 1, 0, TWO_PI); 31 | direction.set(cos(theta), sin(theta)); 32 | }); 33 | field.draw(); 34 | } 35 | 36 | // function mouseMoved() { 37 | // const mouse = new p5.Vector(mouseX, mouseY); 38 | // if (mouse.magSq() > 0) { 39 | // field.update((direction, position) => { 40 | // const newDirection = p5.Vector.sub(mouse, position); 41 | // const mag = newDirection.magSq(); 42 | // newDirection 43 | // .normalize() 44 | // .mult(map(mag, 0, maxDist, 0, maxArrowSize)); 45 | // direction.set(newDirection); 46 | // }); 47 | // } 48 | // } 49 | -------------------------------------------------------------------------------- /sketches/waves/FlowField.js: -------------------------------------------------------------------------------- 1 | class FlowField { 2 | constructor(rows, columns, initializer) { 3 | this.rows = rows; 4 | this.columns = columns; 5 | this.rowSize = width / rows; 6 | this.colSize = height / columns; 7 | this.arrowSize = min(this.rowSize, this.colSize); 8 | this.field = []; 9 | for (let i = 0; i < rows; i++) { 10 | const row = []; 11 | for (let j = 0; j < columns; j++) { 12 | row.push(initializer(i, j)); 13 | } 14 | this.field.push(row); 15 | } 16 | } 17 | 18 | update(iterator) { 19 | this.field.forEach((row, i) => { 20 | row.forEach((direction, j) => { 21 | const startX = (i + 0.5) * this.rowSize; 22 | const startY = (j + 0.5) * this.colSize; 23 | const position = new p5.Vector(startX, startY); 24 | iterator(direction, position, i, j); 25 | }); 26 | }); 27 | } 28 | 29 | draw() { 30 | stroke(155); 31 | this.update((direction, position, i, j) => { 32 | const diff = direction.copy().setMag(this.arrowSize).div(2); 33 | const start = p5.Vector.sub(position, diff); 34 | // const start = position; 35 | const end = p5.Vector.add(position, diff); 36 | // strokeWeight(1); 37 | // console.log(diff.mag()); 38 | // const gray = map(diff.magSq(), 0, maxArrowSize / 2, 50, 255); 39 | const gray = map(p5.Vector.angleBetween(direction, new p5.Vector(1, 0)), 0, PI, 0, 255); 40 | stroke(gray); 41 | line(start.x, start.y, end.x, end.y); 42 | // fill(gray); 43 | // const startX = i * this.rowSize; 44 | // const startY = j * this.colSize; 45 | // rect(startX, startY, startX + this.rowSize, startY + this.colSize); 46 | // strokeWeight(3); 47 | // stroke(0, 0, 255); 48 | // point(start.x, start.y); 49 | // stroke(0, 255, 0, gray); 50 | // point(end.x, end.y); 51 | }); 52 | } 53 | } 54 | --------------------------------------------------------------------------------