基于p5.js的简单绘画系统

 

本次实验的主题是编写一个绘画系统,提供一系列绘画材料例如画笔、颜料、滤镜等给用户操作,以创作出动态、交互的绘画作品。这个绘画是对传统绘画概念的拓展,但仍然要体现出与传统绘画的相似性。

注意:目标可以理解为:

创作一个app,看起来比较像绘画工具,但又不是重复已知的绘画行为,而要体现出绘画出不来的效果:动态/UI或者意图,传统绘画是创作的一个平面视觉图像,这个app可以创作其他东西。

设计思路:

首先,三个基本要求:动态/UI/交互。关于UI和交互其实很多绘图软件里都很常见了,这是当然的,因为一个软件是给人用的,如果没有最基础的友好的ui和交互的话肯定没办法胜过其他软件,最后被淘汰。

所以要确定自己的系统要有UI、可交互。

接下来要大体考虑一下想通过这个绘画系统实现什么样的功能,然后再去通过代码实现。

本次实验借鉴了这篇博客:

https://blog.csdn.net/qq_27534999/article/details/79427721

 

由于是绘画系统,要让使用者能够进行交互的话要设计GUI界面,因此需要按钮,p5.dom里有提供关于直接在界面上创建按钮的函数,这里使用的方法是通过rect画出按钮然后判断鼠标是否点击在画出的范围内,然后再决定是否要执行接下来的事件。

整个界面布局如下:

基于p5.js的简单绘画系统_第1张图片

 

画布右边是调色盘,底端是功能键,点击左二按钮会显示不同的三个数字,分别是1、2、3,代表本系统的三种笔刷

笔刷一(地狱恶犬笔刷):

基于p5.js的简单绘画系统_第2张图片

笔刷二(表情包笔刷):

笔刷三:

基于p5.js的简单绘画系统_第3张图片

 

 

 

附加功能:在上面gif里表现得很明显了,这个绘画系统有自带背景音乐,且会根据音调振幅在屏幕上显示出来。

 

为了实现按钮功能,定义FuncBtn实现重复形状但位置不同的按钮,用ColorBtn来实现画布的调色盘功能。代码不与赘述;

然后有了按钮就要实现相应的功能,这里写了三个方法来画不同的图像,方便被下面的交互运动调用。

function huaji(x,y,size,l){
  //stroke(252,186,12); 
  noStroke();
  fill(237,148,14);
  ellipse(x,y,1.06*size);
  fill(252,222,12);
  ellipse(x,y,size);//脸
  
  fill(173,91,10);
  arc(x, y, 0.8*size, 0.8*size, 0, PI, CHORD);
  fill(252,222,12);
  arc(x, y-0.01*size, 0.8*size, 0.7*size, 0, PI, CHORD);//笑
  
  fill(254,240,205);
  arc(x-0.25*size, y, 0.8*size, 0.6*size, 1.3*PI,1.7* PI, PIE);
  fill(252,222,12);
  arc(x-0.25*size, y, 0.8*size, 0.5*size, 1.3*PI,1.7* PI, PIE);
  
  
  fill(254,240,205);
  arc(x+0.25*size, y, 0.8*size, 0.6*size, 1.3*PI,1.7* PI, PIE);
  fill(252,222,12);
  arc(x+0.25*size, y, 0.8*size, 0.5*size, 1.3*PI,1.7* PI, PIE);//眼壳子
  if(l==-1){
  fill(173,91,10);
  ellipse(x-0.34*size,y-0.28*size,0.1*size);
  ellipse(x+0.16*size,y-0.28*size,0.1*size);//眼珠
  }
  if(l==1){
  fill(173,91,10);
  ellipse(x-0.1*size,y-0.28*size,0.1*size);
  ellipse(x+0.35*size,y-0.28*size,0.1*size);//眼珠
  
  
  }
  
  fill(58,43,1);
  arc(x-0.28*size, y-0.35*size,0.20*size, 0.20*size, 1.1*PI,2.1* PI, OPEN);
  fill(252,222,12);
  arc(x-0.28*size, y-0.35*size, 0.21*size, 0.16*size, 1*PI,2.2* PI, OPEN);
  
  fill(58,43,1);
  arc(x+0.28*size, y-0.35*size,0.20*size,0.20*size, 0.9*PI,1.9* PI, CHORD);
  fill(252,222,12);
  arc(x+0.28*size, y-0.35*size, 0.21*size, 0.15*size, 0.9*PI,1.9* PI, CHORD);//眉毛

  
  fill(241,74,56);
  ellipse(x-0.25*size,y-0.18*size,0.25*size,0.07*size);
  ellipse(x+0.25*size,y-0.18*size,0.25*size,0.07*size);
}
 

