微信小程序 使用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 相关文章推荐
清除网页历史记录,屏蔽后退按钮!
Dec 22 Javascript
日期 时间js控件
May 07 Javascript
使用JSON.parse将json字符串转换成json对象的时候会出错
Sep 04 Javascript
JavaScript与jQuery实现的闪烁输入效果
Feb 18 Javascript
IE和Firefox之间在JavaScript语法上的差异
Apr 22 Javascript
JS实现的驼峰式和连字符式转换功能分析
Dec 21 Javascript
canvas绘制表盘时钟
Jan 23 Javascript
AngularJS ui-router (嵌套路由)实例
Mar 10 Javascript
vue.js前后端数据交互之提交数据操作详解
Apr 24 Javascript
bootstrap table列和表头对不齐的解决方法
Jul 19 Javascript
vue实现Input输入框模糊查询方法
Jan 29 Javascript
layui数据表格重载实现往后台传参
Nov 15 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 远程文件管理,可以给表格排序,遍历目录,时间排序
2009/08/07 PHP
教你在PHPStorm中配置Xdebug
2015/07/27 PHP
完美解决phpdoc导出文档中@package的warning及Error的错误
2016/05/17 PHP
php array_walk_recursive 使用自定的函数处理数组中的每一个元素
2016/11/16 PHP
PHP实现的统计数据功能详解
2016/12/06 PHP
浅谈thinkphp的nginx配置,以及重写隐藏index.php入口文件方法
2019/10/12 PHP
php实现JWT(json web token)鉴权实例详解
2019/11/05 PHP
javascript 对象比较实现代码
2009/04/27 Javascript
10个很棒的jQuery代码片段
2015/09/24 Javascript
表单验证正则表达式实例代码详解
2015/11/09 Javascript
JavaScript类型检测之typeof 和 instanceof 的缺陷与优化
2016/01/13 Javascript
jQuery实现从身份证号中获取出生日期和性别的方法分析
2016/02/25 Javascript
Javascript 实现放大镜效果实例详解
2016/12/03 Javascript
B/S(Web)实时通讯解决方案分享
2017/04/06 Javascript
webpack里使用jquery.mCustomScrollbar插件的方法
2018/05/30 jQuery
基于JS实现父组件的请求服务过程解析
2019/10/14 Javascript
微信小程序select下拉框实现源码
2019/11/08 Javascript
[48:24]完美世界DOTA2联赛PWL S3 Forest vs INK ICE 第一场 12.09
2020/12/12 DOTA
Python遍历目录的4种方法实例介绍
2015/04/13 Python
Python编程实现生成特定范围内不重复多个随机数的2种方法
2017/04/14 Python
python3.4用函数操作mysql5.7数据库
2017/06/23 Python
Python实现的密码强度检测器示例
2017/08/23 Python
pandas中的DataFrame按指定顺序输出所有列的方法
2018/04/10 Python
python实现对图片进行旋转,放缩,裁剪的功能
2019/08/07 Python
Python run()函数和start()函数的比较和差别介绍
2020/05/03 Python
python中sys模块是做什么用的
2020/08/16 Python
使用python将微信image下.dat文件解密为.png的方法
2020/11/30 Python
New Balance德国官方网站:购买鞋子和服装
2019/08/31 全球购物
百年校庆节目主持词
2014/03/27 职场文书
闭幕式主持词
2014/04/02 职场文书
缓刑人员思想汇报
2014/10/11 职场文书
校园游戏活动新闻稿
2014/10/15 职场文书
2014年学校财务工作总结
2014/12/06 职场文书
2015个人简历自我评价语
2015/03/11 职场文书
NodeJs使用webpack打包项目的方法详解
2022/02/28 NodeJs
《艾尔登法环》1.03.3补丁上线 碎星伤害调整
2022/04/06 其他游戏