p5实现一个可交互跟随鼠标的蝴蝶动画效果代码

代码语言:html

所属分类:动画

代码描述:p5实现一个可交互跟随鼠标的蝴蝶动画效果代码

代码标签: p5 交互 跟随 鼠标 蝴蝶 动画

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en" >

<head>

  <meta charset="UTF-8">
  

  
  



</head>

<body  >

<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/p5.1.4.0.js"></script>
  
      <script  >

if(typeof Float32Array != 'undefined') {
        glMatrixArrayType = Float32Array;
} else if(typeof WebGLFloatArray != 'undefined') {
        glMatrixArrayType = WebGLFloatArray; // This is officially deprecated and should dissapear in future revisions.
} else {
        glMatrixArrayType = Array;
}
const colors = [[255,0,255,229],[255,0,255,204],[255,0,255,178],[255,0,255,153]];
let path;
let Width , Height;
let canvas , ctx , time;
let body,left,rigth;
let Butterflys = [];
let trans , angle , scale ,vector, Mouse = {x:0 , y:0};
let stars = [] , stasNumbre = 0;
function preload() {
    let url = 'https://hankuro.org/json/pathdata.json';
    path = loadJSON(url);
}
function setup() {
  canvas = createCanvas(windowWidth, windowHeight);
  Width = windowWidth;
  Height = windowHeight;
  ctx = canvas.drawingContext;
  time = new Date().getTime();
  
  body = new BodyButterfly(path.body,true);
  left = new LeftButterfly(path.left,false);
  rigth = new RigthButterfly(path.rigth,false);
  Butterflys.push(body,left,rigth);
  trans = new Vretex();
  angle = new Vretex();
  scale = new Vretex([1,1,1]);
  
//  star = new Star(sOfEnd);
//  star.setPosition(trans);
}

function draw() {
    applyMatrix(1, 0, 0, 1, Width/2, Height/2);
    clear();
    stroke(0, 0, 0);
    strokeWeight(0.5); 
    fill(0,0,0);
    Mouse.x = mouseX-(width/2) ;
    Mouse.y = mouseY-(height/2) ;
    let m = new Vretex([Mouse.x,Mouse.y,0]);
    
    vector = m.Subtraction(trans);    
    vector = vector.division(200);
    
    let dx = Mouse.x - trans.x;
    let dy = Mouse.y - trans.y;    
    let r = Math.atan2(dy,dx);
   trans = trans.Add(vector) ;
   
   
//   line(trans.x,trans.y,vector.x,vector.y);
//     ellipse(0, 0, 5, 5);
   
//    trans = trans.Add(vector);
//    console.log(trans);
    Butterflys.forEach((b)=>{
//        angle.x = 0 * Math.PI/180 ;
        angle.z = r + 90 * Math.PI / 180;
        trans.multiplication(1000);
        b.postVretex(Mouse,trans);
        b.setMatrix(trans,angle,scale);
        b.draw();
    });
    
    let Flapping = Butterflys[0].Flapping;
    let now = new Date().getTime();
    if(now - time > 1500){
        
        if(Flapping) stars.push(new StarControl(trans,sOfEnd,stasNumbre++));
        time = now;
    }
    stars.forEach((s)=>{
        if(!s.Dead) s.draw();
    });
//    star.draw();
//    rotate(r);
//    line(0,0,100,0);
}

function windowResized() {
  resizeCanvas(windowWidth, windowHeight);
  Width = windowWidth;
  Height = windowHeight;
  ctx = canvas.drawingContext;
}


function sOfEnd(o){
    let int = o.index;
    let index;
    stars.forEach((s,i)=>{
        if(s.index == int) {
            index = i;
        }
    });
    delete stars[index];
   
}

class Butterfly{
    constructor(p,f){
        this.matrix = new Matrix4().identity();
        this.angle = 0;
        this.ptterns = [];
        this.Flapping = false;
        for(let i=0;i<p.length;i++){
            this.ptterns.push(new WingpPttern(p[i],f));
        }
    }
    postVretex(m,t){
        if(m.y < t.y) this.Flapping = true;
        else this.Flapping = false;
    }
    setMatrix(t,a,s){}    
    draw(){        
         this.ptterns.forEach((p)=>{
            p.draw(this.matrix);
        });
    }
}

class WingpPttern{
    constructor(p,f){
        this.fill = f;
        this.types = [];
        this.d = [];
        let index = 0;
        let end = true;
        let type = 0;
        let cnt = 0;
        let cu = [];
        while (end) {
            let c = p[index];
            
            if(c.length == 1){
                switch (c){
                   case "M": type = 0; break;
                   case "L": type = 1; break;
                   case "C": type = 2; cnt = 0; break;
                   case "Z": type = 3; this.types.push(type) ;break;
                }
                index++;
            }else{
                
                switch (type) {
                    case 0: this.d.push(new PathD('M',new MoveTo(c))) ; this.types.push(type) ; break;
                    case 1: this.d.push(new PathD('L',new LineTo(c))) ; this.types.push(type) ; break;
                    case 3: this.types.push(type) ; break;
                    default:
                        cu.push(c);
                        cnt++;
                        if(cnt == 3){
                            
                            this.d.push(new PathD('C',new BezierCurveTo(cu))) ;
                            this.types.push(type) ;
                            cu = [];
                            cnt = 0;
                        }
                        
                        break;
                }
                index++;
            }
            if (p.length == index) end = false;
        }
    }
    draw(m){
        let path = new Path2D();
        let v;
        
        this.d.forEach((d,i)=>{
            switch (this.types[i]) {
                case 0:
                    v = this.chengFloat(d.moveto.matrixMultiplication(m));
                    path.moveTo(v[0],v[1]);
                    break;
                case 1:
                    v = this.chengFloat(d.lineto.matrixMultiplication(m));
                    path.lineTo(v[0],v[1]);
                    break;
                case 2:
                    v = this.chengFloat(d.curveto.matrixMultiplication(m));
                    path.bezierCurveTo(v[0],v[1],v[2],v[3],v[4],v[5]);
                    break;
            }
        });
        if(this.types[this.types.length-1] == 3) {
            if(this.fill){
                path.closePath();
                ctx.fill(path);
            }
        }
        ctx.stroke(path);
    }
    chengFloat(s){
        let d = s.split(",");
        let f = [];
        d.forEach((v)=>{
            f.push(parseFloat(v));
        });
        return f;
    }
}

class PathD{
    constructor(t,p){
        switch (t) {
            case 'M': this.type=0; this.moveto = p;   break;
            case 'L': this.type=1; this.lineto = p;   break;
            case 'C': this.type=2; this.curveto = p;   break;
            case 'Z': this.type=3; break;
        }
    }
    
}

class BodyButterfly extends Butterfly{
    constructor(p,f){
        super(p,f);
    }
    setMatrix(t,a,s){
        this.matrix.identity();
        this.matrix.scale(s);
        this.matrix.translate(t);
        this.matrix.rotateX(a.x);
        this.matrix.rotateY(a.y);
        this.matrix.rotateZ(a.z);
    }
}

class LeftButterfly extends Butterfly{
    constructor(p,f){
        super(p,f);
        this.wingL = 0;
        this.a = 0;
        
    }
   
    setMatrix(t,a,s){
        if(this.Flapping) this.wingL += 0.25;
        else this.wingL += 0.05;
        this.matrix.identity();
        this.matrix.scale(s);
        this.matrix.translate(t);
        this.matrix.rotateX(a.x);
        this.matrix.rotateZ(a.z);
        this.matrix.rotateY((Math.sin(this.wingL)*70)*Math.PI/180);
        
    }
}

class RigthButterfly extends Butterfly{
    constructor(p,f){
        super(p,f);
        this.wingR = 0;
        
    }
    setMatrix(t,a,s){
        if(this.Flapping) this.wingR += 0.25;
        else this.wingR += 0.05;
        this.matrix.identity();
        this.matrix.scale(s);
        this.matrix.translate(t);
        this.matrix.rotateX(a.x);
        this.matrix.rotateZ(a.z);
        this.matrix.rotateY((Math.sin(this.wingR+Math.PI)*70)*Math.PI/180);
    }
}

class MoveTo{
    constructor(p){
        let d = p.split(' ');
        let x = parseFloat(d[0]) / 10;
        let y = parseFloat(d[1]) / 10;
        this.moveto = new Vretex([x,y,0]);
    }
    matrixMultiplication(m){
        let v = this.moveto.MatrixMultiplication(m);
        return v.getScrrenPoint().string;
    }
}
class LineTo{
    constructor(p){
        let d = p.split(' ');
        let x = parseFloat(d[0]) / 10;
        let y = parseFloat(d[1]) / 10;
        this.lineto = new Vretex([x,y,0]);
    }
    matrixMultiplication(m){
        let v = this.lineto.MatrixMultiplication(m);
        return v.getScrrenPoint().s.........完整代码请登录后点击上方下载按钮下载查看

网友评论0