function dog(x,y,size)
{
  noStroke();
  //头
  fill(0);
  quad(x-1*size,y+0.5*size,x-0.5*size,y+1*size,x+0.5*size,y+1*size,x+1*size,y+0.5*size);
  quad(x-1*size,y-0.5*size,x-0.5*size,y-1*size,x+0.5*size,y-1*size,x+1*size,y-0.5*size);
  quad(x-1*size,y+0.5*size,x+1*size,y+0.5*size,x+1*size,y-0.5*size,x-1*size,y-0.5*size);

  //鼻子
  quad(x+0.3*size,y-0.1*size,x+0.3*size,y+0.2*size,x-0.3*size,y+0.2*size,x-0.3*size,y-0.1*size);
  //耳朵
  fill(0);
  triangle(x-1*size,y-0.5*size,x-1*size,y-2*size,x-0.5*size,y-1*size);
  triangle(x+0.5*size,y-1*size,x+1*size,y-2*size,x+1*size,y-0.5*size);
  //眼睛
  fill(255);
  ellipse(x+0.65*size,y-0.25*size,0.25*size,0.25*size);
  ellipse(x-0.65*size,y-0.25*size,0.25*size,0.25*size);
  //ellipse(x-0.25*size,y-0.18*size,0.25*size,0.07*size);
  //胡子
}

function simple(x,y,size)
{
  
   noStroke();//无边框
   ellipse(x*size,y*size,1*size,0.5*size);
   ellipse(x*size,y*size,0.5*size,1*size);
   //ellipse(x*size,y-10*size,2*size,2*size);
   //ellipse(x*size,y+10*size,2*size,2*size);
   //ellipse(x*size,y*size,2*size,2*size);
   
}

 

这里为了让后面实现运动,所以给每个坐标一个缩放比例size,方便后续处理

 

然后为了让画出的图像动起来,定义一个随机偏移量x,一个随机偏移量y,

然后如果点击了相应的按钮,就执行相应的方法,并且传递给方法中的变量x和y的值为浮动值,让图像保持在鼠标曾点击的位置附近运动,这里给传递过来的变量加了周期。

 

然后为了实现播放音乐并显示音乐条的功能,定义全局变量

var song, fft;
var tx =[]; 
var ty = []; 
var big = []; 
var a = 0;
var r = 0;

用preload初始化加载音乐:

这里的preload

是预加载函数,在setup()执行之前执行,用于处理异步操作。所有需要加载的内容(如图片文件、json文件、字体文件等)加载完毕的时候再执行setup()。

在加载内容的时候默认的提示“loading”,如果想要自定义“loading”的样式,则可以在body里加入一段id为“p5_loading”的标签即可,

 

function preload() {
  // we have included both an .ogg file and an .mp3 file
  soundFormats('ogg', 'mp3');

  // if mp3 is not supported by this browser,
  // loadSound will load the ogg file
  // we have included with our sketch
  song = loadSound('1.mp3');
}

在setup方法中

song.play();
  fft = new p5.FFT();
  fft.setInput(song);
  colorMode(RGB);
  for (var i = 0; i < 1024; i++) {//所有的
    tx[i] = 500+cos(r)*100;//x坐标
    ty[i] = 300+sin(r)*200;//y坐标
    r+=2*PI/1024;//增加
  }

 

最后在draw方法中画出运动的音乐条

var spectrum = fft.analyze();
  
  //beginShape();
  //.right.get(i)
  noStroke();
  for (i = 0; i     // vertex(i, map(spectrum[i], 0, 255, height, 0) );
    fill(i/2, 255, 255);
    rect(i*1, 600-spectrum[i]*2, 5, spectrum[i]*0.5 );
  }

其实一开始在构思的时候也上网查找了很多资料,但是网上关于p5.js的内容不是太多,在查找资料的过程中,一开始想实现的效果是这样的,用webgl实现的流体效果,

p5.js中确实能使用webgl,但是尝试了很久,自己写不出来遂放弃。

 

总体来说,

 

 

 

 

 

 

 


 

 

 

 

 

你可能感兴趣的:(基于p5.js的简单绘画系统)