用javascript canvas 画贝塞尔曲线,求高手帮助,急求!!!!!

qq_36549402 2018-04-09 10:48:42
希望大神出手相救,研究生导师下派的任务,我真是没有读明白,希望大神帮忙解答一下第一个和第二个函数的原理,感谢


<!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> //设置一个高600,宽700的画布
<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); //以(x,y)为圆心绘制一条弧线,弧线半径为radius,起始和结束角度(用弧度表示)分别为startAngle和endAngle。最后一个参数表示startAngle和endAngle是否按逆时针方向计算,值为false表示按顺时针方向计算。
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>
...全文
523 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
jahnlis 2019-03-07
  • 打赏
  • 举报
回复
你好 我想问你下 为什么回放出来的线跟之前贝塞尔线生成器生出的 有偏差
天际的海浪 2018-04-10
  • 打赏
  • 举报
回复
curve()是计算贝塞尔曲线中每一个点的坐标。 首先根据参数提供的控制点预先计算出一组中间结果的向量值,并利用闭包保存,使之后不再需要重新计算。 之后curve()函数返回一个函数,调用这个返回的函数,真正计算每一个点的坐标。 upg()是在画布上绘制曲线,控制点与辅助线。

87,907

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