canvas 将折线转换成曲线
实现原理
依靠canvas 2d的api方法context.bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y);
来实现绘制曲线。
实现目标
具体过程
代码
Vector2,一般用来表示向量,但有的时候也用来当作点来进行一计算。
var Vector2 = function(x, y) {this.x = x;this.y = y;
}
Vector2.prototype = {"length": function () {return Math.sqrt(this.x * this.x + this.y * this.y);},"normalize": function () {var inv = 1 / this.length();return new Vector2(this.x * inv, this.y * inv);},"add": function (v) {return new Vector2(this.x + v.x, this.y + v.y);},"multiply": function (f) {return new Vector2(this.x * f, this.y * f);},"dot": function (v) {return this.x * v.x + this.y * v.y;},"angle": function (v) {return Math.acos(this.dot(v) / (this.length() *v.length())) * 180 / Math.PI;}
}
length求向量长度
normalize转单位向量
add向量叠加
multiply向量翻倍
dot内积
angle方法用来求两个向量的夹角
核心方法 根据path上的点,求出所有贝塞尔曲线控制点。
function getControlPoint(path) {var rt = 0.3;var i = 0, count = path.length - 2;var arr = [];for (; i < count; i++) {var a = path[i], b = path[i + 1], c = path[i + 2];var v1 = new Vector2(a.x - b.x, a.y - b.y);var v2 = new Vector2(c.x - b.x, c.y - b.y);var v1Len = v1.length(), v2Len = v2.length();var centerV = v1.normalize().add(v2.normalize()).normalize();var ncp1 = new Vector2(centerV.y, centerV.x * -1);var ncp2 = new Vector2(centerV.y * -1, centerV.x);if (ncp1.angle(v1) < 90) {var p1 = ncp1.multiply(v1Len * rt).add(b);var p2 = ncp2.multiply(v2Len * rt).add(b);arr.push(p1, p2)} else {var p1 = ncp1.multiply(v2Len * rt).add(b);var p2 = ncp2.multiply(v1Len * rt).add(b);arr.push(p2, p1)}}return arr;
}
案例
代码:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<canvas id="c" width="1000" height="800"></canvas><script>var ctx=document.getElementById("c").getContext("2d");var points =[{ x: 50, y: 50 }, { x: 200, y: 100 }, { x: 250, y: 50 }, { x: 350, y: 150 }, { x: 370, y: 100 }, { x: 570, y: 200 }];ctx.lineWidth=3;ctx.strokeStyle="#cccccc";drawPath(points,ctx);function drawPath(path,ctx){var Vector2 = function(x, y) {this.x = x;this.y = y;};Vector2.prototype = {"length": function () {return Math.sqrt(this.x * this.x + this.y * this.y);},"normalize": function () {var inv = 1 / this.length();return new Vector2(this.x * inv, this.y * inv);},"add": function (v) {return new Vector2(this.x + v.x, this.y + v.y);},"multiply": function (f) {return new Vector2(this.x * f, this.y * f);},"dot": function (v) {return this.x * v.x + this.y * v.y;},"angle": function (v) {return Math.acos(this.dot(v) / (this.length() *v.length())) * 180 / Math.PI;}};function getControlPoint(path) {var rt = 0.3;var i = 0, count = path.length - 2;var arr = [];for (; i < count; i++) {var a = path[i], b = path[i + 1], c = path[i + 2];var v1 = new Vector2(a.x - b.x, a.y - b.y);var v2 = new Vector2(c.x - b.x, c.y - b.y);var v1Len = v1.length(), v2Len = v2.length();var centerV = v1.normalize().add(v2.normalize()).normalize();var ncp1 = new Vector2(centerV.y, centerV.x * -1);var ncp2 = new Vector2(centerV.y * -1, centerV.x);if (ncp1.angle(v1) < 90) {var p1 = ncp1.multiply(v1Len * rt).add(b);var p2 = ncp2.multiply(v2Len * rt).add(b);arr.push(p1, p2)}else {var p1 = ncp1.multiply(v2Len * rt).add(b);var p2 = ncp2.multiply(v1Len * rt).add(b);arr.push(p2, p1)}}return arr;}var point=getControlPoint(path);console.log(point);var points = path;ctx.beginPath();var int=0;for(var i =0;i<points.length;i++){if(i==0){ctx.moveTo(points[0].x,points[0].y);ctx.quadraticCurveTo(point[0].x,point[0].y,points[1].x,points[1].y);int=int+1;}else if(i<points.length-2){ctx.moveTo(points[i].x,points[i].y);ctx.bezierCurveTo(point[int].x,point[int].y,point[int+1].x,point[int+1].y,points[i+1].x,points[i+1].y);int+=2;}else if(i==points.length-2){ctx.moveTo(points[points.length-2].x,points[points.length-2].y);ctx.quadraticCurveTo(point[point.length-1].x,point[point.length-1].y,points[points.length-1].x,points[points.length-1].y);}}ctx.stroke();ctx.closePath();ctx.beginPath();for(i =0;i<points.length;i++){ctx.beginPath();ctx.arc(points[i].x,points[i].y,5,0,2*Math.PI);ctx.fillStyle="#cccccc";ctx.fill();ctx.closePath();}}
</script>
</body>
</html>
嫌麻烦直接将值传入,调用drawPath()
方法,就可以实现效果。
代码转至:https://www.cnblogs.com/iamzhanglei/p/4809431.html
canvas 将折线转换成曲线相关推荐
- 使用的是html5的canvas将文字转换成图片
当前功能的运用场景是:用户需要传文件给他人,在用户选择文件之后需要显示一个文件图标和所选文件的名称. 当前代码部分是摘自网上,但是已经忘记在什么地方获取的,如有侵权联系小弟后自当删除. 注意:必须在h ...
- 使用Canvas把照片转换成素描画
一.引子 话说前阵子想把一张照片转换成素描,然后发个微博.结果发现mac上没找到能直接转换素描的软件(PS不算,可要好几步呢),坑爹啊--google 了下,Web上竟然也是没有直接把照片转换成素描的 ...
- 使用canvas画图,转换成图片路径
let canvas= document.createElement('canvas'); //创建canvas 对象canvas.width = 500; canvas.height = 500;l ...
- React生成二维码并将canvas转换成img格式
1. 导入包生成二维码 npm install qrcode.react npm包链接: https://www.npmjs.com/package/qrcode.react 1.1 生成二维码: i ...
- 前端使用canvas实现昵称首个文字转换成图片功能
最近在用腾讯会议的时,看到要是没有设置自定义头像时会有个默认头像,就是昵称的第一个字母.上班摸鱼时突然想用原生的画布实现这个功能. canvas有能够转换成bas64的功能,说以直接写js代码就行,直 ...
- 如何使用Python语言将测量数据曲线动起来? matplotlib转换成 GIF文件
简 介: 本文就如何使用的Python中的Matplotlib绘制的图运动起来进行讨论.实际上是生成多个图片,将它们合成一个动图.编写了PlotGIF函数,将matplotlib绘制的图片存储,然后生 ...
- 【Python】递归绘制科赫曲线及科赫雪花及转换成可执行文件打包
科赫曲线 ----------- 绘制科赫曲线 import turtle def koch(size, n):if n == 0:turtle.fd(size)else:for angle in [ ...
- 三次Bezier曲线/B样条曲线转换成隐函数方程的方法
引言 这个问题在我做相关研究的时候一直很困惑,研究过很久很久,而且网上真的很难找到这方面的答案,在知乎问过(知乎那个问题就是我问的),无大佬知道.后来无意在看别人的硕士论文发现了其实是有方法的. 问题 ...
- Android Canvas画布上放图片,保存图片为黑色,转换成PNG格式还是黑色,画布设置白色则图片不显示,特例出完美的解决办法
网上都说 bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);替换成bitmap.compress(Bitmap.CompressFormat.J ...
最新文章
- 树hash树BtreeB+tree
- 后端直接跳转前端页面_WEB前端开发中页面跳转等待时间过长如何解决?
- 解析xml数据存入bean映射到数据库的 需求解决过程
- java有道云,有道云笔记链接——JAVA面向对象的学习
- 超硬核!躺进BAT以后我总结了出现最多的15道数组题
- 初学者选黑卡还是微单_零基础,一篇读懂单反和微单
- 转载-----Java Longest Palindromic Substring(最长回文字符串)
- 人体特征点检测解决方案
- KMP模式匹配 三(弦)
- cookies时效由谁决定_胎儿的性别,是什么时候定下来的,又是由谁决定的?
- zen brush 2 android,Zen Brush 2 才不仅仅是个练字 App 那么简单
- 《Web程序设计》学习笔记1——web基础知识简述
- 人体神经元细胞分布图片,神经元人体分布大图
- AM5728设备数的描述
- 计算机科学与技术的年崭,计算机科学与信息技术学院举行2019届毕业典礼暨表彰大会...
- 如何在WORD中插入可播放的视频
- Centos7下安装FastDFS服务
- Keil5新建工程项目
- 你要怎么切你的披萨?
- 孤立词语音识别(3)——计算MFCC系数