登录  /  注册

canvas实现高阶贝塞尔曲线

小云云
发布: 2018-01-13 09:40:13
原创
2574人浏览过

本文主要介绍了canvas实现高阶贝塞尔曲线(n阶贝塞尔曲线生成器),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望能帮助到大家。

写在最前

由于原生的Canvas最高只支持到三阶贝塞尔曲线,那么我想添加多个控制点怎么办呢?(即便大部分复杂曲线都可以用3阶贝塞尔来模拟)与此同时,关于贝塞尔控制点的位置我们很难非常直观的清楚到底将控制点设置为多少可以形成我们想要的曲线。本着解决以上两个痛点同时社区内好像并没有N阶的解决方案(js版)故这次作者非常认真的开源了bezierMaker.js!

bezierMaker.js理论上支持N阶贝塞尔曲线的生成,同时提供了试验场供开发者可以自行添加并拖拽控制点最终生成一组绘制动画。非常直观的让开发者知道不同位置的控制点所对应的不同生成曲线。

如果你喜欢这个作品欢迎Star,毕竟star来之不易。。

项目地址:这里✨✨✨

为什么需要一个试验场?

在绘制复杂的高阶贝塞尔曲线时无法知道自己需要的曲线的控制点的精确位置。在试验场中进行模拟,可以实时得到控制点的坐标值,将得到的点坐标变为对象数组传递进BezierMaker类就可以生成目标曲线

效果图

 
 

功能

  1. [x] 试验场可添加任意数量控制点

  2. [x] 试验场支持展示曲线绘制的形成动画

  3. [x] 控制点可自由拖拽

  4. [x] 支持显示贝塞尔曲线形成过程的切线

  5. [x] 3阶及以下贝塞尔曲线的绘制采用原生API

引入


<script src="./bezierMaker.js"></script>
登录后复制

绘制

上面的效果图为试验场的使用,当你通过试验场获得控制点的准确坐标之后,就可以调用bezierMaker.js进行曲线的直接绘制。


/**
 * canvas canvas的dom对象
 * bezierCtrlNodesArr 控制点数组,包含x,y坐标
 * color 曲线颜色
 */
var canvas = document.getElementById(&#39;canvas&#39;)
//3阶之前采用原生方法实现
var arr0 = [{x:70,y:25},{x:24,y:51}]
var arr1 = [{x:233,y:225},{x:170,y:279},{x:240,y:51}]
var arr2 = [{x:23,y:225},{x:70,y:79},{x:40,y:51},{x:300, y:44}]
var arr3 = [{x:333,y:15},{x:70,y:79},{x:40,y:551},{x:170,y:279},{x:17,y:239}]
var arr4 = [{x:53,y:85},{x:170,y:279},{x:240,y:551},{x:70,y:79},{x:40,y:551},{x:170,y:279}]
var bezier0 = new BezierMaker(canvas, arr0, &#39;black&#39;)
var bezier1 = new BezierMaker(canvas, arr1, &#39;red&#39;)
var bezier2 = new BezierMaker(canvas, arr2, &#39;blue&#39;)
var bezier3 = new BezierMaker(canvas, arr3, &#39;yellow&#39;)
var bezier4 = new BezierMaker(canvas, arr4, &#39;green&#39;)
bezier0.drawBezier()
bezier1.drawBezier()
bezier2.drawBezier()
bezier3.drawBezier()
bezier4.drawBezier()
登录后复制

绘制结果

当控制点少于3个时,会适配使用原生的API接口。当控制点多于2个后,由我们自己实现的函数进行描点绘制。

核心原理

绘制贝塞尔曲线

绘制贝塞尔曲线的核心点在于贝塞尔公式的运用:


这个公式中的P0-Pn代表了从起点到各个控制点再到终点的各点与占比t的各种幂运算。


BezierMaker.prototype.bezier = function(t) { //贝塞尔公式调用
    var x = 0,
        y = 0,
        bezierCtrlNodesArr = this.bezierCtrlNodesArr,
        //控制点数组
        n = bezierCtrlNodesArr.length - 1,
        self = this
    bezierCtrlNodesArr.forEach(function(item, index) {
        if(!index) {
            x += item.x * Math.pow(( 1 - t ), n - index) * Math.pow(t, index) 
            y += item.y * Math.pow(( 1 - t ), n - index) * Math.pow(t, index) 
        } else {
        //factorial为阶乘函数
            x += self.factorial(n) / self.factorial(index) / self.factorial(n - index) * item.x * Math.pow(( 1 - t ), n - index) * Math.pow(t, index) 
            y += self.factorial(n) / self.factorial(index) / self.factorial(n - index) * item.y * Math.pow(( 1 - t ), n - index) * Math.pow(t, index) 
        }
    })
    return {
        x: x,
        y: y
    }
}
登录后复制

对所有点进行遍历同时根据当前占比t的值(0

对于贝塞尔公式的推导作者会在之后的文章中专门说明,现在你只需要知道我们通过贝塞尔公式计算出实际贝塞尔曲线被等分成了1000份的各点,用直线连接各点后即可模拟出类曲线。

对于模拟场贝塞尔曲线生成动画的实现

这个部分相关代码可以参考这里

整体思路是用递归的方式来将每个一层控制点当做1阶贝塞尔函数来计算下一层控制点并对应连线。具体逻辑作者会留到深入讲解贝塞尔曲线公式原理的时候一起梳理一下试验场的动画生成原理~

相关推荐:

使用CSS做贝塞尔曲线

贝塞尔曲线的应用详解

实现canvas贝塞尔曲线效果代码演示

以上就是canvas实现高阶贝塞尔曲线的详细内容,更多请关注php中文网其它相关文章!

智能AI问答
PHP中文网智能助手能迅速回答你的编程问题,提供实时的代码和解决方案,帮助你解决各种难题。不仅如此,它还能提供编程资源和学习指导,帮助你快速提升编程技能。无论你是初学者还是专业人士,AI智能助手都能成为你的可靠助手,助力你在编程领域取得更大的成就。
相关标签:
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
最新问题
关于CSS思维导图的课件在哪? 课件
凡人来自于2024-04-16 10:10:18
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2024 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号