p5.js实现动态码绘(3d旋转、2d旋转基础)

p5.js实现动态码绘(3d旋转、2d旋转基础)

一.在开始前遇到的编译器问题

p5有一套自己的绘图框架,并且有一个非常易用的离线网页版编译器,免除了新的编译器带来的烦恼。但是它的web editor也有缺点,即没有词义联想和代码补全。因此最终还是选择了使用vscode。不过作为一个非常轻量级的编译器,vscode虽然能够在自动补全函数参数表的同时提示用户相应的函数方法需要传递什么样的参数,也无法像rider大厂做的商业级代码编译器那样集成了很多的函数说明。因此在编写的时候依旧需要常常参考官方文档,且要时刻警惕代码拼写上的错误。
引入p5相关的扩展包后,发现js的console.log()方法是不能用的,试了很多方法还是没办法用它来调试代码,有一点难受,所以后来调Bug的时候还是用上了网页端的p5编译器。

第一次主要实现了以下两个效果:

绘制旋转的❤

p5给出了一个非常简单易用的box()函数,用以生成一个立方体:translate是平移量,指定在posX,posY,posZ的位置生成一个大小为boxsize的立方体。

    translate(posX,posY,posZ);
    box(BoxSize);

接着,提供一个函数,其作用是按心中的方块排列方式计算坐标,拼成一个心。之后我们将调用这个方法来生成更多的心。

//画一个❤
function drawHeart(BoxSize,posX,posY,posZ,r,g,b,)
{
    fill(r,g,b);
    //第三行第中间的正方体
    translate(posX,posY,posZ);
    box(BoxSize);
    //translate是偏移量
    translate(-(10/9)*BoxSize,0,0);
    box(BoxSize);
    translate(-(10/9)*BoxSize,0,0);
    box(BoxSize);
    translate(-(10/9)*BoxSize,0,0);
    box(BoxSize);
    translate(4*(10/9)*BoxSize,0,0);
    box(BoxSize);
    translate((10/9)*BoxSize,0,0);
    box(BoxSize);
    translate((10/9)*BoxSize,0,0);
    box(BoxSize);
    //第二行
    translate(0,-(10/9)*BoxSize,0);
    box(BoxSize);
    translate(-(10/9)*BoxSize,0,0);
    box(BoxSize);
    translate(-(10/9)*BoxSize,0,0);
    box(BoxSize);
    translate(-(10/9)*BoxSize,0,0);
    box(BoxSize);
    translate(-(10/9)*BoxSize,0,0);
    box(BoxSize);
    translate(-(10/9)*BoxSize,0,0);
    box(BoxSize);
    translate(-(10/9)*BoxSize,0,0);
    box(BoxSize);
    //第一行4个
    translate((10/9)*BoxSize,-(10/9)*BoxSize,0);
    box(BoxSize);
    translate((10/9)*BoxSize,0,0);
    box(BoxSize);
    translate(2*(10/9)*BoxSize,0,0);
    box(BoxSize);
    translate((10/9)*BoxSize,0,0);
    box(BoxSize);
    //第四行5个
    translate(0,3*(10/9)*BoxSize,0);
    box(BoxSize);
    translate(-(10/9)*BoxSize,0,0);
    box(BoxSize);
    translate(-(10/9)*BoxSize,0,0);
    box(BoxSize);
    translate(-(10/9)*BoxSize,0,0);
    box(BoxSize);
    translate(-(10/9)*BoxSize,0,0);
    box(BoxSize);
    //第五行3个
    translate((10/9)*BoxSize,(10/9)*BoxSize,0);
    box(BoxSize);
    translate((10/9)*BoxSize,0,0);
    box(BoxSize);
    translate((10/9)*BoxSize,0,0);
    box(BoxSize);
    //第六行1个
    translate(-(10/9)*BoxSize,(10/9)*BoxSize,0);
    box(BoxSize);
}

现在我们让它转起来。
在p53d中,需要旋转的整体需要被包含在push()/pop()函数之间,以让这个整体绕着这个物体的重心而不是原点(0,0)旋转。

  push();
  translate(-width/2+60, -height/2+60);
  rotateY(millis() / 1000);
  drawHeart(10,0,0,0,249,37,72);
  pop();

