微信小程序 使用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实现ASP分页函数 HTML分页函数
Sep 22 Javascript
ie和firefox中img对象区别的困惑
Dec 27 Javascript
运用jQuery定时器的原理实现banner图片切换
Oct 22 Javascript
node.js中的console.trace方法使用说明
Dec 09 Javascript
JavaScript模块化开发之SeaJS
Dec 13 Javascript
javascript数字验证的实例代码(推荐)
Aug 20 Javascript
vue router动态路由下让每个子路由都是独立组件的解决方案
Apr 24 Javascript
Vue.js 2.x之组件的定义和注册图文详解
Jun 19 Javascript
JQuery扩展对象方法操作示例
Aug 21 jQuery
微信小程序如何修改本地缓存key中单个数据的详解
Apr 26 Javascript
Express 配置HTML页面访问的实现
Nov 01 Javascript
详解vue之自行实现派发与广播(dispatch与broadcast)
Jan 19 Vue.js
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 中的一些经验积累
2006/10/09 PHP
实战mysql导出中文乱码及phpmyadmin导入中文乱码的解决方法
2010/06/11 PHP
Laravel 5 框架入门(一)
2015/04/09 PHP
浅谈PHP的exec()函数无返回值排查方法(必看)
2017/03/31 PHP
php安装扩展mysqli的实现步骤及报错解决办法
2017/09/23 PHP
PHP经典设计模式之依赖注入定义与用法详解
2019/05/21 PHP
php设计模式之中介者模式分析【星际争霸游戏案例】
2020/03/23 PHP
Javascript !!的作用
2008/12/04 Javascript
网站页面自动跳转实现方法PHP、JSP(下)
2010/08/01 Javascript
基于jQuery的为attr添加id title等效果的实现代码
2011/04/20 Javascript
js实现点击后将文字或图片复制到剪贴板的方法
2014/08/04 Javascript
使用命令对象代替switch语句的写法示例
2015/02/28 Javascript
angularjs学习笔记之完整的项目结构
2015/09/26 Javascript
jQuery简单入门示例之用户校验demo示例
2016/07/09 Javascript
使用ionic在首页新闻中应用到的跑马灯效果的实现方法
2017/02/13 Javascript
Vue2.0 slot分发内容与props验证的方法
2017/12/12 Javascript
微信小程序实现滚动消息通知
2018/02/02 Javascript
浅谈webpack SplitChunksPlugin实用指南
2018/09/17 Javascript
Vue v-for中的 input 或 select的值发生改变时触发事件操作
2020/08/31 Javascript
Vue常用API、高级API的相关总结
2021/02/02 Vue.js
Python守护进程(daemon)代码实例
2015/03/06 Python
Python实现图片转字符画的示例
2017/08/22 Python
浅谈Python脚本开头及导包注释自动添加方法
2018/10/27 Python
Django 中自定义 Admin 样式与功能的实现方法
2019/07/04 Python
Python3.6+selenium2.53.6自动化测试_读取excel文件的方法
2019/09/06 Python
Django restframework 框架认证、权限、限流用法示例
2019/12/21 Python
Python随机数函数代码实例解析
2020/02/09 Python
详解anaconda安装步骤
2020/11/23 Python
HTML5页面直接调用百度地图API获取当前位置直接导航目的地的实现代码
2018/03/02 HTML / CSS
canvas里面如何基于随机点绘制一个多边形的方法
2018/06/13 HTML / CSS
自我评价中英文语句
2013/11/30 职场文书
白酒业务员岗位职责
2013/12/27 职场文书
考试作弊检讨书
2014/10/21 职场文书
党的群众路线教育实践活动督导组工作情况汇报
2014/10/28 职场文书
MySQL 使用自定义变量进行查询优化
2021/05/14 MySQL
Pygame Event事件模块的详细示例
2021/11/17 Python