用canvas画一颗花心

jopen 8年前

一、心形函数

function getHeartPoint(angle) {/*agnle=10*/   var t = angle / Math.PI;   var x = 19.5 * (16 * Math.pow(Math.sin(t), 3))*chen;   var y = - 20 * (13 * Math.cos(t) - 5 * Math.cos(2 * t) - 2 * Math.cos(3 * t) - Math.cos(4 * t))*chen;   return {x:offsetX + x, y:offsetY + y};  }

二、用贝叶斯曲线画出花朵

function Vector(x,y){   this.x=x;   this.y=y;  }  Vector.prototype={   rotate:function(theta){    var x = this.x;    var y = this.y;    this.x = Math.cos(theta) * x - Math.sin(theta) * y;    this.y = Math.sin(theta) * x + Math.cos(theta) * y;    return this;   },   mult:function(f){    this.x *= f;    this.y *= f;    return this;   },   clone:function(){    return new Vector(this.x,this.y);   }  }    function Petal(xadd,yadd,startAngle,angle,grow){   this.xadd=xadd;   this.yadd=yadd;   this.startAngle=startAngle;   this.angle=angle;   this.grow=grow;   this.r=1;  }    Petal.prototype={   draw:function(){/*r控制里面空白的大小,angle控制花瓣的数量,startAngle控制起始花瓣的位置,mult方法用来计算出两个控制点的位置*/    var v1, v2, v3, v4;    v1 = new Vector(0, this.r).rotate(this.startAngle * 2 * Math.PI /360);    v2 = v1.clone().rotate(this.angle * 2 * Math.PI /360);    v3 = v1.clone().mult(this.xadd); //.rotate(this.tanAngleA);    v4 = v2.clone().mult(this.yadd); //.rotate(this.tanAngleB);        ctx.strokeStyle = 'rgba('+getRandInt(128,255)+','+getRandInt(0,128)+','+getRandInt(0,128)+',0.1)';    ctx.beginPath();    ctx.lineWidth=1;    ctx.moveTo(v1.x, v1.y);    ctx.bezierCurveTo(v3.x, v3.y, v4.x, v4.y, v2.x, v2.y);    ctx.stroke();   },   update:function(){    if(this.r<=10){     this.draw();     this.r+=this.grow;    }else{     petals.splice(petals.indexOf(this),1);    }   }  }    /*页面加载时启动动画*/  window.onload=function(){   ctx.translate(200, 200);   //ctx.globalCompositeOperation='lighter';   for(var i=0;i<count;i++){    var p=new Petal(getRandInt(3,8),getRandInt(3,8),startAngle,angle,getRand(0.3,0.5));    petals.push(p);    startAngle+=angle;    p.update();   }   setInterval(function(){    for(var i=0;i<petals.length;i++){     petals[i].update();    }   },100);  }

三、把花朵绘到心形函数的路径上,最终代码

var cas=document.getElementById('cas'), ctx=cas.getContext('2d');  cas.width=600;  cas.height=700,  count=getRandInt(8,15),  angle=360/count,  petals=[],  startAngle=getRandInt(0,90),  chen=0.8,  offsetX=300,  offsetY=300,  dots=[],  timer1=0,  timer2=0;    window.onload=function(){      var vector={},i=10;   timer1=setInterval(function(){    vector=getHeartPoint(i);    dots.push(new Dot(vector.x,vector.y));    if(i<30){     i+=0.3    }else{     clearInterval(timer1);    }   },100);      timer2=setInterval(function(){    for(var i=0;i<dots.length;i++){     dots[i].draw();    }   });  }    function Dot(x,y){   this.transX=x;   this.transY=y;   this.petals=[];   this.init();  }  Dot.prototype={   init:function(){    for(var i=0;i<count;i++){     var color=getRGBA(255,128,128,0,128,0,0.1);     var p=new Petal(getRandInt(1,5),getRandInt(1,5),startAngle,angle,getRand(0.1,0.5),color);     this.petals.push(p);     startAngle+=angle;     //p.update();    }   },   draw:function(){    ctx.save();    ctx.translate(this.transX, this.transY);    for(var i=0;i<this.petals.length;i++){     this.petals[i].update();    }    ctx.restore();   }  }    function rgbaStr(r, g, b, a) {    return 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';   };  function getRGBA(rmin, rmax, gmin, gmax, bmin, bmax, a) {   var r = Math.round(getRand(rmin, rmax));   var g = Math.round(getRand(gmin, gmax));   var b = Math.round(getRand(bmin, bmax));   var limit = 5;   if (Math.abs(r - g) <= limit && Math.abs(g - b) <= limit && Math.abs(b - r) <= limit) {    return rgbaStr(rmin, rmax, gmin, gmax, bmin, bmax, a);   } else {    return rgbaStr(r, g, b, a);   }  };  function getHeartPoint(angle) {/*agnle=10*/   var t = angle / Math.PI;   var x = 19.5 * (16 * Math.pow(Math.sin(t), 3))*chen;   var y = - 20 * (13 * Math.cos(t) - 5 * Math.cos(2 * t) - 2 * Math.cos(3 * t) - Math.cos(4 * t))*chen;   return {x:offsetX + x, y:offsetY + y};  }  function Vector(x,y){   this.x=x;   this.y=y;  }  Vector.prototype={   rotate:function(theta){    var x = this.x;    var y = this.y;    this.x = Math.cos(theta) * x - Math.sin(theta) * y;    this.y = Math.sin(theta) * x + Math.cos(theta) * y;    return this;   },   mult:function(f){    this.x *= f;    this.y *= f;    return this;   },   clone:function(){    return new Vector(this.x,this.y);   }  }    function Petal(xadd,yadd,startAngle,angle,grow,color){   this.xadd=xadd;   this.yadd=yadd;   this.startAngle=startAngle;   this.angle=angle;   this.grow=grow;   this.c=color;   this.r=1;  }    Petal.prototype={   draw:function(){/*r控制里面空白的大小,angle控制花瓣的数量,startAngle控制起始花瓣的位置,mult方法用来计算出两个控制点的位置*/    var v1, v2, v3, v4;    v1 = new Vector(0, this.r).rotate(this.startAngle * 2 * Math.PI /360);    v2 = v1.clone().rotate(this.angle * 2 * Math.PI /360);    v3 = v1.clone().mult(this.xadd); //.rotate(this.tanAngleA);    v4 = v2.clone().mult(this.yadd); //.rotate(this.tanAngleB);    ctx.beginPath();    ctx.strokeStyle = this.c;    console.log(ctx.strokeStyle);        ctx.lineWidth=1;    ctx.moveTo(v1.x, v1.y);    ctx.bezierCurveTo(v3.x, v3.y, v4.x, v4.y, v2.x, v2.y);    ctx.stroke();   },   update:function(){    if(this.r<8){     this.draw();     this.r+=this.grow;    }else{     petals.splice(petals.indexOf(this),1);    }   }  }    function getRandInt(min,max){   return Math.floor(Math.random()*(max-min)+min);  }  function getRand(min,max){   return Math.random()*(max-min)+min;  }


来自: http://my.oschina.net/codespring/blog/596311