这里的translate()用以指定心在画布上的位置,rotate()用以指定旋转的速度。之后我们将对translate中坐标的增量和rotate中参数的分母进行变化以调整不同心的位置以及旋转速度。
另外,除第一个rotate()之外其他的rotae中首先为millis()加了一个值,这个值是为了使心与心之间产生一些时间差,否则所有的心就会像是在绕轴旋转一样,没有参差感。加上这个值使他们错开来。

所有代码:

function setup(){
    createCanvas(430, 430, WEBGL);
}

function draw() {
    // put drawing code here
  background(255);
  //第一行爱心,从左往右排列
  push();
  translate(-width/2+60, -height/2+60);
  rotateY(millis() / 1000);
  drawHeart(10,0,0,0,249,37,72);
  pop();
  
  push();
  translate(-width/2+160, -height/2+60);
  rotateY((millis()+500) / 1000);
  drawHeart(10,0,0,0,251,68,105);
  pop();
  
  push();
  translate(-width/2+260, -height/2+60);
  rotateY((millis()+1000) / 1000);
  drawHeart(10,0,0,0,249,37,72);
  pop();
  
  push();
  translate(-width/2+360, -height/2+60);
  rotateY((millis()+1500) / 1000);
  drawHeart(10,0,0,0,251,68,105);
  pop();
  
  
  push();//第二行爱心,从左往右排列
  translate(-width/2+60, -height/2+160);
  rotateY((millis()+500) / 1000);
  drawHeart(10,0,0,0,251,68,105);
  pop();
  
  push();
  translate(-width/2+160, -height/2+160);
  rotateY((millis()+1000) / 1000);
  drawHeart(10,0,0,0,251,68,105);
  pop();
  
  push();
  translate(-width/2+260, -height/2+160);
  rotateY((millis()+1500) / 1000);
  drawHeart(10,0,0,0,249,37,72);
  pop();

  push();
  translate(-width/2+360, -height/2+160);
  rotateY((millis()+2000) / 1000);
  drawHeart(10,0,0,0,249,37,72);
  pop();
  
  
  push();//第三行爱心,从左往右排列
  translate(-width/2+60, -height/2+260);
  rotateY((millis()+1000) / 1000);
  drawHeart(10,0,0,0,249,37,72);
  pop();
  
  push();
  translate(-width/2+160, -height/2+260);
  rotateY((millis()+1500) / 1000);
  drawHeart(10,0,0,0,251,68,105);
  pop();
  
  push();
  translate(-width/2+260, -height/2+260);
  rotateY((millis()+2000) / 1000);
  drawHeart(10,0,0,0,249,37,72);
  pop();
  
  push();
  translate(-width/2+360, -height/2+260);
  rotateY((millis()+2500) / 1000);
  drawHeart(10,0,0,0,251,68,105);
  pop();
  
  push();//第四行爱心,从左往右排列
  translate(-width/2+60, -height/2+360);
  rotateY((millis()+1500) / 1000);
  drawHeart(10,0,0,0,251,68,105);
  pop();
  
  push();
  translate(-width/2+160, -height/2+360);
  rotateY((millis()+2000) / 1000);
  drawHeart(10,0,0,0,249,37,72);
  pop();
  
  push();
  translate(-width/2+260, -height/2+360);
  rotateY((millis()+2500) / 1000);
  drawHeart(10,0,0,0,251,68,105);
  pop();
  
  push();
  translate(-width/2+360, -height/2+360);
  rotateY((millis()+3000) / 1000);
  drawHeart(10,0,0,0,249,37,72);
  pop();
  }


