微信小程序 使用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 相关文章推荐
用js统计用户下载网页所需时间的脚本
Oct 15 Javascript
Javascript load Page,load css,load js实现代码
Mar 31 Javascript
node在两个div之间移动,用ztree实现
Mar 06 Javascript
表格单元格交错着色实现思路及代码
Apr 01 Javascript
localResizeIMG先压缩后使用ajax无刷新上传(移动端)
Aug 11 Javascript
jQuery实现非常实用漂亮的select下拉菜单选择效果
Nov 06 Javascript
Bootstrap 组件之按钮(二)
May 11 Javascript
浅谈javascript中的加减时间
Jul 12 Javascript
BootStrap与Select2使用小结
Feb 17 Javascript
vue封装第三方插件并发布到npm的方法
Sep 25 Javascript
微信小程序之swiper轮播图中的图片自适应高度的方法
Apr 23 Javascript
Node.js 进程平滑离场剖析小结
Jan 24 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中使用模板的方法
2008/05/24 PHP
PHP程序员面试 切忌急功近利(更需要注重以后的发展)
2010/09/01 PHP
PHP实现抓取Google IP并自动修改hosts文件
2015/02/12 PHP
PHP析构函数destruct与垃圾回收机制的讲解
2019/03/22 PHP
JavaScript 动态创建VML的方法
2009/10/14 Javascript
jQuery简单实现日历的方法
2015/05/04 Javascript
纯js代码实现简单计算器
2015/12/02 Javascript
纯js实现手风琴效果
2020/04/17 Javascript
js canvas实现擦除动画
2016/07/16 Javascript
input获取焦点时底部菜单被顶上来问题的解决办法
2017/01/24 Javascript
如何使用Bootstrap 按钮实例详解
2017/03/29 Javascript
JavaScript数据结构之优先队列与循环队列实例详解
2017/10/27 Javascript
解决Mac node版本升级失败的问题
2018/05/16 Javascript
详解JavaScript作用域和作用域链
2019/03/19 Javascript
Node.js在图片模板上生成二维码图片并附带底部文字说明实现详解
2019/08/07 Javascript
Layui数据表格跳转到指定页的实现方法
2019/09/05 Javascript
JS中FileReader类实现文件上传及时预览功能
2020/03/27 Javascript
Python lambda和Python def区别分析
2014/11/30 Python
在Python的Flask框架中实现全文搜索功能
2015/04/20 Python
windows下安装Python和pip终极图文教程
2017/03/05 Python
python3 发送任意文件邮件的实例
2018/01/23 Python
PyQt5每天必学之滑块控件QSlider
2018/04/20 Python
Python Django基础二之URL路由系统
2019/07/18 Python
Django 拆分model和view的实现方法
2019/08/16 Python
解决pytorch-yolov3 train 报错的问题
2020/02/18 Python
python中添加模块导入路径的方法
2021/02/03 Python
CSS3实现内凹圆角的实例代码
2017/05/04 HTML / CSS
HTML5 Canvas鼠标与键盘事件demo示例
2013/07/04 HTML / CSS
ASOS亚洲:ASOS Asia
2018/03/04 全球购物
Annoushka英国官网:英国奢侈珠宝品牌
2018/10/20 全球购物
为什么要使用servlet
2016/01/17 面试题
我的梦想演讲稿
2014/04/30 职场文书
新文化运动的口号
2014/06/21 职场文书
2014国庆黄金周超市促销活动方案
2014/09/21 职场文书
研究生论文答辩开场白
2015/05/27 职场文书
教师培训简讯
2015/07/20 职场文书