An interesting drawing board made with Processing

This is an interesting drawing board written with processing, a gadget I made with my roommate.

The function introduction of the sketchpad is shown in the figure below. insert image description here
Detailed introduction of the menu bar:
Save/Save As: You can open the local folder selector, the default storage format is jpg, if the user specifies the format, the image will be stored in the format specified by the user. After the save button has been used once, clicking it again will not open the folder selector, but save to the previously filled storage location.
Background color: The color mode of the drawing board is HSB mode, the background color selection area is a 120x100 rectangular area, and the drawing area will be cleared when the background color is clicked.
Brush color: the same as the background color, except that clicking on the brush color will not clear the painting area.
Graphic selection: The sketchpad is relatively simple, with fewer graphics, only lines, random circles, moving circles, rectangles, rounded rectangles, center symmetry, flowers (pictures), flowers (graphics).

The main interface of the drawing board is shown in the figure:
insert image description here
insert image description here
the following is the code of the drawing board, which consists of four tags, three of which are class.
DrawPanel_mainfile:

String pic_name="line";          //用于记录图形
PFont font;                //字体
int strokeSize=1;        //用于记录描边粗细
color strokeColor;    //用于记录描边颜色
color backColor;  //用于记录绘画区域的背景颜色
int key_d_=0;      //用于记录帮助是否打开
String filename;    //用于记录之前保存的文件名
//以下四个变量用于画矩形
float x1,x2,y1,y2;      //用于记录按钮按下和松开时的坐标
int j1=0;      //用于记录是否有鼠标按下的坐标
int j2=0;      //用于记录是否有鼠标松开的坐标
int d_;        //用于矩形记录鼠标是否按下
//移动圆所需变量
int move_circle_d=0;        //用于移动圆记录鼠标是否按下
//圆角矩形所需变量
float rcx1,rcx2,rcy1,rcy2;      
int rcj1=0;      
int rcj2=0;      
int rcd_;  
//中心对称所需变量
float csx,csy;
int csj=0;
int csd_;
int line_count=6;      //该整数用于记录当前中心对称所产生的线条数
//花朵所需变量
float flowerSize=50;  //定义一个全局变量用于增加花朵大小
//可填充颜色的花朵所需变量
PShape s;    //创建一个图形对象用来存储花朵的形状
float jiaodu;    //用来画花朵弧形的函数
float size=0;    //用来记录花朵的大小
color colora=color(random(0,120),random(0,120),random(0,100));    //记录花朵的随机颜色
//按钮图标
PImage[] img=new PImage[13];
MoveCircle[] mcs=new MoveCircle[0];
void setup(){
  background(255);
  colorMode(HSB, 100);    //设置颜色模式为HSB模式
  backColor=color(0,0,120);      
  fill(backColor);
  rect(-1,121,1001,680);
  size(1000,800);
  font=createFont("KaiTi-48.vlw",30);    //创建字体为楷体
  textFont(font);        //将楷体设置为默认字体
  textSize(30);
  frameRate(30);
  for(int i=0;i<13;i++){
    img[i]=loadImage(i+".png");
  }
  //创建图形(花朵)
  s=createShape();
  s.beginShape();
  s.fill(0);
  s.noStroke();
  for(int i=-40;i<=40;i++){
   s.vertex(i,-i*i/10*0.6); 
  }
  for(int i=40;i>=-40;i--){
   jiaodu=map(i,40,-40,30,150);
   s.vertex(i,-112-40*(sin(radians(jiaodu))-0.5));
  }
  s.endShape();
  //分割线......
  fill(0);
  line(0,120,1000,120);
  line(210,0,210,120);
  line(210,60,500,60);
  line(500,0,500,120);
  line(750,0,750,120);
  line(610,0,610,120);
  line(860,0,860,120);
  image(img[1],110,15,90,90);   //另存为
  image(img[2],220,5,50,50);    //线条
  image(img[3],275,5,50,50);    //随机圆
  image(img[4],330,5,50,50);    //移动圆
  image(img[5],385,5,50,50);    //矩形
  image(img[6],440,5,50,50);    //圆角矩形
  image(img[7],220,65,50,50);   //中心对称
  image(img[8],275,65,50,50);   //花朵
  image(img[9],330,65,50,50);    //可填充颜色的花朵
  image(img[10],510,10,90,90);   //背景颜色
  image(img[11],760,10,90,90);  //画笔颜色 
  //提示帮助的文字
  noFill();
  rect(385,60,105,60);
  text("帮助(H)",385,100);
  //初始的描边颜色
  strokeColor=color(0,0,0);
  //通过画point来产生一块区域表示颜色选择区域
  for (int i = 0; i < 120; i++) {
    for (int j = 0; j < 100; j++) {
      stroke(i, j, 120);
      point(620+i, 10+j);
    }
  }
  for (int i = 0; i < 120; i++) {
    for (int j = 0; j < 100; j++) {
      stroke(i, j, 120);
      point(870+i, 10+j);
    }
  }
}
void draw(){
  //之所以把保存按钮放在draw()函数里是为了消除一个移动圆带来的bug,通过重新产生一个矩形和保存按钮,
  //来清除移动圆在(0,0)位置产生的痕迹
  fill(0,0,120);
  noStroke();
  rect(0,0,52,52);
  image(img[0],10,15,90,90);    //保存
  ShapeType st=new ShapeType(pic_name);    //创建图形对象
  st.drawShape();     //调用画图函数
  mouseStyle();
}
void mouseReleased()  {
//当点击按钮时,改变pic_name,并修改按钮颜色
  if(mouseX>220&&mouseX<270&&mouseY>5&&mouseY<55){
    pic_name="line";              //线条
  }else if(mouseX>275&&mouseX<325&&mouseY>5&&mouseY<55){
    pic_name="random_circle";      //随机圆
  }else if(mouseX>330&&mouseX<380&&mouseY>5&&mouseY<55){
   pic_name="move_circle";        //移动圆
  }else if(mouseX>385&&mouseX<435&&mouseY>5&&mouseY<55){
   pic_name="rect";              //矩形
  }else if(mouseX>440&&mouseX<490&&mouseY>5&&mouseY<55){
   pic_name="radius_rect";      //圆角矩形
  }else if(mouseX>220&&mouseX<270&&mouseY>65&&mouseY<115){
   pic_name="center_shape";     //中心对称
  }else if(mouseX>275&&mouseX<325&&mouseY>65&&mouseY<115){
   pic_name="flower";           //花朵图片
  }else if(mouseX>330&&mouseX<380&&mouseY>65&&mouseY<115){
   pic_name="color_flower";       //可填充颜色的花朵
  }
  else if(mouseX>870&&mouseX<990&&mouseY>10&&mouseY<110){
    strokeColor=color(mouseX-870,mouseY-10,120);      //画笔颜色
  }else if(mouseX>620&&mouseX<740&&mouseY>10&&mouseY<110&&key_d_==0){      //背景颜色
   backColor=color(mouseX-620,mouseY-10,120); 
   fill(backColor);
   noStroke();
   rect(-1,121,1001,680); 
   mcs=new MoveCircle[0];    //需要清空储存移动圆的数组
  }else if(mouseX>385&&mouseX<490&&mouseY>60&&mouseY<120){
   openHelp();              //调用打开帮助函数 
  }else if(mouseX>120&&mouseX<210&&mouseY>15&&mouseY<105){
    selectOutput("请选择一个文件夹:","selectFile");        //另存为
  }else if(mouseX>10&&mouseX<100&&mouseY>15&&mouseY<105){
    if(filename==null){
      selectOutput("请选择一个文件夹:","selectFile_");      //保存
    }else{
      save(filename); 
    }
  }
}
//另存为调用的函数
void selectFile(File selection){
  if(selection==null){
  }else{    
    if(selection.getAbsolutePath().indexOf(".")>0){  //若用户再文件名处写了后缀
      save(selection.getAbsolutePath());       //以用户规定的格式保存
    }else{
      save(selection.getAbsolutePath()+".jpg");  //默认保存为jpg格式
    }
  }
}
//保存调用的函数,之所以保存与另存为要分开写,是为了filename的正确存储,另存为按钮并不会filename传值
//这样点击另存为之后,再点保存按钮,不会保存到另存为设置的文件路径。这样filename就只能存储保存按钮
//输入的文件存储路径了
void selectFile_(File selection){
  if(selection==null){
  }else{    
    if(selection.getAbsolutePath().indexOf(".")>0){   //若用户再文件名处写了后缀
      save(selection.getAbsolutePath());       //以用户规定的格式保存
      filename=selection.getAbsolutePath();      //将文件名保存下来
    }else{
      save(selection.getAbsolutePath()+".jpg");    //默认保存为jpg格式
      filename=selection.getAbsolutePath()+".jpg";      //将文件名保存下来
    }
  }
}
//键盘监听函数
void keyReleased(){
  char k=key;
  switch(k){
    case 'c':
      fill(backColor);
      noStroke();
      rect(-1,121,1001,680); 
      mcs=new MoveCircle[0];
      break;
    case 'C':
      fill(backColor);
      noStroke();
      rect(-1,121,1001,680); 
      mcs=new MoveCircle[0];
      break;
    case 'h':
      openHelp();    //调用打开帮助的函数
      break;
    case 'H':
      openHelp();
      break;
    case '0':
      strokeSize=0;
      break;
    case '1':
      strokeSize=1;
      break;
    case '2':
      strokeSize=2;
      break;
    case '3':
      strokeSize=3;
      break;
    case '4':
      strokeSize=4;
      break;
    case '5':
      strokeSize=5;
      break;
    case '6':
      strokeSize=6;
      break;
    case '7':
      strokeSize=7;
      break;
    case '8':
      strokeSize=8;
      break;
    case '9':
      strokeSize=9;
      break;
    case 'w':
      line_count+=1;
      break;
    case 's':
      line_count-=1;
      break;
  }
}
//打开、关闭帮助的函数
void openHelp(){
  if(key_d_==0){
        //先用矩形覆盖背景颜色的区域,然后将帮助图片加载上去
        noStroke();
        fill(0,0,120);
        rect(510,0,230,120);
        image(img[12],510,10,230,100);
        key_d_=1; 
      }else{
        //同理用矩形覆盖帮助图片区域,再讲背景颜色的区域重新绘制一边
        noStroke();
        fill(0,0,120);
        rect(510,10,230,110);
        stroke(0,0,0);
        strokeWeight(1);
        line(610,0,610,120);
        for (int i = 0; i < 120; i++) {
          for (int j = 0; j < 100; j++) {
            stroke(i, j, 120);
            point(620+i, 10+j);
          }
        }
        image(img[10],510,10,90,90);    
        key_d_=0; 
      }
}
//监听鼠标样式的函数
void mouseStyle(){
  if(mouseX>220&&mouseX<270&&mouseY>5&&mouseY<55){
    cursor(HAND);
  }else if(mouseX>275&&mouseX<325&&mouseY>5&&mouseY<55){
    cursor(HAND);
  }else if(mouseX>330&&mouseX<380&&mouseY>5&&mouseY<55){
   cursor(HAND);
  }else if(mouseX>385&&mouseX<435&&mouseY>5&&mouseY<55){
   cursor(HAND);
  }else if(mouseX>440&&mouseX<490&&mouseY>5&&mouseY<55){
   cursor(HAND);
  }else if(mouseX>220&&mouseX<270&&mouseY>65&&mouseY<115){
   cursor(HAND);
  }else if(mouseX>275&&mouseX<325&&mouseY>65&&mouseY<115){
   cursor(HAND);
  }else if(mouseX>330&&mouseX<380&&mouseY>65&&mouseY<115){
   cursor(HAND);
  }else if(mouseX>870&&mouseX<990&&mouseY>10&&mouseY<110){
    cursor(CROSS);
  }else if(mouseX>620&&mouseX<740&&mouseY>10&&mouseY<110&&key_d_==0){      
   cursor(CROSS);
  }else if(mouseX>385&&mouseX<490&&mouseY>60&&mouseY<120){
   cursor(HAND); 
  }else if(mouseX>120&&mouseX<210&&mouseY>15&&mouseY<105){
    cursor(HAND);
  }else if(mouseX>10&&mouseX<100&&mouseY>15&&mouseY<105){
    cursor(HAND);
  }else{
   cursor(ARROW); 
  }
}

