微信小程序 使用canvas制作K线实例详解


Posted in Javascript onJanuary 12, 2017

微信小程序 使用canvas制作K线

实现效果图:

微信小程序 使用canvas制作K线实例详解

前言:

我们目的是想要一条平滑的曲线来表示均线等,而不是一条转折点明显的折线。因此还得继续探索api。我们发现,在canvas API中,能够画出曲线的有2个

beZierCurveTo(num1, num2, num3, num4, x, y)
quadraticCurveTo(num1, num2, x, y)

这两个api都是通过贝塞尔曲线来绘制路径。好在学习PS的时候,对贝塞尔曲线的具体表现也是有一定的熟练程度的,因此知道要确定一条由多个点组成的曲线路径,每一个转折点都得有2个控制点来控制曲线的表现

而在曲线的起点和终点,就只能有一个控制点了。因此,我们在绘制起点和终点时,得使用quadraticCurveTo,绘制中间的点,则使用beZierCurveTo。

现在的难点是,如何通过已知的要经过的点,计算出他们的控制点?

为了找到一个行之有效的公式,于是草稿走起。画了一个只有自己看得懂的草稿。

微信小程序 使用canvas制作K线实例详解

没想到告别高中数学那么多年,凭着一点点的记忆,花了一上午,强行搞了一个公式出来,我想如果我还是高中的数学水平的话,估计也就10分钟就能怼出来了,汗!

不知道大家还记不记得切线的概念,如果我们要画一条贝塞尔曲线,M[i-1]是起点,M[i]是终点,另外的两个控制点为A1, A2,这2个控制点一定会在某一个曲面的切线上,而切线则可以由三个点来确定,如我的草稿中,最上面橘黄色的线条就是切线,我们只需要在这条切线上,随意取2个点,分别作为前后曲线的控制点即可

于是,经过我长时间的思考,总结了一个公式如下

A1[M[i-1][0] + a*(M[i][0] - M[i-2][0]), M[i-1][1] + b*(M[i][1] - M[i-2][1])]

A2[M[i][0] - b*(M[i+1][0] - M[i-1][0]), M[i][1] - b*(M[i+1][1] - M[i-1][1])]

其中系数a, b是一个根据情况我随意取的一个值,我试过,建议在0.3附近取值并调试,试试看具体效果再确定

第一个点和最后一点因为无法通过这种方式取得2个控制点,因此我就在点集合的前后各加了一个随意自定自定的点,在实际遍历的时候忽略他们即可。

整理了思路,具体实现如下

bezierLine (canvasId, options) {
let windowWidth = 0
wx.getSystemInfo({
 success (result) {
  windowWidth = result.windowWidth
 }
})
let a = windowWidth / (options.xAxis.length-1)
let data = []
options.xAxis.map((item, i) => {
 data.push([i * a, 200 - options.yAxis[i]])
})
data.unshift(data[0])
data.push(data[data.length - 1])

const ctx = wx.createCanvasContext(canvasId)
ctx.beginPath()
data.map((item, i) => {
 const a = 0.25
 const b = 0.25
 if (i == 0 || i == data.length - 1) {
  // do nothing
 } else if (i == 1) {
  ctx.moveTo(item[0], item[1])
 } else {
  const a1 = data[i - 1][0] + a * (data[i][0] - data[i - 2][0])
  const a2 = data[i - 1][1] + b * (data[i][1] - data[i - 2][1])
  const b1 = data[i][0] - b * (data[i + 1][0] - data[i - 1][0])
  const b2 = data[i][1] - b * (data[i + 1][1] - data[i - 1][1])
  ctx.bezierCurveTo(a1, a2, b1, b2, item[0], item[1])
 }
})
ctx.setLineWidth(1)
ctx.setStrokeStyle('red')
ctx.stroke()
ctx.draw()
}
// 在onLoad中调用
this.bezierLine('stage', {
 xAxis: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30],
 yAxis: [11, 33, 22, 32, 14, 15, 20, 60, 23, 44, 77, 122, 133, 89, 156, 122,128, 143, 111, 101, 132, 99, 98, 44, 62, 74, 111, 13, 42, 55]
})

oh yeah! 效果还可以,以后再也不用担心曲线的绘制了,理我们的k线图又近了一步

ps: 数据的组织形式可以多种多样,可以是数组,可以是二位数组,也可以是对象,这并不是最主要的点,只要能正确处理就行了

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

Javascript 相关文章推荐
在b/s开发中经常用到的javaScript技术
Aug 23 Javascript
学习jquery必备 api中英文对照的chm手册 下载
May 03 Javascript
你必须知道的Javascript知识点之"深入理解作用域链"的介绍
Apr 23 Javascript
jQuery实现返回顶部功能
Feb 23 Javascript
javascript实现任务栏消息提示的简单实例
May 31 Javascript
浅谈js中子页面父页面方法 变量相互调用
Aug 04 Javascript
AngularJS变量及过滤器Filter用法分析
Nov 22 Javascript
VueJs使用Amaze ui调整列表和内容页面
Nov 30 Javascript
使用typescript开发angular模块并发布npm包
Apr 19 Javascript
vue和webpack打包项目相对路径修改的方法
Jun 15 Javascript
Node.js的进程管理的深入理解
Jan 09 Javascript
vue实现跨域的方法分析
May 21 Javascript
JS实现仿百度文库评分功能
Jan 12 #Javascript
移动端基础事件总结与应用
Jan 12 #Javascript
微信小程序 PHP后端form表单提交实例详解
Jan 12 #Javascript
简单的渐变轮播插件
Jan 12 #Javascript
那些精彩的JavaScript代码片段
Jan 12 #Javascript
JavaScript实现星级评分
Jan 12 #Javascript
angular2倒计时组件使用详解
Jan 12 #Javascript
You might like
教你如何解密 “ PHP 神盾解密工具 ”
2014/06/20 PHP
PHP实现四种基础排序算法的运行时间比较(推荐)
2016/08/11 PHP
thinkPHP框架实现多表查询的方法
2018/06/14 PHP
PHP的PDO大对象(LOBs)
2019/01/27 PHP
Laravel框架实现定时Task Scheduling例子
2019/10/22 PHP
写的htc的数据表格
2007/01/20 Javascript
用javascript实现页面打印的三种方法
2007/03/05 Javascript
jQuery 方法大全方便学习参考
2010/02/25 Javascript
js图片卷帘门导航菜单特效代码分享
2015/09/10 Javascript
浅谈JavaScript for循环 闭包
2016/06/22 Javascript
Angular.js 实现数字转换汉字实例代码
2016/07/14 Javascript
Vue.js 和 MVVM 的注意事项
2016/11/07 Javascript
微信小程序左滑删除效果的实现代码
2017/02/20 Javascript
使用jquery datatable和bootsrap创建表格实例代码
2017/03/17 Javascript
Angularjs中数据绑定的实例详解
2017/08/25 Javascript
jQuery 利用ztree实现树形表格的实例代码
2017/09/27 jQuery
iview日期控件,双向绑定日期格式的方法
2018/03/15 Javascript
node运行js获得输出的三种方式示例详解
2020/07/02 Javascript
用JavaScript实现贪吃蛇游戏
2020/10/23 Javascript
记录一次websocket封装的过程
2020/11/23 Javascript
Python简单生成随机姓名的方法示例
2017/12/27 Python
详谈python3中用for循环删除列表中元素的坑
2018/04/19 Python
在pytorch中实现只让指定变量向后传播梯度
2020/02/29 Python
Python读取文件内容为字符串的方法(多种方法详解)
2020/03/04 Python
pycharm 实现本地写代码,服务器运行的操作
2020/06/08 Python
如何在scrapy中捕获并处理各种异常
2020/09/28 Python
python中操作文件的模块的方法总结
2021/02/04 Python
西班牙香水和化妆品购物网站:Arenal Perfumerías
2019/03/01 全球购物
Koral官方网站:女性时尚运动服
2019/04/10 全球购物
如何利用cmp命令比较文件
2013/09/23 面试题
2014年十一国庆向国旗敬礼寄语
2014/04/11 职场文书
2014年党支部书记工作总结
2014/12/04 职场文书
朋友圈早安励志语录!
2019/07/08 职场文书
win10安装配置nginx的过程
2021/03/31 Servers
PyQt5结合QtDesigner实现文本框读写操作
2021/06/11 Python
Nginx实现会话保持的两种方式
2022/03/18 Servers