微信小程序 使用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 相关文章推荐
通过JAVAScript实现页面自适应
Jan 19 Javascript
一个原生的用户等级的进度条
Jul 03 Javascript
仿百度的关键词匹配搜索示例
Sep 25 Javascript
node.js中的emitter.on方法使用说明
Dec 10 Javascript
javascript经典特效分享 手风琴、轮播图、图片滑动
Sep 14 Javascript
JS中mouseup事件丢失的原因与解决办法
Jun 14 Javascript
vue2组件之select2调用的示例代码
Oct 12 Javascript
bootstrap table sum总数量统计实现方法
Oct 29 Javascript
原生javascript实现连连看游戏
Jan 03 Javascript
vue实现微信二次分享以及自定义分享的示例
Mar 20 Javascript
微信小程序 WXML节点信息查询详解
Jul 29 Javascript
解决vuex数据页面刷新后初始化操作
Jul 26 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+mysql 实现身份验证代码
2010/03/24 PHP
ThinkPHP中的关联模型注意点
2014/06/16 PHP
20个2014年最优秀的PHP框架回顾
2014/10/22 PHP
php生成带logo二维码方法小结
2016/04/08 PHP
PHP判断一个数组是另一个数组子集的方法详解
2017/07/31 PHP
jQuery模拟超链接点击效果代码
2013/04/21 Javascript
JavaScript中的typeof操作符用法实例
2014/04/05 Javascript
js实现可兼容IE、FF、Chrome、Opera及Safari的音乐播放器
2015/02/11 Javascript
通过BootStrap实现轮播图的实际应用
2016/09/26 Javascript
jQuery视差滚动效果网页实现方法经验总结
2016/09/29 Javascript
原生js实现新闻列表展开/收起全文功能
2017/01/20 Javascript
微信小程序 自定义对话框实例详解
2017/01/20 Javascript
JavaScript字符集编码与解码详谈
2017/02/02 Javascript
详解nodeJS中读写文件方法的区别
2017/03/06 NodeJs
详解Angular2 关于*ngFor 嵌套循环
2017/05/22 Javascript
JavaScript的setter与getter方法
2017/11/29 Javascript
AngularJS使用Filter自定义过滤器控制ng-repeat去除重复功能示例
2018/04/21 Javascript
详解JS浏览器事件循环机制
2019/03/27 Javascript
JS实现动态无缝轮播
2020/01/11 Javascript
Python调用C/C++动态链接库的方法详解
2014/07/22 Python
Windows下用py2exe将Python程序打包成exe程序的教程
2015/04/08 Python
django与小程序实现登录验证功能的示例代码
2019/02/19 Python
Python3.7 新特性之dataclass装饰器
2019/05/27 Python
python爬虫-模拟微博登录功能
2019/09/12 Python
Python3 解决读取中文文件txt编码的问题
2019/12/20 Python
服务器端jupyter notebook映射到本地浏览器的操作
2020/04/14 Python
python的reverse函数翻转结果为None的问题
2020/05/11 Python
体育教育毕业生自荐信
2013/11/21 职场文书
小学生成长感言
2014/01/30 职场文书
作文评语大全
2014/04/23 职场文书
学校食品安全实施方案
2014/06/14 职场文书
入党介绍人意见范文
2015/06/01 职场文书
旅行社计调工作总结
2015/08/12 职场文书
《祁黄羊》教学反思
2016/02/20 职场文书
当你焦虑迷茫时,请读读这6句话
2019/07/24 职场文书
七年级之开学家长寄语35句
2019/09/05 职场文书