ShapeType_class:

class ShapeType{
  String shape_name;
  
  //有参构造函数,获取代表形状的参数shape_name
  ShapeType(String pic_name){
    shape_name=pic_name;
  }
  
  //绘画函数,根据shapename来判断需要画什么图形
  public void drawShape(){
    //当图形为线条时
    if(shape_name=="line"){
      frameRate(300);
      strokeWeight(strokeSize);
      stroke(strokeColor);
      if(mousePressed&&mouseY>140){
        line(mouseX,mouseY,pmouseX,pmouseY);
      }
    }
    
    //当图形为随机圆时
    if(shape_name=="random_circle"){
      frameRate(8);                  //修改帧速率,防止图形产生过快覆盖了原图形
      noStroke();
      if(mousePressed&&(mouseButton==LEFT)&&mouseY>140){
        int r=(int)random(25,45);    //随机产生圆半径
        int R=(int)random(0,255);    //随机red值
        int G=(int)random(0,255);    //随机green值
        int B=(int)random(0,255);    //随机blue值
        int A=(int)random(0,255);    //随机透明度
        fill(R,G,B,A);
        ellipse(mouseX,mouseY,r,r);
      }
    }
    
    //当图形为移动圆形时
    if(shape_name=="move_circle"){
      frameRate(50);
      noStroke();    //去掉描边
      if(mouseY>140){
        if(mousePressed){
          move_circle_d=1;
        }else{
          if(move_circle_d==1){
             MoveCircle mc=new MoveCircle(mouseX,mouseY,strokeColor,strokeSize);
             mcs=(MoveCircle[])append(mcs,mc);    //用append函数添加新元素到对象数组中
          }
          move_circle_d=0;
        }
      }
      for(int i=0;i<mcs.length;i++){
         mcs[i].move();       //遍历对象数组,依次移动数组中的圆
      }
    }
    
    //当图形为矩形时
    if(shape_name=="rect"){   
      frameRate(30);
      noStroke();
      if(mouseY>140){
      if(mousePressed){
          d_=1;
          j2=0;
          if (j1==0) //按下鼠标时记录此时的鼠标坐标
          {
            j1=1;
            x1=mouseX;
            y1=mouseY;
          }    
        }else{
          if (d_==1) {
            fill(strokeColor);
            j1=0;
            if (j2==0) //松开鼠标时记录此时的鼠标坐标
            {
              j2=1;
              x2=mouseX;
              y2=mouseY;
            }
            quad(x1, y1, x1, y2, x2, y2, x2, y1);    //只需在松开鼠标时绘画,用四边形,不能用矩形
            d_=0;
          }
        } 
      } 
    }
    
    //当图形为圆角矩形时
    if(shape_name=="radius_rect"){
      frameRate(100);
      strokeWeight(strokeSize);
      stroke(strokeColor);
      if(mouseY>140){
      if(mousePressed){
          rcd_=1;
          rcj2=0;
          if (rcj1==0) //按下鼠标时记录此时的鼠标坐标
          {
            rcj1=1;
            rcx1=mouseX;
            rcy1=mouseY;
          }
        }else{
          if (rcd_==1) {
            fill(255);
            rcj1=0;
            if (rcj2==0) //松开鼠标时记录此时的鼠标坐标
            {
              rcj2=1;
              rcx2=mouseX;
              rcy2=mouseY;
            }
            //quad(rcx1, rcy1, rcx1, rcy2, rcx2, rcy2, rcx2, rcy1);
            float rcr=min(abs(rcx1-rcx2),abs(rcy1-rcy2))/3.0;    //圆角半径
            float rct;    //用于交换坐标值时作为中间量
            //交换角点值,使得rcx1,rcy1为左上角的坐标,rcx2,rcy2为右下角坐标
            if(rcx1>rcx2){
             rct=rcx1;rcx1=rcx2;rcx2=rct;
            }
            if(rcy1>rcy2){
             rct=rcy1;rcy1=rcy2;rcy2=rct; 
            }
            fill(strokeColor);
            arc(rcx1+rcr/2,rcy1+rcr/2,rcr,rcr,PI,PI+HALF_PI);
            arc(rcx2-rcr/2,rcy1+rcr/2,rcr,rcr,PI+HALF_PI,TWO_PI);
            arc(rcx2-rcr/2,rcy2-rcr/2,rcr,rcr,0,HALF_PI);
            arc(rcx1+rcr/2,rcy2-rcr/2,rcr,rcr,HALF_PI,PI);
            rect(rcx1,rcy1+rcr/2,rcx2-rcx1,rcy2-rcr-rcy1);
            rect(rcx1+rcr/2,rcy1,rcx2-rcr-rcx1,rcy2-rcy1);
            rcd_=0;
          }
        } 
      } 
    }
    
    //当图形为中心对称图形时
    if(shape_name=="center_shape"){
      frameRate(300);
      strokeWeight(strokeSize);
      stroke(strokeColor);
      if(mouseY>140){
        if(mousePressed){
          csd_=1;
          if(csj==0){
            csj=1;
            csx=mouseX;
            csy=mouseY;
          }
          translate(csx,csy);           //移动坐标系
          if(dist(mouseX-csx,mouseY-csy,0,0)<(csy-140)){    //约束中心对称的大小,避免画到工具栏上面
            for(int i=0;i<line_count;i++){  
                line(mouseX-csx,mouseY-csy,pmouseX-csx,pmouseY-csy);          
                rotate(TWO_PI/line_count);                      //旋转坐标系
              }
            }
        }else{
          if(csd_==1){
            csj=0;
          }
          csd_=0;
        }
      }
    }
    
    //当图形为花朵时
    if(shape_name=="flower"){
      frameRate(15);
      if(mouseY>150){
        if(mousePressed){
            Flower f=new Flower(mouseX, mouseY);
            f.show();
        }else{
          flowerSize=50;
        }
      }
    }
    
    //当图形为可填充颜色的花朵时
    if(shape_name=="color_flower"){
      frameRate(10);
      if(mouseY>150){
        if(mousePressed){  
          translate(mouseX,mouseY);
          scale(flowerSize/100-0.3+size);
          s.beginShape();
          s.fill(strokeColor);
          s.endShape();
          if(size<=0.6&&mouseY-(132*(0.2+size))>120){
            for(int j=0;j<6;j++){       
              shape(s,0,0); 
              rotate(radians(72));
            }
            fill(colora);
            ellipse(0,0,40,40);
            size+=0.03;
          }
        }else{
          colora=color(random(0,120),random(0,120),random(0,100));
          size=0;
        }
      }
    }  
  }
}

