玩玩Canvas高阶贝塞尔曲线动画

原创 2014年07月20日 13:40:08
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title> new document </title>
<style type="text/css">
#canvasId {	border: #6666ff 1px solid; position: absolute; top:60px; left:10px; }
#text {	width: 600px; }
</style>
</head>
<body>
<input type="text" id="text" />
<input type="button" value="播放动画" onclick="run()" /><br />
说明:鼠标拖拽画布上的点可移动,双击画布空白处增加新的点,双击画布上的点可将其删除
<canvas id="canvasId" width="700" height="600"></canvas>
<script type="text/javascript">
var canvas = document.getElementById("canvasId");
var cxt = canvas.getContext("2d");
var p = [{x:43,y:131},{x:257,y:307},{x:237,y:27},{x:455,y:210}];
var clearTimer;
var bnp;


function curve(p,lt)//贝塞尔曲线
{
	var sx=0, sy=0, s=p.length-1;
	var q = [];
	for(var i=0, l = p.length-2; i<l; ++i)
	{
		q[i] = {
			x: (p[i+1].x - p[i].x) * s - sx ,
			y: (p[i+1].y - p[i].y) * s - sy
		};
		sx += q[i].x;
		sy += q[i].y;
	}
	q[i] = {
		x: p[i+1].x - p[0].x - sx ,
		y: p[i+1].y - p[0].y - sy
	};
	sx=sy=s=i=l=undefined;
	return function(t)
	{
		t /= lt;
		var x=0, y=0;
		for(var i=q.length-1; i>=0; --i)
		{
			x = (x + q[i].x) * t;
			y = (y + q[i].y) * t;
		}
		return {x: x+p[0].x , y: y+p[0].y};
	};
}

function upg()
{
	cxt.clearRect(0,0,canvas.width,canvas.height);
	cxt.strokeStyle = "#bcbcbc";
	cxt.lineWidth = 1;
	cxt.beginPath();
	for(var i=0, l = p.length; i<l; ++i)
	{
		var u = p[i];
		cxt.lineTo(u.x, u.y);
	}
	cxt.stroke();
	var cur = curve(p,100);
	cxt.strokeStyle = "#ff0000";
	cxt.lineWidth = 3;
	cxt.beginPath();
	for(var i=0; i<=100; i++)
	{
		u = cur(i);
		cxt.lineTo(u.x, u.y);
	}
	cxt.stroke();
	for(var i=0, l = p.length; i<l; ++i)
	{
		u = p[i];
		cxt.fillStyle = u===bnp?"#c8660d":"#5b6ff0";
		cxt.beginPath();
		cxt.arc(u.x, u.y,6,0,2*Math.PI,true);
		cxt.closePath();
		cxt.fill();
	}
}

function run()
{
	clearTimeout(clearTimer);
	var cur = curve(p,100);
	cxt.strokeStyle = "#ff0000";
	cxt.lineWidth = 1;
	cxt.fillStyle = "#7122b7";
	function eyg(t)
	{
		cxt.clearRect(0,0,canvas.width,canvas.height);
		cxt.beginPath();
		for(var i=0; i<=100; i++)
		{
			var u = cur(i);
			cxt.lineTo(u.x, u.y);
		}
		cxt.stroke();
		var u = cur(t);
		cxt.beginPath();
		cxt.arc(u.x, u.y,8,0,2*Math.PI,true);
		cxt.closePath();
		cxt.fill();
		if(++t<=100)
			clearTimer = setTimeout(function(){eyg(t)},50);
		else
			upg();
	}
	eyg(0);
}

function distance(a,b)
{
	var x = b.x-a.x , y = b.y-a.y;
	return Math.sqrt(x*x+y*y);
}

function getXY(e)
{
	return {
		x : e.clientX - canvas.offsetLeft + document.body.scrollLeft,
		y : e.clientY - canvas.offsetTop  + document.body.scrollTop
	}
}

function select(sp)
{
	for(var i=0, l = p.length; i<l; ++i)
		if(distance(sp,p[i])<=6)
			return i;
	return -1;
};

function uptext()
{
	var arr = [];
	for(var i=0, l = p.length; i<l; ++i)
		arr[i] = "{x:"+p[i].x+",y:"+p[i].y+"}";
	document.getElementById("text").value = "["+arr.join(",")+"]";
}

