返回顶部
首页 > 资讯 > 精选 >canvas怎么画出平滑的曲线
  • 229
分享到

canvas怎么画出平滑的曲线

2023-06-09 13:06:17 229人浏览 薄情痞子
摘要

这篇文章将为大家详细讲解有关canvas怎么画出平滑的曲线,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。背景概要相信大家平时在学习canvas 或 项目开发中使用canvas的时候应该都遇到过这样的需求:

这篇文章将为大家详细讲解有关canvas怎么画出平滑的曲线,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

背景概要

相信大家平时在学习canvas 或 项目开发中使用canvas的时候应该都遇到过这样的需求:实现一个可以书写的画板小工具

嗯,相信这对canvas使用较熟的童鞋来说仅仅只是几十行代码就可以搞掂的事情,以下demo就是一个再也简单不过的例子了:

<!DOCTYPE html><html><head>    <title>Sketchpad demo</title>    <style type="text/CSS">        canvas {            border: 1px blue solid;         }    </style></head><body>    <canvas id="canvas" width="800" height="500"></canvas>    <script type="text/javascript">        let isDown = false;        let beginPoint = null;        const canvas = document.querySelector('#canvas');        const ctx = canvas.getContext('2d');        // 设置线条颜色        ctx.strokeStyle = 'red';        ctx.lineWidth = 1;        ctx.lineJoin = 'round';        ctx.lineCap = 'round';        canvas.addEventListener('mousedown', down, false);        canvas.addEventListener('mousemove', move, false);        canvas.addEventListener('mouseup', up, false);        canvas.addEventListener('mouseout', up, false);        function down(evt) {            isDown = true;            beginPoint = getPos(evt);        }        function move(evt) {            if (!isDown) return;            const endPoint = getPos(evt);            drawLine(beginPoint, endPoint);            beginPoint = endPoint;        }        function up(evt) {            if (!isDown) return;                        const endPoint = getPos(evt);            drawLine(beginPoint, endPoint);            beginPoint = null;            isDown = false;        }        function getPos(evt) {            return {                x: evt.clientX,                y: evt.clientY            }        }        function drawLine(beginPoint, endPoint) {            ctx.beginPath();            ctx.moveTo(beginPoint.x, beginPoint.y);            ctx.lineTo(endPoint.x, endPoint.y);            ctx.stroke();            ctx.closePath();        }    </script></body></html>

它的实现逻辑也很简单:

  • 我们在canvas画布上主要监听了三个事件:mousedownmouseupmousemove,同时我们也创建了一个isDown变量;

  • 当用户按下鼠标(mousedown,即起笔)时将isDown置为true,而放下鼠标(mouseup)的时候将它置为false,这样做的好处就是可以判断用户当前是否处于绘画状态;

  • 通过mousemove事件不断采集鼠标经过的坐标点,当且仅当isDowntrue(即处于书写状态)时将当前的点通过canvas的lineTo方法与前面的点进行连接、绘制;

通过以上几个步骤我们就可以实现基本的画板功能了,然而事情并没那么简单,仔细的童鞋也许会发现一个很严重的问题&mdash;&mdash;通过这种方式画出来的线条存在锯齿,不够平滑,而且你画得越快,折线感越强。表现如下图所示:

canvas怎么画出平滑的曲线

为什么会这样呢?

问题分析

出现该现象的原因主要是:

我们是以canvas的lineTo方法连接点的,连接相邻两点的是条直线,非曲线,因此通过这种方式绘制出来的是条折线;

canvas怎么画出平滑的曲线

受限于浏览器对mousemove事件的采集频率,大家都知道在mousemove时,浏览器是每隔一小段时间去采集当前鼠标的坐标的,因此鼠标移动的越快,采集的两个临近点的距离就越远,故“折线感越明显“;

如何才能画出平滑的曲线?

要画出平滑的曲线,其实也是有方法的,lineTo靠不住那我们可以采用canvas的另一个绘图api&mdash;&mdash;quadraticCurveTo ,它用于绘制二次贝塞尔曲线。

二次贝塞尔曲线

quadraticCurveTo(cp1x, cp1y, x, y)

调用quadraticCurveTo方法需要四个参数,cp1xcp1y描述的是控制点,而xy则是曲线的终点:

canvas怎么画出平滑的曲线

更多详细的信息可移步MDN