MoveCircle_class:

class MoveCircle{
 float x,y,x1,y1;
 float xspeed,yspeed;
 color circleColor;
 int size;
 MoveCircle(float a,float b,color c,int d){
   x=a;
   y=b;
   circleColor=c;    //圆形颜色
   size=d+1;      //记录当前strokeSize,+1是为了保证size!=0,因为圆形半径=size*10
   xspeed=random(-1,1);
   yspeed=random(-1,1);
 }
 void move(){
   //每隔一段时间修改一次圆形速度,为了修改周期与帧速率匹配,需要设定一个范围
   if(millis()%1000<10||millis()%1000>990&&millis()%1000<1000){
       xspeed=random(-1,1);
       yspeed=random(-1,1);
     }
   x+=xspeed;
   y+=yspeed;
   fill(backColor);
   ellipse(x1,y1,10*size+2,size*10+2);  //该圆形用于清除前一个圆,做到"伪刷新"
   if(y-25>140){
     fill(circleColor);
     ellipse(x,y,size*10,size*10);
     x1=x;y1=y;
   }
 }
}

Flower_class:

class Flower {
  PImage flower;  //载入花朵图片
  float x,y;
  Flower(float mx, float my){
    x=mx;
    y=my;
    flower = loadImage("flower.png");  //载入花朵图片
  }
  void show(){
    if(flowerSize<200){
      flowerSize+=10;
      if((mouseY-flowerSize/2)>120){
        image(flower, x-flowerSize/2, y-flowerSize/2,flowerSize,flowerSize);
      }
    }
  }
}

Next are some image resources needed for this project:
all project resources can be downloaded from here: processing fun sketchpad code and resources
insert image description here
insert image description here
insert image description here
insert image description here
insert image description here
insert image description here
insert image description here
insert image description here
insert image description here
insert image description here
insert image description here
insert image description here
insert image description here
insert image description here

Guess you like

Origin blog.csdn.net/zhulong16/article/details/99688786