基于js Canvas实现二次贝塞尔曲线


Posted in Javascript onDecember 25, 2018

本文实例为大家分享了js Canvas实现二次贝塞尔曲线的具体代码,供大家参考,具体内容如下

先上效果图:

基于js Canvas实现二次贝塞尔曲线

实现代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>二次贝塞尔曲线</title>
<meta name="Keywords" content="">
<meta name="Description" content="">
<style type="text/css">
 body, h1{margin:0;}
 canvas{margin: 20px; }
</style>
</head>
<body>
 <h1>二次贝塞尔曲线</h1>
 <canvas id="canvas" width=600 height=600 style="border: 1px solid #ccc;"></canvas>
<script>
 /**
 * @param sx 起始点x坐标
 * @param sy 起始点y坐标
 * @param ex 结束点x坐标
 * @param ey 结束点y坐标
 * @param cx 控制点x坐标
 * @param cy 控制点y坐标
 * @param part 将起始点到控制点的线段分成的份数,数值越高,计算出的曲线越精确
 */
 function draw(sx, sy, ex, ey, cx, cy, part) {
 var canvas = document.getElementById('canvas');
 var ctx = canvas.getContext('2d'); 
 //绘制起始点、控制点、终点 
 ctx.beginPath();
 ctx.moveTo(sx, sy);
 ctx.lineTo(cx, cy);
 ctx.lineTo(ex, ey);
 ctx.stroke();
 
 // 绘制二次贝塞尔曲线
 ctx.beginPath();
 ctx.moveTo(sx, sy);
 // 起始点到控制点的x和y每次的增量
 var changeX1 = (cx - sx) / part;
 var changeY1 = (cy - sy) / part;
 // 控制点到结束点的x和y每次的增量
 var changeX2 = (ex - cx) / part;
 var changeY2 = (ey - cy) / part;
 
 for(var i = 0; i < part; i++) {
 // 计算两个动点的坐标
 var qx1 = sx + changeX1 * i;
 var qy1 = sy + changeY1 * i;
 var qx2 = cx + changeX2 * i;
 var qy2 = cy + changeY2 * i;
 // 计算得到此时的一个贝塞尔曲线上的点坐标
 var bx = qx1 + (qx2 - qx1) * i / part;
 var by = qy1 + (qy2 - qy1) * i / part;
 
 ctx.lineTo(bx, by);
 }
 ctx.stroke();
 }
 
 window.onload = function () {
 draw(0, 0, 600, 0, 150, 450, 100);
 };
</script>
</body>
</html>

上面的是静态的,来个动态的看一看:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>二次贝塞尔曲线</title>
<meta name="Keywords" content="">
<meta name="Description" content="">
<style type="text/css">
 body, h1{margin:0;}
 canvas{margin: 20px; }
</style>
</head>
<body>
 <h1>二次贝塞尔曲线</h1>
 <canvas id="canvas" width=600 height=600 style="border: 1px solid #ccc;"></canvas>
<script>
 /**
 * @param sx 起始点x坐标
 * @param sy 起始点y坐标
 * @param ex 结束点x坐标
 * @param ey 结束点y坐标
 * @param cx 控制点x坐标
 * @param cy 控制点y坐标
 * @param part 将起始点到控制点的线段分成的份数,数值越高,计算出的曲线越精确
 * @param interval 画图的间隔
 * @return function 调用一次就向后画一段曲线
 */
 function draw(sx, sy, ex, ey, cx, cy, part, interval) {
 var canvas = document.getElementById('canvas');
 var ctx = canvas.getContext('2d'); 
 //绘制起始点、控制点、终点 
 ctx.beginPath();
 ctx.moveTo(sx, sy);
 ctx.lineTo(cx, cy);
 ctx.lineTo(ex, ey);
 ctx.stroke();
 
 // 绘制二次贝塞尔曲线
 ctx.beginPath();
 ctx.moveTo(sx, sy);
 // 起始点到控制点的x和y每次的增量
 var changeX1 = (cx - sx) / part;
 var changeY1 = (cy - sy) / part;
 // 控制点到结束点的x和y每次的增量
 var changeX2 = (ex - cx) / part;
 var changeY2 = (ey - cy) / part;
 // 上次的点坐标
 var lastX = sx;
 var lastY = sy;
 
 var i = 0;
 
 return function () {
 // 计算两个动点的坐标
 var qx1 = sx + changeX1 * i;
 var qy1 = sy + changeY1 * i;
 var qx2 = cx + changeX2 * i;
 var qy2 = cy + changeY2 * i;
 // 计算得到此时的一个贝塞尔曲线上的点
 var bx = qx1 + (qx2 - qx1) * i / part;
 var by = qy1 + (qy2 - qy1) * i / part;
 // 从上次的点继续画
 ctx.beginPath();
 ctx.moveTo(lastX, lastY);
 ctx.lineTo(bx, by);
 ctx.stroke();
 // 保存点坐标
 lastX = bx;
 lastY = by;
 
 i += 1;
 
 if (i < part) {
 setTimeout(arguments.callee, interval);
 }
 }
 }
 
 window.onload = function () {
 var display = draw(0, 0, 600, 0, 150, 450, 200, 50);
 display();
 };