canvas.onmousedown=function(e)
{
	e = e||event;
	var sp = getXY(e);
	var gr = select(sp);
	bnp = gr!=-1 ? p[gr] : null;
};

canvas.onmousemove=function(e)
{
	if(!bnp) return;
	e = e||event;
	var sp = getXY(e);
	bnp.x = sp.x;
	bnp.y = sp.y;
	uptext();
	upg();
};

canvas.onmouseup=function(e)
{
	bnp = null;
};

canvas.ondblclick=function(e)
{
	e = e||event;
	var sp = getXY(e);
	var gr = select(sp);
	if(gr==-1)
		p.push(sp);
	else
	{
		if(p.length>2)
			p.splice(gr,1);
		else
			alert("一条线不能少于 2 个点吧");
	}
	uptext();
	upg();
};

canvas.onselectstart=canvas.ondragstart=function(e){return false;};

uptext();
upg();

</script>
</body>
</html>

版权声明:本文为博主原创文章,未经博主允许不得转载。

Html5系列(二十三) canvas高级贝塞尔曲线运动动画

DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1...
  • dhdhxgx
  • dhdhxgx
  • 2015年04月16日 23:05
  • 5061

html5Canvas动画实现球内波浪效果

前言 先自己动手通过Canvas实现的效果始终不很满意,后来在网上找了一些html5Canvas实现的类似的波浪效果,但都没有我想要的,最后在github上找到一个我想要的类似效果,只不过这个是在长...
  • yyy269954107
  • yyy269954107
  • 2015年02月03日 14:08
  • 7716

HTML5 Canvas绘图与动画学习59例源码

  • 2014年04月27日 12:13
  • 2KB
  • 下载

Html5系列(二十三) canvas高级贝塞尔曲线运动动画

DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1...
  • dhdhxgx
  • dhdhxgx
  • 2015年04月16日 23:05
  • 5061

html5-canvas3-二次贝塞尔曲线和三次贝塞尔曲线以及canvas的渐变

以前不知道二次贝塞尔曲线和三次贝塞尔曲线,学习canvas时,canvas提供了两个方法来绘制这两条陌生的线。偶也是初次了解,不知道什么地方将来会用到,先分享了再说: 和以前一样,先建个canvas标...
  • wo1aijava
  • wo1aijava
  • 2014年01月14日 17:59
  • 1648

自定义控件三部曲之绘图篇(六)——Path之贝赛尔曲线和手势轨迹、水波纹效果

前言:好想义无反顾地追逐梦想相关文章:《Android自定义控件三部曲文章索引》从这篇开始,我将延续androidGraphics系列文章把图片相关的知识给大家讲完,这一篇先稍微进阶一下,给大家把《a...
  • harvic880925
  • harvic880925
  • 2016年03月28日 09:48
  • 14874

Html5系列(二十三) canvas高级贝塞尔曲线运动动画

DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1...
  • dhdhxgx
  • dhdhxgx
  • 2015年04月16日 23:05
  • 5061

简易制作贝塞尔曲线动画(JS+css3+canvas)

简易制作贝塞尔曲线动画(JS+css3+canvas)一些废话(直接看代码的可跳过)贝塞尔曲线:什么是贝塞尔曲线?用过PS的就知道,那破钢笔工具就是,什么,没用过?自行百度用法。 需要的工具 ctr...
  • Mcky_Love
  • Mcky_Love
  • 2017年11月30日 22:22
  • 188

贝塞尔曲线与CSS3动画、SVG和canvas的基情

一、甚忙,短言之 最近谷歌那谁谁因为自己的相好被老大抢了,就去小米了!狗血的三角关系要比烂掉的TVB神剧好看多了。 但这只是小菜,贝塞尔曲线才是很角色,因为有外国血统,因此,和CSS3动画...
  • Fuohua
  • Fuohua
  • 2017年07月22日 15:13
  • 365

贝塞尔曲线与CSS3动画、SVG和canvas的基情

贝塞尔曲线与CSS3动画、SVG和canvas的基情 这篇文章发布于 2013年08月30日,星期五,23:23,归类于 canvas相关, css相关, SVG相关。 阅读 95700...
  • a460550542
  • a460550542
  • 2017年06月15日 16:02
  • 322
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:玩玩Canvas高阶贝塞尔曲线动画
举报原因:
原因补充:

(最多只允许输入30个字)