您的位置:首页 > Web前端 > JavaScript

P5.js完成动态旋转图的临摹和创作

2020-01-12 15:39 281 查看

P5.js完成动态图的临摹和创作

  • 完成效果展示
  • 拓展
  • 图片的临摹选择

    开始临摹

    首先,我们可以发现图片由从内到外的八个不同颜色的圈构成,每个圈又拥有不同数量的小球。
    通过观察,可以发现:
    1.最内圈有四个小球,每往外一圈,小球数量就增加四个。
    2.小球均以顺时针,固定角速度进行运动。

    初步实现

    设置随时间变化的变量以实现小球旋转动态。

    background(0);
    var dx=0
    dx+=PI/180;
    var t=-(millis()/5)*sin(dx);
    var num=4;
    //num为计算每层小球数量的变量

    实现一层小球绕中心转动,每一层的小球都均匀分布在该圈圆圈上。
    从第一层开始循环八次,由于需要分层为小球颜色赋值,没有直接使用两个for循环。

    for(var j=1;j<=num;j++)
    {
    fill(24,110,178);
    //为小球颜色赋值
    translate(width/2, height/2);
    rotate(-t*5);
    var cl=(PI/num)*j*2;
    ellipse((cos(cl))*(num*6),(sin(cl))*(num*6),10,(num-num)*0.25+10);
    resetMatrix();
    }
    num+=4;

    此时已经基本可以实现原图的基本样子了。

    细节添加

    角速度区别修改

    仔细观察原图,我们可以发现,原图的小球转动角速度是由内到外不断减小的,我们就需要根据内外圈对其速度进行调整,这个简单,只需要对for循环中的rotate函数进行修改即可。

    改为:

    rotate(-t*5/num);

    修改后,越靠近外圈的小球,转速就会越慢了。

    起始点位置修改

    继续对原图进行观察,就可以发现,原图各圈小球的位置是错开的,起始点位置并不是完全对齐,是根据圆圈均匀分布错开的,直接旋转,就容易造成转成十字形的形状。

    这个问题,就需要修改小球的生成函数的起始位置了,改为:

    var cl=(PI/num)*j*2+PI*num/32;

    起始点的位置就会随圈的不同而错开了。

    为小球添加动态特效

    从原图可以观察得到,越靠近外圈,小球就会拉出更多轨迹,呈对称轴垂直于圆心的椭圆形,本来我的实现方法是生成随外圈半径变长的椭圆,但是效果非常僵硬,经过对于其他文章的参考,我采取了更好的方法,即生成时在非常靠近小球的圆圈轨道上位置,同样生成3-4个小球,小球叠在一起进行旋转,就会产生动态轨迹效果。代码如下:

    for(var k=1;k<num;k++)
    {
    fill(24,110,178);
    translate(width/2, height/2);
    rotate(-t*5/num);
    var cl=(PI/num)*j*2+PI*num/32+(PI/num)*k*0.008;
    ellipse((cos(cl))*(num*6),(sin(cl))*(num*6),10,(num-num)*0.25+10);
    resetMatrix();
    }
    //是上文的代码的子循环

    完成效果展示

    修改过细节后,和原图已经非常相似了,这是最后生成的样子:

    拓展

    完成后,在原来的代码上添加了新的效果:通过修改圆的半径随时间的流逝而变大形成爆炸效果。
    当爆炸超出屏幕时再进行回缩。
    实现较为简单,只需要修改半径随时间t而变化即可,当到达限度时再将t放至半径的分母位置。

    代码如下:

    if(-t*0.3<-30/t)
    {
    rotate(-t*5/num);
    var cl=(PI/num)*j*2+PI*num/32+(PI/num)*k*0.008;
    ellipse((cos(cl))*(-t*0.3)*(num*6),(sin(cl))*(-t*0.3)*(num*6),10,(num-num)*0.25+10);
    }
    else
    {
    rotate(t*5/num);
    var cl=(PI/num)*j*2+PI*num/32+(PI/num)*k*0.008;
    ellipse((cos(cl))*(-30/t)*(num*6),(sin(cl))*(-30/t)*(num*6),10,(num-num)*0.25+10);
    }
    //t是时间变量

    完成效果展示

    gif录制问题,存在一点卡顿

    源代码展示

    function setup()
    
    {
    
    createCanvas(600,600);
    
    frameRate(150);
    
    }
    
    function draw()
    
    {
    
    background(0);
    
    var dx=0
    
    dx+=PI/180;
    
    var t=-(millis()/5)*sin(dx);
    
    var num=4;
    
    for(var j=1;j<=num;j++)
    
    {
    
    for(var k=1;k<num;k++)
    
    {
    
    fill(24,110,178);
    
    translate(width/2, height/2);
    
    rotate(-t*5/num);
    
    var cl=(PI/num)*j*2+PI*num/32+(PI/num)*k*0.008;
    
    ellipse((cos(cl))*(num*6),(sin(cl))*(num*6),10,(num-num)*0.25+10);
    
    resetMatrix();
    
    }
    
    }
    
    num+=4;
    
    for(var j=1;j<=num;j++)
    
    {
    
    for(var k=1;k<num;k++)
    
    {
    
    fill(0,164,150);
    
    translate(width/2, height/2);
    
    rotate(-t*5/num);
    
    var cl=(PI/num)*j*2+PI*num/32+(PI/num)*k*0.008;
    
    ellipse((cos(cl))*(num*6),(sin(cl))*(num*6),10,(num-num)*0.25+10);
    
    resetMatrix();
    
    }
    
    }
    
    num+=4
    
    for(var j=1;j<=num;j++)
    
    {
    
    for(var k=1;k<num;k++)
    
    {
    
    fill(130,197,64);
    
    translate(width/2, height/2);
    
    rotate(-t*5/num);
    
    var cl=(PI/num)*j*2+PI*num/32+(PI/num)*k*0.008;
    
    ellipse((cos(cl))*(num*6),(sin(cl))*(num*6),10,(num-num)*0.25+10);
    
    resetMatrix();
    
    }
    
    }
    
    num+=4;
    
    for(var j=1;j<=num;j++)
    
    {
    
    for(var k=1;k<num;k++)
    
    {
    
    fill(236,175,45);
    
    translate(width/2, height/2);
    
    rotate(-t*5/num);
    
    var cl=(PI/num)*j*2+PI*num/32+(PI/num)*k*0.008;
    
    ellipse((cos(cl))*(num*6),(sin(cl))*(num*6),10,(num-num)*0.25+10);
    
    resetMatrix();
    
    }
    
    }
    
    num+=4;
    
    for(var j=1;j<=num;j++)
    
    {
    
    for(var k=1;k<num;k++)
    
    {
    
    fill(228,88,52);
    
    translate(width/2, height/2);
    
    rotate(-t*5/num);
    
    var cl=(PI/num)*j*2+PI*num/32+(PI/num)*k*0.008;
    
    ellipse((cos(cl))*(num*6),(sin(cl))*(num*6),10,(num-num)*0.25+10);
    
    resetMatrix();
    
    }
    
    }
    
    num+=4;
    
    for(var j=1;j<=num;j++)
    
    {
    
    for(var k=1;k<num;k++)
    
    {
    
    fill(201,35,82);
    
    translate(width/2, height/2);
    
    rotate(-t*5/num);
    
    var cl=(PI/num)*j*2+PI*num/32+(PI/num)*k*0.008;
    
    ellipse((cos(cl))*(num*6),(sin(cl))*(num*6),10,(num-num)*0.25+10);
    
    resetMatrix();
    
    }
    
    }
    
    num+=4;
    
    for(var j=1;j<=num;j++)
    
    {
    
    for(var k=1;k<num;k++)
    
    {
    
    fill(194,34,134);
    
    translate(width/2, height/2);
    
    rotate(-t*5/num);
    
    var cl=(PI/num)*j*2+PI*num/32+(PI/num)*k*0.008;
    
    ellipse((cos(cl))*(num*6),(sin(cl))*(num*6),10,(num-num)*0.25+10);
    
    resetMatrix();
    
    }
    
    }
    
    num+=4;
    
    for(var j=1;j<=num;j++)
    
    {
    
    for(var k=1;k<num;k++)
    
    {
    
    fill(84,44,121);
    
    translate(width/2, height/2);
    
    rotate(-t*5/num);
    
    var cl=(PI/num)*j*2+PI*num/32+(PI/num)*k*0.008;
    
    noStroke();
    
    ellipse((cos(cl))*(num*6),(sin(cl))*(num*6),10,(num-num)*0.25+10);
    
    resetMatrix();
    
    }
    
    }
    
    num+=4;
    
    }
    • 点赞
    • 收藏
    • 分享
    • 文章举报
    斑驳斓杂 发布了7 篇原创文章 · 获赞 0 · 访问量 137 私信 关注
    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: