基于P5.js的创意交互自画像(状态切换实现变身效果)

创意交互GIF图展示

在这里插入图片描述

交互功能与相应代码介绍

①运行程序后是一只狐狸,此时的交互为鼠标位置的改变会改变狐狸尾巴的位置 每个狐狸尾巴的颜色也会做相位不同的周期性变换,相应的代码如下:

//尾巴
      push();
        fill(color(254,60+60*sin(theta),2,255/colorRate));
        translate(70,10);
        rotate( PI/15+0.5*sin(mouseX/100));
        triangle(0, 0, 90, -150, 230, -175);
  
        fill(color(254,60+60*sin(theta+PI/6),2,255/colorRate));
        rotate( PI/15+0.5*sin(mouseX/100));
        triangle(0, 0, 90, -150, 230, -175);
  
        fill(color(254,60+60*sin(theta+PI/3),2,255/colorRate));
        rotate( PI/15+0.5*sin(mouseX/100));
        scale(0.9);
        triangle(0, 0, 90, -150, 230, -175);
  
        fill(color(254,60+60*sin(theta+PI/2),2,255/colorRate));
        rotate( PI/15+0.5*sin(mouseX/100));
        scale(0.9);
        triangle(0, 0, 90, -150, 230, -175);
      pop();

②当单机鼠标左键的时候进入下一个状态,即“影分身”状态:
此时先前的狐狸图像消失,取而代之的是四个alpha值变为原来四分之一的狐狸分身,并做向外部四个方向散发的周期性运动,一共循环运动三次,代码如下:

  if(boolState==1){
  drawBg(theta);
  background(0);
  push();
  fill(color(200,200,200,255/5));
  translate(Math.ceil(-200*sin(theta)), Math.ceil(-200*sin(theta)));
  drawFox(4); 
  pop();
  
  push();
  translate(Math.ceil(200*sin(theta)), Math.ceil(200*sin(theta)));
  //rotate(theta);
  drawFox(4); 
  pop();
    
  push();
  fill(color(200,200,200,255/5));
  translate(Math.ceil(-200*sin(theta)), Math.ceil(200*sin(theta)));
  //rotate(theta);
  drawFox(4);   
  pop();
    
  push();
  fill(color(200,200,200,255/5));
  translate(Math.ceil(200*sin(theta)), Math.ceil(-200*sin(theta)));
  //rotate(theta);
  drawFox(4);   
  pop();
  if(theta<6*HALF_PI){theta=theta+0.15;}
  if(theta>=6*HALF_PI){drawMan(1);  
  theta=theta+0.15;
                      }
  }

③“影分身”状态结束之后进入变身后的形象,变为“神祗”,“神祗”的“太阳背景”做交替性闪烁,身后的由大到小的“九个尾巴”做周期性的加速减速运动,产生华丽的效果。代码如下:

translate(300,300);
    //画背景九尾狐
    strokeWeight(0);
    push();
    for(let i=0;i<30;i++){
    fill(color(254,60+60*sin(theta+PI/2*i),0,120));
//fill(color(254,60+60*sin(theta+PI/6),2,255/colorRate));
    
    translate(0,0);
    rotate( PI/(4+4*sin(theta/10)));
    
    scale(1.08);
    beginShape();
    vertex(0,0);
    bezierVertex(-10,-40,-30,20,-40,-40);
    bezierVertex(-30,40,-10,30,0,0);
    endShape();}

④此时在次点击鼠标左键,画面由“神祗‘再次变为最初的狐狸。

注意事项

创造闭合贝塞尔曲线图形的代码格式基本格式如下:

    beginShape();
    vertex(80,-180);
    bezierVertex(-340,0,-60,180,160,-80);
    bezierVertex(-60,65,-240,0,80,-180);
    endShape();

如果想要加更多的点,可以多加一句bezeirVertex:

    //眉心
    strokeWeight(1);
    fill(color(255,0,0,255/colorRate));
    beginShape();
    vertex(20,-100);
    bezierVertex(-100,-40,-40,20,40,-60);
    bezierVertex(-30,-20,-50,-30,20,-80);
    bezierVertex(-30,-40,-60,-50,20,-100);
    endShape();

