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