基于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 相关文章推荐
文本框的字数限制功能jquery插件
Nov 24 Javascript
javascript学习笔记(十一) 正则表达式介绍
Jun 20 Javascript
jquery miniui 教程 表格控件 合并单元格应用
Nov 25 Javascript
设为首页和收藏的Javascript代码(亲测兼容IE,Firefox,chrome等浏览器)
Nov 18 Javascript
js格式化时间小结
Nov 03 Javascript
Javascript小技能总结(推荐)
Jun 02 Javascript
Javascript基础学习笔记(菜鸟必看篇)
Jul 22 Javascript
微信小程序小组件 基于Canvas实现直播点赞气泡效果
May 29 Javascript
angularjs下拉框空白的解决办法
Jun 20 Javascript
JS小球抛物线轨迹运动的两种实现方法详解
Dec 20 Javascript
Javascript将图片的绝对路径转换为base64编码的方法
Jan 11 Javascript
微信小程序跨页面传递data数据方法解析
Dec 13 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
windows下PHP APACHE MYSQ完整配置
2007/01/02 PHP
Zend Framework教程之Zend_Db_Table用法详解
2016/03/21 PHP
PHP文件与目录操作示例
2016/12/24 PHP
php处理静态页面:页面设置缓存时间实例
2017/06/22 PHP
thinkphp5 模型实例化获得数据对象的教程
2019/10/18 PHP
Thinkphp 框架扩展之驱动扩展实例分析
2020/04/27 PHP
PHP常量DIRECTORY_SEPARATOR原理及用法解析
2020/11/10 PHP
PhpSpreadsheet设置单元格常用操作汇总
2020/11/13 PHP
JavaScript与函数式编程解释
2007/04/27 Javascript
javascript 字符 Escape,encodeURI,encodeURIComponent
2009/07/09 Javascript
你必须知道的Javascript知识点之&quot;单线程事件驱动&quot;的使用
2013/04/23 Javascript
javascript学习笔记之10个原生技巧
2014/05/21 Javascript
javascript实现左右控制无缝滚动
2014/12/31 Javascript
JS去除iframe滚动条的方法
2015/04/01 Javascript
js随机生成字母数字组合的字符串 随机动画数字
2015/09/02 Javascript
jquery+php实现滚动的数字特效
2015/11/29 Javascript
jQuery实现点击按钮文字变成input框点击保存变成文字
2016/05/09 Javascript
js实现图片缓慢放大缩小效果
2016/08/02 Javascript
jQuery如何跳转到另一个网页 就这么简单
2016/12/28 Javascript
利用Chrome DevTools直接调试Node.js和JavaScript的方法详解(并行)
2017/02/16 Javascript
简单谈谈gulp-changed插件
2017/02/21 Javascript
jQuery+Cookie实现切换皮肤功能【附源码下载】
2018/03/25 jQuery
利用nodeJs anywhere搭建本地服务器环境的方法
2018/05/12 NodeJs
JS关闭子窗口并且刷新上一个窗口的实现示例
2020/03/10 Javascript
Vue按时间段查询数据组件使用详解
2020/08/21 Javascript
[02:18]《我与DAC》之工作人员:为了热爱DOTA2的玩家们
2018/03/28 DOTA
[46:12]完美世界DOTA2联赛循环赛 DM vs Matador BO2第一场 11.04
2020/11/04 DOTA
浅谈python socket函数中,send与sendall的区别与使用方法
2017/05/09 Python
Python实现多线程的两种方式分析
2018/08/29 Python
python 利用文件锁单例执行脚本的方法
2019/02/19 Python
python中hasattr()、getattr()、setattr()函数的使用
2019/08/16 Python
EMU Australia澳大利亚官网:澳大利亚本土雪地靴品牌
2019/07/24 全球购物
Linux操作面试题
2015/02/11 面试题
幼儿如何来做好自我评价
2013/11/05 职场文书
体育教育专业毕业生自荐信
2013/11/15 职场文书
烹调加工管理制度
2014/02/04 职场文书