然后下面的代码可以先确定要旋转的中心,然后进行旋转缩放,每重复一次,旋转缩放一次;

    translate(0,0);
    rotate( PI/(4+4*sin(theta/10)));
    scale(1.08);

切身感受

本次实验的的自由度很高,进行自由的艺术创作感觉也很棒,除了在贝塞尔曲线上面有点费劲,画点有点费劲,其他还好

源代码

let theta;
let boolState;
let colorRate;
function setup() {
  createCanvas(600, 600);
  theta=0;
  boolState=0;
  colorRate=1;
}

function draw() {
  //noStroke();
  if(boolState==0){
  background(0);
  //画狐狸主体
  drawFox(1);
  //drawMan(1);
  theta=theta+0.1;
  }
  if(boolState==1){
  drawBg(theta);
  background(0);
  push();
  fill(color(200,200,200,255/5));
  translate(Math.ceil(-200*sin(theta)), Math.ceil(-200*sin(theta)));
  drawFox(4); 
  pop();
  
  push();
  translate(Math.ceil(200*sin(theta)), Math.ceil(200*sin(theta)));
  //rotate(theta);
  drawFox(4); 
  pop();
    
  push();
  fill(color(200,200,200,255/5));
  translate(Math.ceil(-200*sin(theta)), Math.ceil(200*sin(theta)));
  //rotate(theta);
  drawFox(4);   
  pop();
    
  push();
  fill(color(200,200,200,255/5));
  translate(Math.ceil(200*sin(theta)), Math.ceil(-200*sin(theta)));
  //rotate(theta);
  drawFox(4);   
  pop();
  if(theta<6*HALF_PI){theta=theta+0.15;}
  if(theta>=6*HALF_PI){drawMan(1);  
  theta=theta+0.15;
                      }
  }
}


function drawBg(theta){
  let c=color(5*mouseX*cos(theta*2)/length,255*mouseY*sin(theta*3)/width,510*sin(theta*20)*mouseX/length,255*mouseY*cos(theta*2)/width); 
  background(c);
}

function mouseClicked()
{
  if(boolState==0){
    boolState=1;
    theta=0;
  }
  else if(boolState==1){
    boolState=0;
    theta=0;
  }
}


function drawMan(colorRate)
{
   push();
    translate(300,300);
    //画背景九尾狐
    strokeWeight(0);
    push();
    for(let i=0;i<30;i++){
    fill(color(254,60+60*sin(theta+PI/2*i),0,120));
//fill(color(254,60+60*sin(theta+PI/6),2,255/colorRate));
    
    translate(0,0);
    rotate( PI/(4+4*sin(theta/10)));
    
    scale(1.08);
    beginShape();
    vertex(0,0);
    bezierVertex(-10,-40,-30,20,-40,-40);
    bezierVertex(-30,40,-10,30,0,0);
    endShape();}
    pop();
  
  
    //画黑圆圈
    fill(255*sin(theta),0,0,255/colorRate);
    
    circle(0,0,300);
    
    //轮廓
    noFill();
    strokeWeight(3);
    stroke(color(255,0,0,255/colorRate));
    line(-100,20,-92,55);
    line(-92,55,-85,60);
    line(-85,60,-95,107);
    bezier(-95,107,-90,110,-80,110,-70,107);
    line(-70,107,-65,115);
    line(-65,115,-60,113);
    line(-60,113,-63,116);
    bezier(-63,116,-65,116,-55,130,-45,136);
    bezier(-45,136,-25,140,50,100,40,50);
    bezier(40,50,50,20,60,20,70,10);
    bezier(70,10,80,0,90,-50,110,-80);
    bezier(110,-80,80,-50,60,-80,0,20);
    bezier(110,-80,80,-50,60,-80,0,20);
    //填充 
    
    //眼睛
    strokeWeight(1);
    fill(color(255,0,0,255/colorRate));
    beginShape();
    vertex(-65,65);
    bezierVertex(-60,80,-50,80,-20,50);
    bezierVertex(-40,70,-60,65,-65,65);
    endShape();
  
    //头环
    strokeWeight(1);
    fill(color(255,0,0,255/colorRate));
    beginShape();
    vertex(80,-180);
    bezierVertex(-340,0,-60,180,160,-80);
    bezierVertex(-60,65,-240,0,80,-180);
    endShape();
    
    //眉心
    strokeWeight(1);
    fill(color(255,0,0,255/colorRate));
    beginShape();
    vertex(20,-100);
    bezierVertex(-100,-40,-40,20,40,-60);
    bezierVertex(-30,-20,-50,-30,20,-80);
    bezierVertex(-30,-40,-60,-50,20,-100);
    endShape();

  pop();
}