</script>
</body>
</html>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
理解Javascript_11_constructor实现原理
Oct 18 Javascript
node.js中的fs.exists方法使用说明
Dec 17 Javascript
Java遍历集合方法分析(实现原理、算法性能、适用场合)
Apr 25 Javascript
浅谈JavaScript的push(),pop(),concat()方法
Jun 03 Javascript
JavaScript 实现 Tab 点击切换实例代码
Mar 25 Javascript
详解如何使用vue-cli脚手架搭建Vue.js项目
May 19 Javascript
Angular使用 ng-img-max 调整浏览器中的图片的示例代码
Aug 17 Javascript
详解小程序输入框闪烁及重影BUG解决方案
Aug 31 Javascript
ES6中Set和Map数据结构,Map与其它数据结构互相转换操作实例详解
Feb 28 Javascript
亲自动手实现vue日历控件
Jun 26 Javascript
微信小程序实现拍照画布指定区域生成图片
Jul 18 Javascript
JS如何在数组指定位置插入元素
Mar 10 Javascript
JavaScript实现小球沿正弦曲线运动
Sep 07 #Javascript
微信小程序使用二次贝塞尔曲线画波浪
Dec 25 #Javascript
微信小程序开发问题之wx.previewImage
Dec 25 #Javascript
微信小程序使用for循环动态渲染页面操作示例
Dec 25 #Javascript
JavaScript简单实现动态改变HTML内容的方法示例
Dec 25 #Javascript
使用gulp构建前端自动化的方法示例
Dec 25 #Javascript
JavaScript实现的级联算法示例【省市二级联动功能】
Dec 25 #Javascript
You might like
PHP 5.0对象模型深度探索之绑定
2006/09/05 PHP
类的另类用法--数据的封装
2006/10/09 PHP
关于PHP递归算法和应用方法介绍
2013/04/15 PHP
php采集神器cURL使用方法详解
2016/02/19 PHP
php识别翻转iphone拍摄的颠倒图片
2018/05/17 PHP
jQuery find和children方法使用
2011/01/31 Javascript
javascript中动态加载js文件多种解决办法总结
2013/11/15 Javascript
如何使用Bootstrap创建表单
2017/03/29 Javascript
浅谈JavaScript find 方法不支持IE的问题
2017/09/28 Javascript
详解浏览器缓存和webpack缓存配置
2018/07/06 Javascript
详解JavaScript 的变量
2019/03/08 Javascript
JavaScript实现单英文金山打字通
2020/07/24 Javascript
vue项目中使用AES实现密码加密解密(ECB和CBC两种模式)
2019/08/12 Javascript
python虚拟环境 virtualenv的简单使用
2020/01/21 Javascript
[43:24]2018DOTA2亚洲邀请赛3月29日 小组赛A组 LGD VS Liquid
2018/03/30 DOTA
[02:23]完美世界全国高校联赛街访DOTA2第一期
2019/11/28 DOTA
python对指定目录下文件进行批量重命名的方法
2015/04/18 Python
Python操作Access数据库基本步骤分析
2016/09/19 Python
http请求 request失败自动重新尝试代码示例
2018/01/25 Python
python模块smtplib学习
2018/05/22 Python
ubuntu17.4下为python和python3装上pip的方法
2018/06/12 Python
django2+uwsgi+nginx上线部署到服务器Ubuntu16.04
2018/06/26 Python
Python使用Flask-SQLAlchemy连接数据库操作示例
2018/08/31 Python
python字符串替换第一个字符串的方法
2019/06/26 Python
python从内存地址上加载python对象过程详解
2020/01/08 Python
如何使用canvas绘制可移动网格的示例代码
2020/12/14 HTML / CSS
波兰在线儿童和婴儿用品零售商:pinkorblue
2019/06/29 全球购物
领导干部群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
2014年城管工作总结
2014/11/20 职场文书
2015年保育员个人工作总结
2015/05/13 职场文书
重阳节主题班会
2015/08/17 职场文书
2016年记者节感言
2015/12/08 职场文书
队名及霸气口号大全
2015/12/25 职场文书
导游词之南京栖霞山
2019/10/18 职场文书
PyQt5 QThread倒计时功能的实现代码
2021/04/02 Python
SQL Server 中的事务介绍
2022/05/20 SQL Server