玩玩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>

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jslang/article/details/37991517

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:31
  • 5733

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

一些废话(直接看代码的可跳过) 贝塞尔曲线:什么是贝塞尔曲线?用过PS的就知道,那破钢笔工具就是,什么,没用过?自行百度用法。 需要的工具 ctrl+c、ctrl+v ...
  • Mcky_Love
  • Mcky_Love
  • 2017-11-30 22:22:50
  • 538

html5Canvas动画实现球内波浪效果

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

绘制贝塞尔曲线()

body{text-align: center;} #can{ border:1px solid black;} beisaier var a...
  • j_d_m_y
  • j_d_m_y
  • 2015-08-17 10:26:38
  • 384

用JS写的N阶贝塞尔曲线升阶降阶以及拖拽

用的是sublime3 直接上代码HTML:      Bezier    .canvas{  position: relative;  top: 10px;  displa...
  • freakkkk
  • freakkkk
  • 2017-12-20 20:27:08
  • 288

Android 绘制N阶Bezier曲线

前端时间公司项目中有用到Bezier曲线的知识,在熟悉Bezier曲线原理和实现方式后,我突发奇想在Android客户端实现Bezier曲线的构建动画,于是有了BezierMaker这个项目。在讲解代...
  • venshine
  • venshine
  • 2016-06-25 16:04:39
  • 6102

贝塞尔曲线的数学原理

Bézier curve(贝塞尔曲线)是应用于二维图形应用程序的数学曲线。 曲线定义:起始点、终止点(也称锚点)、控制点。通过调整控制点,贝塞尔曲线的形状会发生变化。 1962年,法国数学家Pierr...
  • likendsl
  • likendsl
  • 2012-08-10 17:43:13
  • 15269

安卓手写字迹源码(毛笔,喷枪,马克笔等效果)

之前项目需要,要在手机上实现笔迹的效果,这类的应用多了,但是源码在全球最大局域网内却找不到~~ 一年前是想着自己做的,当时知道安卓设备的touch是可以获取伪压力感应值 即手指压力越大,皮肤接触面...
  • qinpanke
  • qinpanke
  • 2015-07-29 19:33:31
  • 1637

获取贝塞尔曲线上的100个点

#include typedef struct {     float x;     float y; }Point2D; void ComputeBezie...
  • guo_hongjun1611
  • guo_hongjun1611
  • 2012-09-10 09:48:58
  • 2534

canvas 手写毛笔字效果

canvas 手写毛笔字效果 #canvasId { background-color: #FFFFcc; } function Handwriting(id) { this....
  • jslang
  • jslang
  • 2016-03-03 18:47:31
  • 5567
收藏助手
不良信息举报
您举报文章:玩玩Canvas高阶贝塞尔曲线动画
举报原因:
原因补充:

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