微信小程序 使用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函数返回多个返回值的示例代码
Nov 05 Javascript
javascript得到当前页的来路即前一页地址的方法
Feb 18 Javascript
创建js对象和js类的方法汇总
Dec 24 Javascript
JavaScript的removeChild()函数用法详解
Dec 27 Javascript
JS控制静态页面之间传递参数获取参数并应用的简单实例
Aug 10 Javascript
JS验证码实现代码
Sep 14 Javascript
JavaScript实现左侧菜单效果
Dec 14 Javascript
Webpack实战加载SVG的方法
Dec 26 Javascript
vue.js在标签属性中插入变量参数的方法
Mar 06 Javascript
学习jQuery中的noConflict()用法
Sep 28 jQuery
基于vue+axios+lrz.js微信端图片压缩上传方法
Jun 25 Javascript
微信小程序自定义单项选择器样式
Jul 25 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
利用文件属性结合Session实现在线人数统计
2006/10/09 PHP
使用PHP提取视频网站页面中的FLASH地址的代码
2010/04/17 PHP
js和php邮箱地址验证的实现方法
2014/01/09 PHP
php使用MySQL保存session会话的方法
2015/06/26 PHP
php随机显示指定文件夹下图片的方法
2015/07/13 PHP
三个思路解决laravel上传文件报错:413 Request Entity Too Large问题
2017/11/13 PHP
js 效率组装字符串 StringBuffer
2009/12/23 Javascript
从零学JS之你需要了解的几本书
2014/05/19 Javascript
js常用数组操作方法简明总结
2014/06/20 Javascript
js 数组去重的四种实用方法
2014/09/09 Javascript
JS实现兼容性较好的随屏滚动效果
2015/11/09 Javascript
Vue数据驱动模拟实现4
2017/01/12 Javascript
Bootstrap treeview实现动态加载数据并添加快捷搜索功能
2018/01/07 Javascript
Vue.js 通过jQuery ajax获取数据实现更新后重新渲染页面的方法
2018/08/09 jQuery
jQuery实现获取当前鼠标位置并输出功能示例
2019/01/05 jQuery
webpack.DefinePlugin与cross-env区别详解
2020/02/23 Javascript
Python单元测试框架unittest简明使用实例
2015/04/13 Python
python 限制函数执行时间,自己实现timeout的实例
2019/01/12 Python
Python通过for循环理解迭代器和生成器实例详解
2019/02/16 Python
详解python中__name__的意义以及作用
2019/08/07 Python
Python性能分析工具Profile使用实例
2019/11/19 Python
TensorFlow tf.nn.conv2d实现卷积的方式
2020/01/03 Python
Python使用graphviz画流程图过程解析
2020/03/31 Python
Python求解排列中的逆序数个数实例
2020/05/03 Python
使用Numpy对特征中的异常值进行替换及条件替换方式
2020/06/08 Python
python 根据列表批量下载网易云音乐的免费音乐
2020/12/03 Python
纯CSS3实现给头像加个光芒四射且旋转的背景动画效果
2014/05/07 HTML / CSS
Stefania Mode美国:奢华设计师和时尚服装
2018/01/07 全球购物
法国在线药房:1001Pharmacies
2021/03/07 全球购物
Internet主要有哪些网络群组成
2015/12/24 面试题
授权委托书格式模板
2014/04/03 职场文书
法学专业毕业生自荐信
2014/06/11 职场文书
关于读书的演讲稿1000字
2014/08/27 职场文书
党员四风自我剖析材料
2014/10/07 职场文书
付款承诺函范文
2015/01/21 职场文书
学生逃课万能检讨书2000字
2015/02/17 职场文书