//画一个❤
function drawHeart(BoxSize,posX,posY,posZ,r,g,b,)
{
    fill(r,g,b);
    //第三行第中间的正方体
    translate(posX,posY,posZ);
    box(BoxSize);
    //translate是偏移量
    translate(-(10/9)*BoxSize,0,0);
    box(BoxSize);
    translate(-(10/9)*BoxSize,0,0);
    box(BoxSize);
    translate(-(10/9)*BoxSize,0,0);
    box(BoxSize);
    translate(4*(10/9)*BoxSize,0,0);
    box(BoxSize);
    translate((10/9)*BoxSize,0,0);
    box(BoxSize);
    translate((10/9)*BoxSize,0,0);
    box(BoxSize);
    //第二行
    translate(0,-(10/9)*BoxSize,0);
    box(BoxSize);
    translate(-(10/9)*BoxSize,0,0);
    box(BoxSize);
    translate(-(10/9)*BoxSize,0,0);
    box(BoxSize);
    translate(-(10/9)*BoxSize,0,0);
    box(BoxSize);
    translate(-(10/9)*BoxSize,0,0);
    box(BoxSize);
    translate(-(10/9)*BoxSize,0,0);
    box(BoxSize);
    translate(-(10/9)*BoxSize,0,0);
    box(BoxSize);
    //第一行4个
    translate((10/9)*BoxSize,-(10/9)*BoxSize,0);
    box(BoxSize);
    translate((10/9)*BoxSize,0,0);
    box(BoxSize);
    translate(2*(10/9)*BoxSize,0,0);
    box(BoxSize);
    translate((10/9)*BoxSize,0,0);
    box(BoxSize);
    //第四行5个
    translate(0,3*(10/9)*BoxSize,0);
    box(BoxSize);
    translate(-(10/9)*BoxSize,0,0);
    box(BoxSize);
    translate(-(10/9)*BoxSize,0,0);
    box(BoxSize);
    translate(-(10/9)*BoxSize,0,0);
    box(BoxSize);
    translate(-(10/9)*BoxSize,0,0);
    box(BoxSize);
    //第五行3个
    translate((10/9)*BoxSize,(10/9)*BoxSize,0);
    box(BoxSize);
    translate((10/9)*BoxSize,0,0);
    box(BoxSize);
    translate((10/9)*BoxSize,0,0);
    box(BoxSize);
    //第六行1个
    translate(-(10/9)*BoxSize,(10/9)*BoxSize,0);
    box(BoxSize);
}

运行结果:

2D旋转(绕顶点旋转并停留一段时间)

这是一张一开始看很简单越做复杂的图。
首先所有的扇形需要以不同的速率绕中心旋转;其次,要计算好每个图形的起始位置,再次,每次旋转都需要停顿一段时间。最后,仔细观察会发现有的扇形是一直在旋转的,有的转一下又停一下,有的向顺时针方向旋转一次后立刻逆时针旋转,来回往复。每个扇形的旋转特征都不是非常一样,这导致了非常大的困难。这个看起来简单的图前前后后写了超过5个小时。

1.四种旋转函数
将每一种旋转方法封装成函数,传入图形中心、颜色、控制旋转的时间。

  function drawCircle(posX, posY, r, g, b, q) {
    noStroke();
    push();
    fill(r, g, b);
    translate(posX, posY);
    rotate(q * HALF_PI);
    arc(0, 0, 100, 100, 0, HALF_PI, PIE);
    arc(0, 0, 100, 100, PI, PI + HALF_PI, PIE);
    pop();
  }
  
  function drawCircle2(posX, posY, r, g, b, q) {
    noStroke();
    push();
    fill(r, g, b);
    translate(posX, posY);
    rotate(q * HALF_PI);
    arc(0, 0, 100, 100, HALF_PI, HALF_PI + HALF_PI, PIE);
    arc(0, 0, 100, 100, PI + HALF_PI, TWO_PI, PIE);
    pop();
  }
  
  
  function antiClockwise1(posX, posY, r, g, b, q) {
  
    noStroke();
    push();
    fill(r, g, b);
    translate(posX, posY);
    rotate(-q * HALF_PI);
    arc(0, 0, 100, 100, HALF_PI, HALF_PI + HALF_PI, PIE);
    arc(0, 0, 100, 100, PI + HALF_PI, TWO_PI, PIE);
    pop();
  
  }
  
  function antiClockwise2(posX, posY, r, g, b, q) {
  
    noStroke();
    push();
    fill(r, g, b);
    translate(posX, posY);
    rotate(-q * HALF_PI - HALF_PI);
    arc(0, 0, 100, 100, HALF_PI, HALF_PI + HALF_PI, PIE);
    arc(0, 0, 100, 100, PI + HALF_PI, TWO_PI, PIE);
    pop();
  
  }

