首先看一下这样两幅图:
两幅图都是一种重复而且有规律的动画,第一幅图的基本元素是方块,第二个则是圆形。
js是一种基于对象的语言,在之前的学习过程中,使用p5.js绘图通常都是直接利用自带的函数进行直接绘制,或者说是和面向过程一般不断调用函数,要想绘制像上面两幅图难免会有些枯燥的坐标调整等,而我比较喜欢面向对象的编程方式。所以这次我选择使用一个简单的类似‘类’的结构来进行绘制动态效果。
js的方法可以进行实例化,比如这样子:
function Car(color,door){
this.color = color;//this代表这是一个公共变量
this.doors = door;
this.showColor = function(){
alert(this.color)};
}
var car1 = new Car(“red”,4);
var car2 = new Car(“blue”,4);`
这样就实例化了Car‘类’的对象并且可以随时改变对象的属性。
而这次选择的绘制方法也是如此。
首先定义一个简单的绘制正方形的类:
function square(x,y,sidelength,angle)
{
var Posx=x;
var Posy=y;
this.sidelength=sidelength;
this.angle=angle;
this.setAngle=function(angle){this.angle=angle;}
this.setSize=function(size){this.sidelength=size;}
this.getX=function(){return Posx;}
this.getY=function(){return Posy;}
this.setPos=function(x,y){
Posx=x;
Posy=y;
}
this.getAngle=function(){return this.angle;}
this.getSize=function(){return this.sidelength;}
this.change=function(extraSize,extraAngle)
{ this.sidelength+=extraSize;
this.angle+=extraAngle;
}
this.drawSquare=function()
{
var x1=Posx+Math.cos((this.angle+45)*(Math.PI)/180)*Math.sqrt(2)/2*this.sidelength;
var y1=Posy+Math.sin((this.angle+45)*(Math.PI)/180)*Math.sqrt(2)/2*this.sidelength;
var x2=Posx+Math.cos((this.angle+135)*(Math.PI)/180)*Math.sqrt(2)/2*this.sidelength;
var y2=Posy+Math.sin((this.angle+135)*(Math.PI)/180)*Math.sqrt(2)/2*this.sidelength;
var x3=Posx+Math.cos((this.angle+225)*(Math.PI)/180)*Math.sqrt(2)/2*this.sidelength;
var y3=Posy+Math.sin((this.angle+225)*(Math.PI)/180)*Math.sqrt(2)/2*this.sidelength;
var x4=Posx+Math.cos((this.angle+315)*(Math.PI)/180)*Math.sqrt(2)/2*this.sidelength;
var y4=Posy+Math.sin((this.angle+315)*(Math.PI)/180)*Math.sqrt(2)/2*this.sidelength;
noFill();
stroke(200, 250, 240);
quad(x1,y1,x2,y2,x3,y3,x4,y4);
}
这里只是简单定义了正方形的中心点坐标,边长以及角度,
当然,想绘制其他图案只需要在里面加上一个绘制的方法就行。
这样定义方便随时改变绘制出来的图案的大小和旋转角度,
也不用旋转坐标轴和进行push和pop来保证相对坐标不变了。
接下来就是类的实例化:
var squares=[];
for(var i=0;i<10000;i++)
{
squares[i]=new square(400, 400,0,i*20);
}
squares[0].setSize(10);
在实例化了square对象后,可以改变它的坐标角度等参数,很简单的就能达到动态的效果:
function setup() {
createCanvas(800, 800);
}
function draw() {
background(0,0,0);
for(var i=squares.length-1;i>=0;i--)
{
if(i>0)
{
squares[i].change(squares[i-1].getSize()/40);
}
else{
squares[i].change(squares[i].getSize()/40);
}
}
for(var i=0;i<squares.length;i++)
{
squares[i].drawSquare();
}
}
效果图:
录制的有点卡
手绘对比:
这里只对正方形对象的大小和角度进行了改变。
当然也可以对中心点的坐标进行一些操作,话不多说直接上代码:
function draw() {
background(0,0,0);
count+=5/100;
for(var i=squares.length-1;i>=0;i--)
{
if(i>0&&i%2==1)
{
if(cos(count)<=0){
squares[i].change(squares[i-1].getSize()/50,2);
}
}
else if(i>0&&i%2==0)
{
if(cos(count)<=0){
squares[i].change(squares[i-1].getSize()/100,2);
}
}
else{
squares[i].change(squares[i].getSize()/50,-2);
}
}
for(var i=0;i<squares.length;i++)
{
if(i<squares.length-2&&i%2==1)
{
squares[i].setPos(400-20*Math.cos(count),400+20*Math.cos(count));
}else if(i<squares.length-2&&i%2==0)
{
squares[i].setPos(400+20*Math.cos(count),400+20*Math.cos(count));
}
if(squares[i].getSize()<800)
{
squares[i].drawSquare();
}
}
}
emmm。。。可能有些鬼畜,但还是达到了目的:
这里只用了简单的正方形作为基本元素,绘制更复杂的图形可以自己定义更多的图形绘制方法。
手绘和码绘的区别
绘制工具以及局限性
使用代码绘制在某些方面有着很大的局限性,比如不能表现出更随意的形状和特征,绘制图像都是基于之前给定或者自定的绘制方式或者元素来进行变换和组合,也可以添加交互的效果,当然这也可以当成是另一种‘手绘’的形式。
而手绘则可以随意发挥,可以混合颜料,可以绘制任意形状,可以随意控制画面的明暗对比等。
比如这样一张图:
但是手绘复杂而且有规律的图像就比较麻烦,而码绘的优点就是可修改,速度快,代码输入即可获得结果。
绘画体验
手绘想要达到动态效果必须对每一帧进行绘制,而用代码绘画只需要用一个循环就能绘制出一幅动态图。
机器处理重复有规律的劳动更方便快捷,但是手绘能直接便捷地绘制想要的图形。至于哪个更适合自己,
这就需要看个人的需求,追求更精致,更有艺术感的选择手绘更能表达情感,追求快捷,规律美的可以
使用代码绘制。
呈现效果
代码绘制的图像更加直观,简洁,而手绘则可以使用色彩的明暗,留白等技法表现朦胧的美感,两者各有优点。
总结
手绘和码绘各有优点也有各自的局限性,在选择适合自己的方法的时候,要结合自己的情况,当然码绘也有用代码实现的画布,再用鼠标等直接绘制的方法,这个可以说是结合了两种绘画方式吧。
参考链接:
1.《用代码画画》:
0.1 用代码画画——搞艺术的学编程有啥用?
https://blog.csdn.net/magicbrushlv/article/details/77922119
1.1 开始第一幅“码绘”——以编程作画的基本方法
https://blog.csdn.net/magicbrushlv/article/details/77840565
2. 以编程的思想来理解绘画—— (一)用”一笔画“表现“过程美”
https://blog.csdn.net/magicbrushlv/article/details/82634189