既然要使用贝塞尔曲线,很显然我们的数据是不够用的,要完整描述一个二次贝塞尔曲线,我们需要:起始点、控制点和终点,这些数据怎么来呢?

有一个很巧妙的算法可以帮助我们获取这些信息

获取二次贝塞尔关键点的算法

这个算法并不难理解,这里我直接举例子吧:

假设我们在一次绘画中共采集到6个鼠标坐标,分别是A, B, C, D, E, F;取前面的A, B, C三点,计算出BC的中点B1,以A为起点,B为控制点,B1为终点,利用quadraticCurveTo绘制一条二次贝塞尔曲线线段;

canvas怎么画出平滑的曲线

接下来,计算得出CD点的中点C1,以B1为起点、C为控制点、C1为终点继续绘制曲线;

canvas怎么画出平滑的曲线

依次类推不断绘制下去,当到最后一个点F时,则以DE的中点D1为起点,以E为控制点,F为终点结束贝塞尔曲线。

canvas怎么画出平滑的曲线

OK,算法就是这样,那我们基于该算法再对现有代码进行一次升级改造:

let isDown = false;let points = [];let beginPoint = null;const canvas = document.querySelector('#canvas');const ctx = canvas.getContext('2d');// 设置线条颜色ctx.strokeStyle = 'red';ctx.lineWidth = 1;ctx.lineJoin = 'round';ctx.lineCap = 'round';canvas.addEventListener('mousedown', down, false);canvas.addEventListener('mousemove', move, false);canvas.addEventListener('mouseup', up, false);canvas.addEventListener('mouseout', up, false);function down(evt) {    isDown = true;    const { x, y } = getPos(evt);    points.push({x, y});    beginPoint = {x, y};}function move(evt) {    if (!isDown) return;    const { x, y } = getPos(evt);    points.push({x, y});    if (points.length > 3) {        const lastTwoPoints = points.slice(-2);        const controlPoint = lastTwoPoints[0];        const endPoint = {            x: (lastTwoPoints[0].x + lastTwoPoints[1].x) / 2,            y: (lastTwoPoints[0].y + lastTwoPoints[1].y) / 2,        }        drawLine(beginPoint, controlPoint, endPoint);        beginPoint = endPoint;    }}function up(evt) {    if (!isDown) return;    const { x, y } = getPos(evt);    points.push({x, y});    if (points.length > 3) {        const lastTwoPoints = points.slice(-2);        const controlPoint = lastTwoPoints[0];        const endPoint = lastTwoPoints[1];        drawLine(beginPoint, controlPoint, endPoint);    }    beginPoint = null;    isDown = false;    points = [];}function getPos(evt) {    return {        x: evt.clientX,        y: evt.clientY    }}function drawLine(beginPoint, controlPoint, endPoint) {    ctx.beginPath();    ctx.moveTo(beginPoint.x, beginPoint.y);    ctx.quadraticCurveTo(controlPoint.x, controlPoint.y, endPoint.x, endPoint.y);    ctx.stroke();    ctx.closePath();}

在原有的基础上,我们创建了一个变量points用于保存之前mousemove事件中鼠标经过的点,根据该算法可知要绘制二次贝塞尔曲线起码需要3个点以上,因此我们只有在points中的点数大于3时才开始绘制。接下来的处理就跟该算法一毛一样了,这里不再赘述。

代码更新后我们的曲线也变得平滑了许多,如下图所示:

canvas怎么画出平滑的曲线

关于“canvas怎么画出平滑的曲线”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

--结束END--

本文标题: canvas怎么画出平滑的曲线

本文链接: https://lsjlt.com/news/256209.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • canvas怎么画出平滑的曲线
    这篇文章将为大家详细讲解有关canvas怎么画出平滑的曲线,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。背景概要相信大家平时在学习canvas 或 项目开发中使用canvas的时候应该都遇到过这样的需求:...
    99+
    2023-06-09
  • canvas小画板之平滑曲线的实现案例
    小编给大家分享一下canvas小画板之平滑曲线的实现案例,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!功能需求项目需求:需要实现一个可以自由书写的小画板简单实现对...
    99+
    2023-06-09
  • matlab怎么画出光滑的曲线
    要画出光滑的曲线,可以使用MATLAB中的插值函数。下面是一种常用的方法:1. 首先,创建一个包含X和Y数据的向量,其中X是自变量,...
    99+
    2023-10-08
    matlab
  • 怎么用HTML5 canvas画曲线
    本篇内容介绍了“怎么用HTML5 canvas画曲线”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!<...
    99+
    2024-04-02
  • Javascript中怎么生成平滑曲线
    这篇文章给大家介绍Javascript中怎么生成平滑曲线,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。前言平滑曲线生成是一个很实用的技术很多时候,我们都需要通过绘制一些折线,然后让计算机平滑的连接起来,先来看下最终效果...
    99+
    2023-06-20
  • android怎么实现可以滑动的平滑曲线图
    本文小编为大家详细介绍“android怎么实现可以滑动的平滑曲线图”,内容详细,步骤清晰,细节处理妥当,希望这篇“android怎么实现可以滑动的平滑曲线图”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。1 att...
    99+
    2023-07-02
  • Python曲线平滑的实现示例
    在编写测试程序的时候,由于数据帧数多的原因,导致生成的曲线图比较难看,如下图: 由于高频某些点的波动导致高频曲线非常难看,因此需要对曲线做平滑处理,让曲线过渡更平滑。对曲线进行平滑...
    99+
    2024-04-02
  • 基于canvas如何使用贝塞尔曲线平滑拟合折线段
    小编给大家分享一下基于canvas如何使用贝塞尔曲线平滑拟合折线段,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!为什么要平滑拟合折线段先来看下Echarts下折线图的渲染效果: 一开始我没注意到其实这个折线段是曲...
    99+
    2023-06-09
  • android实现可以滑动的平滑曲线图
    本文实例为大家分享了android实现可以滑动的平滑曲线图的具体代码,供大家参考,具体内容如下 直接上代码,里面有详细注解 1 attr 属性编写    <...
    99+
    2024-04-02
  • 怎么用html5的canvas画布绘制贝塞尔曲线
    这篇文章主要介绍“怎么用html5的canvas画布绘制贝塞尔曲线”,在日常操作中,相信很多人在怎么用html5的canvas画布绘制贝塞尔曲线问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,...
    99+
    2024-04-02
  • ps怎么画弯曲的虚线
    ps画弯曲的虚线的方法:1、打开ps,创建新文档;2、选择画笔工具;3、选择画笔选项,调整画笔大小、硬度和颜色;4、在画布上点击鼠标,绘制一条实线;5、选择路径工具;6、在路径工具面板中选择曲线工具;7、使用曲线工具绘制路径;8、选择画笔工...
    99+
    2023-07-26
  • 怎么使用HTML5的Canvas绘制曲线
    今天小编给大家分享一下怎么使用HTML5的Canvas绘制曲线的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们...
    99+
    2024-04-02
  • HTML5中怎么用canvas绘制曲线
    本文小编为大家详细介绍“HTML5中怎么用canvas绘制曲线”,内容详细,步骤清晰,细节处理妥当,希望这篇“HTML5中怎么用canvas绘制曲线”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起...
    99+
    2024-04-02
  • 如何用html5的canvas画布绘制贝塞尔曲线
    这篇“如何用html5的canvas画布绘制贝塞尔曲线”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来...
    99+
    2024-04-02
  • 使用Canvas怎么绘制一个贝赛尔曲线轨迹动画
    本篇文章为大家展示了使用Canvas怎么绘制一个贝赛尔曲线轨迹动画,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。二次贝赛尔曲线   function draw...
    99+
    2023-06-09
  • 怎么使用python画曲线图
    要使用Python画曲线图,可以使用matplotlib库。下面是一个简单的示例代码:```pythonimport matplot...
    99+
    2023-10-12
    python
  • 怎么用HTML5 canvas画线条
    这篇文章主要介绍“怎么用HTML5 canvas画线条”,在日常操作中,相信很多人在怎么用HTML5 canvas画线条问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么用H...
    99+
    2024-04-02
  • Android怎么用Canvas绘制贝塞尔曲线
    这篇文章主要介绍了Android怎么用Canvas绘制贝塞尔曲线的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Android怎么用Canvas绘制贝塞尔曲线文章都会有所收获,下面我们一起来看看吧。用Canvas...
    99+
    2023-07-02
  • html5的画布canvas如何画出弧线和旋转的图形
    本篇文章给大家分享的是有关html5的画布canvas如何画出弧线和旋转的图形,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。 ...
    99+
    2024-04-02
  • 怎么用html5的画布canvas画出简单的图形
    本篇内容介绍了“怎么用html5的画布canvas画出简单的图形”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作