p5.js创意绘图(2)自画像

mac2024-03-14  25

利用p5.js画一幅自画像,效果如下: 1.按下键盘“M”(music)键,音乐停止播放;再次按下“M”键,音乐重新开始播放。 2.按下键盘“S”(shape)键,眼睛形状改变。一共有两种形状:死鱼眼和星星眼。 3.按下键盘“C”(Color)键,眼睛颜色会改变。死鱼眼有黑色和红色两种颜色,星星眼有黑色和黄色两种颜色。 4.眼睛会眨动。点击鼠标左键,眼睛停止眨动;再次点击鼠标左键,眼睛重新开始眨动。 5.死鱼眼状态下,按住鼠标右键,眼睛会随鼠标移动而移动。

下面进行代码讲解。 一、眼睛 (一)死鱼眼 先画一个圆形,再在圆形和眉毛之间接矩形。因为圆形可能会跑到眉毛上,所以眉毛上要画一个肤色的矩形盖住。

//眼睛1(死鱼眼) function drawEye1(dx,dy) { //画眼睛圆形部分 stroke(0); strokeWeight(4); ellipse(width/2-60+dx,160+dy,50,50); ellipse(width/2+60+dx,160+dy,50,50); //画眼睛矩形部分 noStroke(); rect(width/2-60-25+dx,160,50,dy); rect(width/2+60-25+dx,160,50,dy); //画眼睛矩形部分的边框 stroke(0); strokeWeight(4); line(width/2-60-25+dx,160,width/2-60-25+dx,160+dy); line(width/2-60-25+dx+50,160,width/2-60-25+dx+50,160+dy); line(width/2+60-25+dx,160,width/2+60-25+dx,160+dy); line(width/2+60-25+dx+50,160,width/2+60-25+dx+50,160+dy); //盖住在眉毛上的部分 noStroke(); fill(210,180,140); rect(width/2-100-5,160-55,200+10,58); }

(二)星星眼 先画一个矩形,再在四角各画一个肤色的四分之一椭圆。

function drawEye2(percent) { var dx=32; var dy=38; //左眼 noStroke(); rect(width/2-60-dx*percent,198-dy*percent,2*dx*percent,2*dy*percent); //盖住多余的矩形 stroke(0); strokeWeight(4); fill(210,180,140); arc(width/2-60-dx*percent-1,198-dy*percent-1,2*dx*percent+2,2*dy*percent+2,0,HALF_PI); arc(width/2-60-dx*percent+2*dx*percent+1,198-dy*percent-1,2*dx*percent+2,2*dy*percent+2,HALF_PI,2*HALF_PI); arc(width/2-60-dx*percent+2*dx*percent+1,198-dy*percent+2*dy*percent+1,2*dx*percent+2,2*dy*percent+2,2*HALF_PI,3*HALF_PI); arc(width/2-60-dx*percent-1,198-dy*percent+2*dy*percent+1,2*dx*percent+2,2*dy*percent+2,3*HALF_PI,4*HALF_PI); //右眼 noStroke(); rect(width/2+60-dx*percent,198-dy*percent,2*dx*percent,2*dy*percent); //盖住多余的矩形 stroke(0); strokeWeight(4); fill(210,180,140); arc(width/2+60-dx*percent-1,198-dy*percent-1,2*dx*percent+2,2*dy*percent+2,0,HALF_PI); arc(width/2+60-dx*percent+2*dx*percent+1,198-dy*percent-1,2*dx*percent+2,2*dy*percent+2,HALF_PI,2*HALF_PI); arc(width/2+60-dx*percent+2*dx*percent+1,198-dy*percent+2*dy*percent+1,2*dx*percent+2,2*dy*percent+2,2*HALF_PI,3*HALF_PI); arc(width/2+60-dx*percent-1,198-dy*percent+2*dy*percent+1,2*dx*percent+2,2*dy*percent+2,3*HALF_PI,4*HALF_PI); }

(三)眼睛随鼠标移动 为了防止眼睛移动到眉毛外,有两种方案: 1.规定鼠标横坐标在一定范围内时,眼睛随鼠标移动;若鼠标横坐标超过这一范围,眼睛位于位移最大处。

mx=mouseX-200; if(abs(mx)>=14) { if(mx<0) mx=-14; else mx=14; }

2.利用map()函数,将鼠标横坐标映射到眼睛位移范围。

map(x,a1,a2,b1,b2);

map()函数:将变量x的值从a1-a2映射到b1-b2。可用直线来理解: 因为不知道屏幕大小为多少,所以设置若鼠标移动到画布外,则眼睛不移动。

if(mouseX<=width)//width:画布的宽 mx=map(mouseX,0,width,-14,14);

二、刘海 绘制不规则图形区域:以beginShape();为开头,一直到endShape();为结束,往数组vertex里加点x1,x2,…,xn,可以绘制x1->x2->…->xn->x1的不规则封闭图形。

beginShape(); for(var i=0;i<vec1[0].length;i++) { vertex(vec1[0][i],vec1[1][i]); } endShape();

三、鼠标、键盘事件 (一)点击左键 鼠标点击会触发函数mouseClicked()。在该函数中添加点击左键时的操作。

//左键控制眼睛是否眨眼 function mouseClicked()//点击鼠标 { if(mouseButton==LEFT)//点击的是鼠标左键 flag=!flag; }

(二)按住右键 鼠标点击会令变量mouseIsPressed的值变成true。添加被按住的是右键时的操作。

//右键按住时眼睛才移动 if(mouseIsPressed)//鼠标被按住 { if(mouseButton==RIGHT)//被按住的是右键 { ... } }

(三)按下键盘 键盘按下会触发函数keyPressed()。在该函数中添加按下某些按键时的操作。

function keyPressed()//按下了键盘 { switch(keyCode)//判断被按下了哪个键 { case 67://C(color),眼睛颜色 colorFlag=!(colorFlag); break; case 83://S(shape),眼睛形状 eyeFlag=!(eyeFlag); break; case 77://M(music),音乐 musicFlag=!(musicFlag); if(song.isPlaying()) song.stop(); else song.loop(); break; } }

四、其余部分 利用绘制基本几何形状的ellipse()、line()、rect()函数绘制便可。需要注意的是,脸、头发、眼镜、耳朵一定要按顺序绘制,这样才能有眼镜戴在耳朵上,并且挡住头发的效果。

五、背景 (注:因为有音乐,所以只有在Microsoft Edge才能打开。其他浏览器需要加载插件。) 背景光柱的高度及光点个数随音乐而变化。

(1)初始化音乐资源

var song, fft; function preload()//预加载 { soundFormats('ogg', 'mp3'); song = loadSound('xxx.mp3'); } function setup() { ... song.loop();//循环播放 fft = new p5.FFT(); fft.setInput(song);//导入音乐 }

注:loop()为循环播放,若为play()则只会播放一遍。 (2)背景跟随音乐变化 利用analyze()获取音乐信息至变量spectrum,spectrum.length为音乐音阶个数,spectrum[i]为各音阶的音量大小。

//音乐背景 function drawMusic() { var x,y,i; var spectrum=fft.analyze(); colorMode(HSB,spectrum.length);//将颜色模式调为HSB模式下的自定义索引值模式 noStroke(); //光柱 for (i=0; i<spectrum.length; i+=2) { fill(i,spectrum.length,spectrum.length); rect(i, height-spectrum[i], 3, spectrum[i]); } //光点 for (i=0; i<spectrum.length; i+=2) { x=Math.random()*width;//产生随机数 y=Math.random()*height; fill(i,spectrum.length,spectrum.length); ellipse(x, y, spectrum[i]/10,spectrum[i]/10) } colorMode(RGB);//将颜色模式变回RGB模式 }

(参考资料:P5js–声音可视化) 为了使光柱和光点消失时有渐出的效果,背景颜色要设置一定的透明度。

background(255,255,255,30);//R,G,B,A(透明度)

总结 p5.js真的很有趣,可以把许多有趣的想法变为现实!

最新回复(0)