Tuesday, September 26, 2017

p5 editor to programmatically make a downloadable image in the browser

QUICK HACK: I have a lot of decent art programs for my iPad, but it seems like like such programs no longer come with tools for making simple shapes, like circles and squares. That made my inner child a little sad! Paint programs used to be fun, you know? Like just tooling around throwing shapes and patterns on the screen...

It's tough enough to find programs with flood fill, actually.... it seems like almost every art program is either imitating "real" art tools, aimed at photo retouching, or tries to get you to think in their weird interface for vectors.

Anyway, I wanted a colored circle as a base for a Jack-O-Lantern tuba cover I'm making, and the easiest way was to go to the online p5 editor and enter the following:

function setup() { 
  createCanvas(3000, 3000);
noSmooth();


function draw() { 
  background(255);
noStroke();
fill(255,140,0);
ellipse(1500,1500,2500,2500);
saveCanvas("art.png");
noLoop();
}

That actually generates a file "art.png" which the browser will offer to download.
I then used Dropbox to transfer it to my iPad.

UPDATE:  Did a bit more work...

So, I'm making up designs for tuba covers (as printed by the fine folks at http://stretchablecovers.net/) Before I mentioned the first step for a Jack-O-Lantern (drawn in by hand)

But a few years ago I had a DIY craft project (felt crudely stapled onto the blank side of a cover) skull for my tuba:


I lost it in my recent move, and decided I'd get it printed up, and that I'd use another p5.js program to do it. (I liked the idea of using shapes rather than being quite hand drawn).

Net, net, you can see and play with the p5.js program here. The moderately clever bit is using a technique to let me finesse the placement of a piece via "map()"ing the X and Y mouse position to appropriate values, and then building a string for the corresponding ellipse() or line() command. I then both print the screen and run javascript's "eval()" on it. Once I get the fragement where I like it, I copy and paste the printed version of the statement and place it into the code, so it's kind of baked into the place and then I repeat the technique for the next fragment.


Oh, also for funsies check out my old Carve Your Own Jack-O-Lantern Processing Program... very similar in spirit to all this.

For reference (since I guess I shouldn't an  account on a "alpha version" editor as a code repository) here is the code... it's not (quite) as hackish as it looks.

var BASE;
var s;
function setup() { 
  BASE = 30;// random(38,58);
  createCanvas(BASE*10, BASE*10);
strokeCap(SQUARE);


function draw() { 
  //BASE += random(-.1,.1);
  background(200);
noStroke();
translate(width/2,height/2);
fill(255);
ellipse(0,0,BASE*8,BASE*8);
fill(0);
push();
  var f1 = map(mouseX,0,width, -5,5).toFixed(3);;
  var f2 = map(mouseY,0,height, -5,5).toFixed(3);
  var s;
//var s = "bigEye("+f1+","+f2+");";
  s = "bigEye(1.835,-1.239);";
  eval(s);
  s = "nose(-1.867,0.824)";
  eval(s);
  
  //s = "smallEye("+f1+","+f2+")";
  s = "smallEye(-2.037,-0.947)";
  eval(s);
  
  s = "mouth()";
  eval(s);
  
  s = "crack("+f1+","+(f2)+");"
  eval(s);


}

function mousePressed(){
  noLoop(); 
}

function crack(a,b){
    strokeWeight(BASE/5);
  stroke(0);
  noFill();
  push();
 // print (a+":"+b);
  translate(BASE*.137,BASE*.44);
beginShape();
  push();
 vertex(BASE*-3.392,BASE*-4.471);
vertex(BASE*-1.704,BASE*-3.673);
vertex(BASE*-1.367,BASE*-3.895);
vertex(BASE*-1.316,BASE*-3.14);
vertex(BASE*-0.497,BASE*-3.36);
  vertex(BASE*0.084,BASE*-2.65);
//vertex(BASE*-0.894,BASE*-2.657);
vertex(BASE*-0.497,BASE*-3.36);
  vertex(BASE*0.143,BASE*-3.791);

  s = "vertex(BASE*"+a+",BASE*"+b+");";
 // eval(s);
 // print(s);
  endShape();
  pop();
  
  
    noLoop(); 
 saveCanvas("skull.png");

}


function mouth(){
  strokeWeight(BASE/2.8);
  stroke(0);
  line(-BASE*4,BASE*2,BASE*4,BASE*2);
  
  line(0,BASE*1.35,0,BASE*2.65);
  line(-BASE,BASE*1.45,-BASE,BASE*2.55);
  line(-2*BASE,BASE*1.4,-2*BASE,BASE*2.55);
  line(BASE,BASE*1.45,BASE,BASE*2.65);
  line(2*BASE,BASE*1.45,2*BASE,BASE*2.55);
}



function nose(a,b){
  push();
  push();
  rotate(a);
  ellipse(0,BASE/4,BASE*2,BASE);
  pop();
  push();
  rotate(-a);
  ellipse(0,+BASE/4,BASE*2,BASE);
  pop();
}

function bigEye(f1,f2){
  var g = 2.5;
  push();
  translate(f1* BASE,f2*BASE);
rotate(0.1);
  ellipse(0,0,BASE*g,BASE*g*1.3);
pop();
}

function smallEye(f1,f2){
  var g = 2.2;
  push();
  translate(f1* BASE,f2*BASE);
rotate(0.1);
  ellipse(0,0,BASE*g*1.1,BASE*g);
pop();
}

1 comment: