您现在的位置是:网站首页> 编程资料编程资料
canvas进阶之贝塞尔公式推导与物体跟随复杂曲线的轨迹运动HTML5 canvas实现的粒子流向轨迹动画特效源码html5 canvas实现的行星运动轨迹动画特效源码canvas实现按住鼠标移动绘制出轨迹的示例代码
2021-08-31
1160人已围观
简介 这篇文章主要介绍了canvas进阶之贝塞尔公式推导与物体跟随复杂曲线的轨迹运动,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
写在最前
在之前的这篇文章中我们提到了对于贝塞尔公式的运用。本次分享一下如何推导贝塞尔公式以及附一个简单的🌰即小球跟随曲线轨迹运动。
效果预览

对于如何绘制连续的贝塞尔曲线可以参照这篇文章:基于canvas使用贝塞尔曲线平滑拟合折线段
在本例中生成的曲线由以上文章中的源码提供。
贝塞尔曲线公式推导

上面这张图是贝塞尔曲线的完整公式,看起来一脸懵逼=。=,因为这是N阶的推导公式,本次我们以一二阶贝塞尔公式的推导来理解一下这个推导公式的由来。先来看下网上流传已久的几张贝塞尔动图:



在这三张图中最重要的部分是我们需要理解变量t。t的取值范围是0-1。从上面的gif中也可以看出来似乎曲线的绘制过程就是t从0到1的过程。嗯其实就是这样的。t的真实含义是什么呢?
在p0p1、p1p2、p2p3等等的起点到控制点再到终点的连线中,每段连线都被分割成了两部分(仔细看动图中的黑色、绿色、蓝色圆点),各段连线中两部分的比值都是相同的,比值范围是0到1,而这个比值就是t
来看下面的一阶贝塞尔曲线示意图:

pt是p0p1上的任意一点,p0pt / ptp1 = t。从而我们可以引出下面的推导

此时t为时间,v为速度。我们可以看做从p0到p1的距离等于固定速度乘以固定时间

故到p上某一点的时间为固定的速度乘以某个时间值。同时固定的速度已经已经可以表示为上面的推导公式。此时等式右边就形成了t(0,1) / t;即相当于某个时间值 / 固定时间值,即产生了我们一开始所强调的变量t,其取值范围为[0,1]。从而下面的等式也就比较好理解了。

至此一阶贝塞尔曲线我们已经推到了出来,其中变量为起点、终点与比值t。
那么二阶公式如何从一阶过渡过去呢?
来看下面这张图:

其中Pp(t)的经过路径就是我们所求的二阶贝塞尔曲线,那么其实我们也可以将其从一阶进行演变:

我们先将pa、pb两个点所连线段当做一阶曲线,之后再由两端一阶曲线分别表示pa、pb,最后就得到了我们的二阶曲线公式。仔细观察就能发现这和我们最初的完整公式是相同的:

其中n选择不同数值时就可以得出不同阶的曲线公式。同时从上面的推导过程也可以知道,不论是几阶曲线,我们都可以完全由一阶来表示,而这个“表示”的过程就是我们在上面看到的形成动画中那些辅助线。故可以感受下作者自己写的曲线形成动画中的效果,每段辅助线均由一阶曲线形成:

物体跟随复杂曲线轨迹运动
当我们知道曲线的公式有何而来之后,如何让小球沿着曲线运动就很好理解了。我们生成的每段曲线都是可以用公式表示出来的,也正因如此我们就可以得到每个t值时的曲线坐标点。从而知道物体的绘制坐标。
//核心逻辑 LinearGradient.prototype.drawBall = function() { var self = this var item = ctrlNodesArr[ctrlDrawIndex] //存储了各段曲线的控制点 //各段曲线均为三阶贝塞尔,故下面计算x,y值代入到了三阶公式中 var ctrlAx = item.cAx,//各个控制点 ctrlAy = item.cAy, ctrlBx = item.cBx, ctrlBy = item.cBy, ... if(item.t > 1) { ctrlDrawIndex++ //当一段曲线的t>1说明曲线已经走到头 }else { self.ctx.clearRect(0, 0, self.width, self.height) item.t += 0.05 var ballX = ox * Math.pow((1 - item.t), 3) + 3 * ctrlAx * item.t * Math.pow((1 - item.t), 2) + 3 * ctrlBx * Math.pow(item.t, 2) * (1 - item.t) + x * Math.pow(item.t, 3) var ballY = oy * Math.pow((1 - item.t), 3) + 3 * ctrlAy * item.t * Math.pow((1 - item.t), 2) + 3 * ctrlBy * Math.pow(item.t, 2) * (1 - item.t) + y * Math.pow(item.t, 3) //代入三阶贝塞尔曲线公式算出小球的坐标值 self.ctx.beginPath() self.ctx.arc(ballX, ballY, 5, 0, Math.PI * 2, false) self.ctx.fill() } if(ctrlDrawIndex !== ctrlNodesArr.length) { window.requestAnimationFrame(newMap.drawBall.bind(self)) } }最后
demo地址:这里✨✨
源码地址:欢迎star
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
相关内容
- 基于canvas使用贝塞尔曲线平滑拟合折线段的方法canvas进阶之如何画出平滑的曲线
- canvas实现高阶贝塞尔曲线(N阶贝塞尔曲线生成器)html5实现点击弹出图片功能html5 录制mp3音频支持采样率和比特率设置html5表单的required属性使用html5调用摄像头实例代码HTML5页面音频自动播放的实现方式Html5大屏数据可视化开发的实现html实现弹窗的实例HTML5来实现本地文件读取和写入的实现方法HTML 罗盘式时钟的实现HTML5简单实现添加背景音乐的几种方法
- html5实现多图片预览上传及点击可拖拽控件html5拖拽排序多图片上传插件特效源码HTML5 拖拽批量上传文件的示例代码html5使用Drag事件编辑器拖拽上传图片的示例代码HTML5+CSS3实现无插件拖拽上传图片(支持预览与批量)HTML5 canvas实现移动端上传头像拖拽裁剪效果结合html5+nodejs+express实现拖拽上传的功能HTML5拖拽文件到浏览器并实现文件上传下载功能代码html5 拖拽上传图片实例演示HTML5拖拽文件上传的示例代码
- 微信html5页面调用第三方位置导航的示例HTML5页面直接调用百度地图API获取当前位置直接导航目的地的实现代码基于html和CSS3制作酷炫的导航栏使用jquery实现HTML5响应式导航菜单教程css3与html5实现响应式导航菜单(导航栏)效果分享纯html5+css3下拉导航菜单实现代码
- 微信端html5页面调用分享接口示例Html5 实现微信分享及自定义内容的流程Html5页面在微信端的分享的实现方法详解html5 canvas 微信海报分享(个人爬坑)HTML5实现分享到微信好友朋友圈QQ好友QQ空间微博二维码功能HTML5中外部浏览器唤起微信分享功能的代码
- 使用html5新特性轻松监听任何App自带返回键的示例css3实现动画的三种方式如何使用css3实现一个类在线直播的队列动画的示例代码html5新特性与用法大全HTML5新特性之type=file文件上传功能HTML5新特性之语义化标签前端面试必备之html5的新特性CSS3动画和HTML5新特性详解
- 配置H5的滚动条样式的示例代码HTML5实现直播间评论滚动效果的代码h5页面背景图很长要有滚动条滑动效果的实现
- Canvas制作旋转的太极的示例HTML5 Canvas旋转动画的2个代码例子(一个旋转的太极图效果)canvas绘制太极图的实现示例
- 详解px单位html5响应式方案详解HTML5中的picture元素响应式处理图片HTML5响应式(自适应)网页设计的实现推荐10个HTML5响应式框架分享29个基于Bootstrap的HTML5响应式网页设计模板浅谈html5 响应式布局
- html5开发三八女王节表白神器html5实现点击弹出图片功能html5 录制mp3音频支持采样率和比特率设置html5表单的required属性使用html5调用摄像头实例代码HTML5页面音频自动播放的实现方式Html5大屏数据可视化开发的实现html实现弹窗的实例HTML5来实现本地文件读取和写入的实现方法HTML 罗盘式时钟的实现HTML5简单实现添加背景音乐的几种方法