2.用q来计算停顿的时间

  function ease(q) {
    return q * q * 3 - q * q * q * 2;
  }

3.根据时间轮转,设置一个t来做循环的参数。将frameCount(表示已经绘制的帧数),将它与1作处于运算,并根据所得的数来判断每个扇形在某一段时间内所需要做的旋转。
之后,将t分区,对时间进行分块,在每一块时间中对每一个需要旋转的扇形赋予运动特征。

  function draw() {
    noStroke();
    background(0);
    t = (0.01 * frameCount) % 1;
    push();
    //第一行
    if (t < .25) {
    //分块1
    }
    else if(t<0.5){
    //分块2
    }
    else if(...)
    ....

4.对于停顿时间,这里使用map()函数进行映射。map(t,a1,a2,b1,b2)表示将t从(a1,a2)的范围映射到(b1,b2)。map映射规则根据时间分区来进行不同的选择。
举例:

        drawCircle2(100,100,0,163,150,ease(map(t, 0, .25, 0, 1)));

即表示在(100,100)的位置绘制一个颜色为rgb(0,153,150)的蝶形。

完整代码如下:

function setup() {
    createCanvas(400, 400);
    //background(0);
  }
  
  function draw() {
    noStroke();
    background(0);
    t = (0.01 * frameCount) % 1;
    push();
    //第一行
    if (t < .25) {

        //中间四个
        drawCircle2(100,100,0,163,150,ease(map(t, 0, .25, 0, 1)));
        drawCircle2(300,100,97,46,141,ease(map(t, 0, .25, 0, 1)));
        drawCircle2(100,300,97,46,141,ease(map(t, 0, .25, 0, 1)));
        drawCircle2(300,300,234,34,94,ease(map(t, 0, .25, 0, 1)));
        //中间的
        antiClockwise1(200, 200, 97,46,141, ease(map(t, 0, .25, 0, 1)));
        //每条边上中间的
        antiClockwise1(0, 0, 247,182,44, ease(map(t, 0, .25, 0, 1)));
        antiClockwise1(0, 200,0,163,150, ease(map(t, 0, .25, 0, 1)));
        antiClockwise1(0, 400,97,46,141, ease(map(t, 0, .25, 0, 1)));
        antiClockwise1(200, 0,0,163,150, ease(map(t, 0, .25, 0, 1)));
        antiClockwise1(200, 400,234,34,94, ease(map(t, 0, .25, 0, 1)));
        antiClockwise1(400, 0,97,46,141, ease(map(t, 0, .25, 0, 1)));
        antiClockwise1(400, 200,234,34,94, ease(map(t, 0, .25, 0, 1)));
        antiClockwise1(400, 400,247,182,44, ease(map(t, 0, .25, 0, 1)));
        //
        antiClockwise2(100, 0, 129,197,64, ease(map(t, 0, .25, 0, 1)));
        antiClockwise2(100, 200, 22,116,188, ease(map(t, 0, .25, 0, 1)));
        antiClockwise2(100, 400, 194,34,134, ease(map(t, 0, .25, 0, 1)));
        antiClockwise2(300, 0, 22,116,188, ease(map(t, 0, .25, 0, 1)));
        antiClockwise2(300, 200, 194,34,134, ease(map(t, 0, .25, 0, 1)));
        antiClockwise2(300, 400, 237,91,53, ease(map(t, 0, .25, 0, 1)));
        //
        drawCircle(0, 100, 129,197,64, ease(map(t, 0, .25, 0, 1)))
        drawCircle(0, 300, 22,116,188, ease(map(t, 0, .25, 0, 1)))
        drawCircle(200, 100, 22,116,188, ease(map(t, 0, .25, 0, 1)))
        drawCircle(200, 300, 194,34,134, ease(map(t, 0, .25, 0, 1)))
        drawCircle(400, 100, 194,34,134, ease(map(t, 0, .25, 0, 1)))
        drawCircle(400, 300, 237,91,53, ease(map(t, 0, .25, 0, 1)))

    } 
    else if (t < .5) {
        //
        drawCircle(100, 100, 0,163,150, ease(map(t, 0.25, .5, 0, 1)))
        drawCircle(100, 300, 97,46,141, ease(map(t, 0.25, .5, 0, 1)))
        drawCircle(300, 100, 97,46,141, ease(map(t, 0.25, .5, 0, 1)))
        drawCircle(300, 300, 234,34,94, ease(map(t, 0.25, .5, 0, 1)))
        //
        antiClockwise2(200, 0, 0,163,150, 0);
        antiClockwise2(200, 200, 97,46,141, 0);
        antiClockwise2(200, 400, 234,34,94, 0);
        //
        antiClockwise2(0, 0, 247,182,44, ease(map(t, .25, .5, 0, 1)));
        antiClockwise2(0, 200, 0,163,150, ease(map(t, .25, .5, 0, 1)));
        antiClockwise2(0, 400, 97,46,141, ease(map(t, .25, .5, 0, 1)));
        antiClockwise2(400, 0, 97,46,141, ease(map(t, .25, .5, 0, 1)));
        antiClockwise2(400, 200, 234,34,94, ease(map(t, .25, .5, 0, 1)));
        antiClockwise2(400, 400, 247,182,44, ease(map(t, .25, .5, 0, 1)));
        //
        antiClockwise1(100, 0, 129,197,64, 0);
        antiClockwise1(100, 200, 22,116,188, 0);
        antiClockwise1(100, 400, 194,34,134, 0);
        antiClockwise1(300, 0, 22,116,188, 0);
        antiClockwise1(300, 200, 194,34,134, 0);
        antiClockwise1(300, 400, 237,91,53, 0);
        //
        drawCircle2(0, 100, 129,197,64, 0);
        drawCircle2(0, 300, 22,116,188, 0);
        drawCircle2(200, 100, 22,116,188, 0);
        drawCircle2(200, 300, 194,34,134, 0);
        drawCircle2(400, 100, 194,34,134, 0);
        drawCircle2(400, 300, 237,91,53, 0);

    } 
    else if (t < .75) {
        //
        drawCircle2(100, 100, 0,163,150, ease(map(t, 0.5, .75, 0, 1)));
        drawCircle2(100, 300, 97,46,141, ease(map(t, 0.5, .75, 0, 1)));
        drawCircle2(300, 100, 97,46,141, ease(map(t, 0.5, .75, 0, 1)));
        drawCircle2(300, 300, 234,34,94, ease(map(t, 0.5, .75, 0, 1)));
        //
        drawCircle(200, 0, 0,163,150, ease(map(t, 0.5, .75, 0, 1)));
        drawCircle(200, 200, 97,46,141, ease(map(t, 0.5, .75, 0, 1)));
        drawCircle(200, 400, 234,34,94, ease(map(t, 0.5, .75, 0, 1)));
        //
        antiClockwise1(0, 0, 247,182,44, ease(map(t, 0.5, .75, 0, 1)));
        antiClockwise1(0, 200, 0,163,150, ease(map(t, 0.5, .75, 0, 1)));
        antiClockwise1(0, 400, 97,46,141, ease(map(t, 0.5, .75, 0, 1)));
        antiClockwise1(400, 0, 97,46,141, ease(map(t, 0.5, .75, 0, 1)));
        antiClockwise1(400, 200, 234,34,94, ease(map(t, 0.5, .75, 0, 1)));
        antiClockwise1(400, 400, 247,182,44, ease(map(t, 0.5, .75, 0, 1)));
        //
        antiClockwise1(100, 0, 129,197,64,ease(map(t, 0.5, .75, 0, 1)));
        antiClockwise1(100, 200,22,116,188,ease(map(t, 0.5, .75, 0, 1)));
        antiClockwise1(100, 400,194,34,134,ease(map(t, 0.5, .75, 0, 1)));
        antiClockwise1(300, 0,22,116,188,ease(map(t, 0.5, .75, 0, 1)));
        antiClockwise1(300, 200,194,34,134,ease(map(t, 0.5, .75, 0, 1)));
        antiClockwise1(300, 400,237,91,53,ease(map(t, 0.5, .75, 0, 1)));
        //
        drawCircle2(0, 100, 129,197,64, ease(map(t, 0.5, .75, 0, 1)))
        drawCircle2(0, 300, 22,116,188, ease(map(t, 0.5, .75, 0, 1)))
        drawCircle2(200, 100, 22,116,188, ease(map(t, 0.5, .75, 0, 1)))
        drawCircle2(200, 300, 194,34,134, ease(map(t, 0.5, .75, 0, 1)))
        drawCircle2(400, 100, 194,34,134, ease(map(t, 0.5, .75, 0, 1)))
        drawCircle2(400, 300, 237,91,53, ease(map(t, 0.5, .75, 0, 1)))

    } 
    else if (t < 1) 
    {
        //
        drawCircle(100, 100, 0,163,150, ease(map(t, .75, 1, 0, 1)));
        drawCircle(100, 300, 97,46,141, ease(map(t, .75, 1, 0, 1)));
        drawCircle(300, 100, 97,46,141, ease(map(t, .75, 1, 0, 1)));
        drawCircle(300, 300, 234,34,94, ease(map(t, .75, 1, 0, 1)));
        //
        drawCircle2(200, 0, 0,163,150, 0);
        drawCircle2(200, 200, 97,46,141, 0);
        drawCircle2(200, 400, 234,34,94, 0);
        //
        antiClockwise2(0, 0, 247,182,44, ease(map(t, 0.75, 1, 0, 1)));
        antiClockwise2(0, 200, 0,163,150, ease(map(t, 0.75, 1, 0, 1)));
        antiClockwise2(0, 400,97,46,141, ease(map(t, 0.75, 1, 0, 1)));
        antiClockwise2(400, 0,97,46,141, ease(map(t, 0.75, 1, 0, 1)));
        antiClockwise2(400, 200,234,34,94, ease(map(t, 0.75, 1, 0, 1)));
        antiClockwise2(400, 400,247,182,44, ease(map(t, 0.75, 1, 0, 1)));
        //
        antiClockwise2(100,0, 129,197,64,0);
        antiClockwise2(100,200, 22,116,188,0);
        antiClockwise2(100,400, 194,34,134,0);
        antiClockwise2(300,0, 22,116,188,0);
        antiClockwise2(300,200, 194,34,134,0);
        antiClockwise2(300,400, 237,91,53,0);
        //
        drawCircle(0, 100,129,197,64, 0);
        drawCircle(0, 300,22,116,188, 0);
        drawCircle(200,100,22,116,188, 0);
        drawCircle(200,300,194,34,134, 0);
        drawCircle(400,100,194,34,134, 0);
        drawCircle(400,300,237,91,53, 0);

    }
    pop();
  }
  
  function ease(q) {
    return q * q * 3 - q * q * q * 2;
  }
  
  
  
  function drawCircle(posX, posY, r, g, b, q) {
    noStroke();
    push();
    fill(r, g, b);
    translate(posX, posY);
    rotate(q * HALF_PI);
    arc(0, 0, 100, 100, 0, HALF_PI, PIE);
    arc(0, 0, 100, 100, PI, PI + HALF_PI, PIE);
    pop();
  }
  
  function drawCircle2(posX, posY, r, g, b, q) {
    noStroke();
    push();
    fill(r, g, b);
    translate(posX, posY);
    rotate(q * HALF_PI);
    arc(0, 0, 100, 100, HALF_PI, HALF_PI + HALF_PI, PIE);
    arc(0, 0, 100, 100, PI + HALF_PI, TWO_PI, PIE);
    pop();
  }
  
  
  function antiClockwise1(posX, posY, r, g, b, q) {
  
    noStroke();
    push();
    fill(r, g, b);
    translate(posX, posY);
    rotate(-q * HALF_PI);
    arc(0, 0, 100, 100, HALF_PI, HALF_PI + HALF_PI, PIE);
    arc(0, 0, 100, 100, PI + HALF_PI, TWO_PI, PIE);
    pop();
  
  }
  
  function antiClockwise2(posX, posY, r, g, b, q) {
  
    noStroke();
    push();
    fill(r, g, b);
    translate(posX, posY);
    rotate(-q * HALF_PI - HALF_PI);
    arc(0, 0, 100, 100, HALF_PI, HALF_PI + HALF_PI, PIE);
    arc(0, 0, 100, 100, PI + HALF_PI, TWO_PI, PIE);
    pop();
  
  }

这个例子的实现还有一些问题,有几个蝶形的旋转还有一点点小小的不对,但是今天写这东西实在头太晕了,不想搞了。
效果图:

拓展
第二个图形非常容易拓展成另外的图形。甚至无论修改哪个蝶形的旋转方向(或是旋转速度、停顿时长)都可以催生出不同的图。这是非常有意思的。
比如:

代码也贴出来:

function setup() {
    createCanvas(400, 400);
    //background(0);
  }
  
function draw() {
    noStroke();
    background(0);
    t = (0.018*frameCount)%1;
    push();
    if(t<0.5)
    {
        //第一行
        drawCircleReverse(0,0,246,182,48,ease(map(t,0,0.5,0,1)));
        drawCircleReverse(100,0,129,197,64,ease(map(t,0,0.5,0,1)));
        drawCircle(200,0,1,163,150,ease(map(t,0,0.5,0,1)));
        drawCircleReverse(300,0,22,116,188,ease(map(t,0,0.5,0,1)));
        drawCircleReverse(400,0,97,46,141,ease(map(t,0,0.5,0,1)));
        //第二行
        drawCircle(0, 100, 129,197,64,ease(map(t,0,.5,0,1)));
        drawCircle(100, 100, 1, 163, 150,ease(map(t,0,.5,0,1)));
        drawCircle2(200,100,22, 116, 188,ease(map(t,0,.5,0,1)));
        drawCircle(300, 100, 97, 46, 141,ease(map(t,0,.5,0,1)));
        drawCircle(400, 100, 194,34,134,ease(map(t,0,.5,0,1)));
        //第三行
        drawCircleReverse(0, 200, 1, 163, 150,ease(map(t,0,.5,0,1)));
        drawCircleReverse(100, 200,22,116,188,ease(map(t,0,.5,0,1)));
        drawCircle2(200, 200,97, 46, 141,ease(map(t,0,0.5,0,1)));
        drawCircle2Reverse(300, 200,194,34,134,ease(map(t,0,0.5,0,1)));
        drawCircleReverse(400, 200,234,34,94,ease(map(t,0,0.5,0,1)));
        //第四行
        drawCircle(0,300,22, 116, 188,ease(map(t,0,.5,0,1)));
        drawCircle(100, 300, 97, 46, 141,ease(map(t,0,0.5,0,1)));
        drawCircle2(200, 300, 194,34,134,ease(map(t,0,0.5,0,1)));
        drawCircle(300, 300,234,34,94,ease(map(t,0,0.5,0,1)));
        drawCircle2(400, 300,237,91,53,ease(map(t,0,0.5,0,1)));
        //第五行
        drawCircle2Reverse(0, 400,97, 46, 141,ease(map(t,0,0.5,0,1)));
        drawCircle2Reverse(100,400,194,34,134,ease(map(t,0,0.5,0,1)));
        drawCircle(200,400,234,34,94,ease(map(t,0,0.5,0,1)));
        drawCircle2Reverse(300,400,237,91,53,ease(map(t,0,0.5,0,1)));
        drawCircleReverse(400,400,246,182,48,ease(map(t,0,0.5,0,1)));
    }
    else if(t>0.5)
    {
        //第一行
        drawCircle2Reverse(0,0,246,182,48,ease(map(t,0.5,1,0,1)));
        drawCircle2Reverse(100,0,129,197,64,ease(map(t,0.5,1,0,1)));
        drawCircle2Reverse(200,0,1,163,150,ease(map(t,0.5,1,0,1)));
        drawCircle2Reverse(300,0,22,116,188,ease(map(t,0.5,1,0,1)));
        drawCircle2Reverse(400,0,97,46,141,ease(map(t,0.5,1,0,1)));
        //第二行
        drawCircle2(0, 100, 129,197,64,ease(map(t,0.5,1,0,1)));
        drawCircle2(100, 100, 1, 163, 150,ease(map(t,.5,1,0,1)));
        drawCircle(200,100, 22,116,188,ease(map(t,0.5,1,0,1)));
        drawCircle2(300, 100, 97, 46, 141,ease(map(t,0.5,1,0,1)));
        drawCircle2(400, 100, 194,34,134,ease(map(t,0.5,1,0,1)));
        //第三行
        drawCircle2Reverse(0, 200, 1, 163, 150,ease(map(t,0.5,1,0,1)));
        drawCircle2Reverse(100, 200,22,116,188,ease(map(t,0.5,1,0,1)));
        drawCircleReverse(200, 200,97, 46, 141,ease(map(t,0.5,1,0,1)));
        drawCircleReverse(300, 200,194,34,134,ease(map(t,0.5,1,0,1)));
        drawCircle2Reverse(400, 200,234,34,94,ease(map(t,0.5,1,0,1)));
        //第四行
        drawCircle2(0,300,22, 116, 188,ease(map(t,0.5,1,0,1)));
        drawCircle2(100, 300, 97, 46, 141,ease(map(t,.5,1,0,1)));
        drawCircle(200, 300, 194,34,134,ease(map(t,0.5,1,0,1)));
        drawCircle2(300, 300,234,34,94,ease(map(t,.5,1,0,1)));
        drawCircle(400, 300,237,91,53,ease(map(t,0.5,1,0,1)));
        //第五行
        drawCircleReverse(0, 400,97, 46, 141,ease(map(t,0.5,1,0,1)));
        drawCircleReverse(100,400,194,34,134,ease(map(t,0.5,1,0,1)));
        drawCircle2Reverse(200,400,234,34,94,ease(map(t,0.5,1,0,1)));
        drawCircleReverse(300,400,237,91,53,ease(map(t,0.5,1,0,1)));
        drawCircle2Reverse(400,400,246,182,48,ease(map(t,0.5,1,0,1)));



    }
    else{
        //pauseCircle(0,0,246,182,48,ease(map(t,0.5,1,0,1)));
        pauseCircle(200,100,22,116,188,ease(map(t,0,.5,0,1)));
    }

   
    pop();
  }
  
function ease(q)
{
   return q*q*3-q*q*q*2; 
}
  
function drawCircle(posX, posY, r, g, b,q) {
    noStroke();
    push();
    fill(r, g, b);
    translate(posX,posY);
    rotate(q*HALF_PI);
    arc(0, 0 , 100, 100, 0, HALF_PI, PIE);
    arc(0, 0 , 100, 100, PI, PI + HALF_PI, PIE);
    pop();    
  }
  
function drawCircle2(posX, posY, r, g, b, q) {
    noStroke();
    push();
    fill(r, g, b);
    translate(posX,posY);
    rotate(q*HALF_PI);
    arc(0, 0 , 100, 100, HALF_PI, HALF_PI+HALF_PI, PIE);
    arc(0, 0 , 100, 100, PI+HALF_PI, TWO_PI, PIE);
    pop();
}

function drawCircleReverse(posX, posY, r, g, b, q){
    noStroke();
    push();
    fill(r, g, b);
    translate(posX,posY);
    rotate(-q*HALF_PI);
    arc(0, 0 , 100, 100, 0, HALF_PI, PIE);
    arc(0, 0 , 100, 100, PI, PI + HALF_PI, PIE);
    pop(); 
}

function drawCircle2Reverse(posX, posY, r, g, b, q) {
    noStroke();
    push();
    fill(r, g, b);
    translate(posX,posY);
    rotate(-q*HALF_PI);
    arc(0, 0 , 100, 100, HALF_PI, HALF_PI+HALF_PI, PIE);
    arc(0, 0 , 100, 100, PI+HALF_PI, TWO_PI, PIE);
    pop();
}

function pauseCircle(posX, posY, r, g, b,q) {
    noStroke();
    push();
    fill(r, g, b);
    translate(posX,posY);
    //rotate(0);
    arc(0, 0 , 100, 100, 0, HALF_PI, PIE);
    arc(0, 0 , 100, 100, PI, PI + HALF_PI, PIE);
    pop();    
  }

不写了不写了。太累了。

你可能感兴趣的:(p5.js,码绘)