function drawFox(colorRate)
{
   push();
    translate(300,300);
    push();
    fill(color(255,0,0,255/colorRate));
    //脚趾头
    noStroke();
    triangle(-90,80,-110,110,-90,110);
    triangle(50,80,30,110,50,110);

    fill(color(254,60,2,255/colorRate));
    ellipse(-90,50,40,100);//腿
    ellipse(50,50,40,100);//腿
    //尾巴
      push();
        fill(color(254,60+60*sin(theta),2,255/colorRate));
        translate(70,10);
        rotate( PI/15+0.5*sin(mouseX/100));
        triangle(0, 0, 90, -150, 230, -175);
  
        fill(color(254,60+60*sin(theta+PI/6),2,255/colorRate));
        rotate( PI/15+0.5*sin(mouseX/100));
        triangle(0, 0, 90, -150, 230, -175);
  
        fill(color(254,60+60*sin(theta+PI/3),2,255/colorRate));
        rotate( PI/15+0.5*sin(mouseX/100));
        scale(0.9);
        triangle(0, 0, 90, -150, 230, -175);
  
        fill(color(254,60+60*sin(theta+PI/2),2,255/colorRate));
        rotate( PI/15+0.5*sin(mouseX/100));
        scale(0.9);
        triangle(0, 0, 90, -150, 230, -175);
      pop();
    fill(color(254,100,2,255/colorRate));
    ellipse(-10,30,180,80);//躯干
    triangle(-70,80,-90,110,-70,110);
    triangle(70,80,50,110,70,110);
    fill(color(254,85,2,255/colorRate));
    ellipse(-70,50,40,100);//腿
    ellipse(70,50,40,100);//腿
    //头
    push();
    noStroke();
    //translate(0,0);
    //rotate( PI/15+0.5*sin(mouseX/100));
    fill(color(254,100,2,255/colorRate));
    beginShape();
    vertex(-40, -100);
    vertex(-50, -100);
    vertex(-60, -140);
    vertex(-80, -120);
    vertex(-90, -100);
    vertex(-110, -90);
    vertex(-140, -60);
    vertex(-120, -60);
    vertex(-130, -50);
    vertex(-120, -54);
    vertex(-120, 0);//鼻子
    vertex(-70, 0);
    vertex(-70, 10);
    vertex(-60, 0);
    vertex(-60, 20);
    vertex(-40, 00);
    vertex(-30, -10);
    vertex(-20, -30);
    vertex(0, -40);
    vertex(20, -60);
    vertex(-20, -70);
    vertex(-20, -80);
    endShape(CLOSE);
  
    fill(color(255,0,0,255/colorRate));//红色眉心
    beginShape();
    vertex(-60, -80);
    vertex(-60, -60);
    vertex(-40, -60);
    vertex(-47, -67);
    vertex(-40, -80);
    vertex(-54, -74);
    endShape(CLOSE);
  
    fill(color(255,0,0,255/colorRate));//红色左眼
    beginShape();
    vertex(-94, -80);
    vertex(-100, -60);
    vertex(-90, -50);
    endShape(CLOSE);
  
    fill(color(255,0,0,255/colorRate));//红色右眼
    beginShape();
    vertex(-40, -27);
    vertex(-60, -20);
    vertex(-70, -30);
    endShape(CLOSE);
    
    fill(color(255,0,0,255/colorRate));//红色眉
    beginShape();
    vertex(-80, -90);
    vertex(-87, -40);
    vertex(-120, -10);
    vertex(-110, 0);
    vertex(-80, -34);
    vertex(-30, -40);
    vertex(-74, -47);
    endShape(CLOSE);
  
    fill(color(255,0,0,255/colorRate));//红鼻子
    circle(-120,0,20);
    pop();
  
    pop();
  
  
  //rotate(theta); 
  pop();
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值