用canvas画一颗花心

一、心形函数

162302_mjSF_1475179.png

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};
}

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

162312_9cVR_1475179.png

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);
}

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

162311_Qdd1_1475179.png

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;
}


转载于:https://my.oschina.net/codespring/blog/596311

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值