![【移动应用开发技术】在微信小程序中如何使用canvas绘制天气折线图_第1页](http://file4.renrendoc.com/view/3bd8cbfd7a9aeefe55b5a58f414b4795/3bd8cbfd7a9aeefe55b5a58f414b47951.gif)
![【移动应用开发技术】在微信小程序中如何使用canvas绘制天气折线图_第2页](http://file4.renrendoc.com/view/3bd8cbfd7a9aeefe55b5a58f414b4795/3bd8cbfd7a9aeefe55b5a58f414b47952.gif)
![【移动应用开发技术】在微信小程序中如何使用canvas绘制天气折线图_第3页](http://file4.renrendoc.com/view/3bd8cbfd7a9aeefe55b5a58f414b4795/3bd8cbfd7a9aeefe55b5a58f414b47953.gif)
![【移动应用开发技术】在微信小程序中如何使用canvas绘制天气折线图_第4页](http://file4.renrendoc.com/view/3bd8cbfd7a9aeefe55b5a58f414b4795/3bd8cbfd7a9aeefe55b5a58f414b47954.gif)
![【移动应用开发技术】在微信小程序中如何使用canvas绘制天气折线图_第5页](http://file4.renrendoc.com/view/3bd8cbfd7a9aeefe55b5a58f414b4795/3bd8cbfd7a9aeefe55b5a58f414b47955.gif)
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【移动应用开发技术】在微信小程序中如何使用canvas绘制天气折线图
今天在下给大家分享一下在微信小程序中如何使用canvas绘制天气折线图的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。折线效果图:自定义组件line-chart<canvas
type="2d"
id="line"
class="line-class"
style="width:{{width}}px;height:{{height}}px"
/>Component({
externalClasses:
['line-class'],
properties:
{
width:
String,
height:
String,
data:
Array,
},
observers:
{
width()
{
//
这里监听
width
变化重绘
canvas
//
动态传入
width
好像只能这样了..
const
query
=
this.createSelectorQuery();
query
.select('#line')
.fields({
node:
true,
size:
true
})
.exec(res
=>
{
const
canvas
=
res[0].node;
const
ctx
=
canvas.getContext('2d');
const
width
=
res[0].width;
//
画布宽度
const
height
=
res[0].height;
//
画布高度
console.log(`宽度:
${width},
高度:
${height}`);
const
dpr
=
wx.getSystemInfoSync().pixelRatio;
canvas.width
=
width
*
dpr;
canvas.height
=
height
*
dpr;
ctx.scale(dpr,
dpr);
//
开始绘图
this.drawLine(ctx,
width,
height,
this.data.data);
});
},
},
methods:
{
drawLine(ctx,
width,
height,
data)
{
const
Max
=
Math.max(...data);
const
Min
=
Math.min(...data);
//
把
canvas
的宽度,
高度按一定规则平分
const
startX
=
width
/
(data.length
*
2),
//
起始点的横坐标
X
baseY
=
height
*
0.9,
//
基线纵坐标
Y
diffX
=
width
/
data.length,
diffY
=
(height
*
0.7)
/
(Max
-
Min);
//
高度预留
0.2
写温度
ctx.beginPath();
ctx.textAlign
=
'center';
ctx.font
=
'13px
Microsoft
YaHei';
ctx.lineWidth
=
2;
ctx.strokeStyle
=
'#ABDCFF';
//
画折线图的线
data.forEach((item,
index)
=>
{
const
x
=
startX
+
diffX
*
index,
y
=
baseY
-
(item
-
Min)
*
diffY;
ctx.fillText(`${item}°`,
x,
y
-
10);
ctx.lineTo(x,
y);
});
ctx.stroke();
//
画折线图背景
ctx.lineTo(startX
+
(data.length
-
1)
*
diffX,
baseY);
//
基线终点
ctx.lineTo(startX,
baseY);
//
基线起点
const
lingrad
=
ctx.createLinearGradient(0,
0,
0,
height
*
0.7);
lingrad.addColorStop(0,
'rgba(255,255,255,0.9)');
lingrad.addColorStop(1,
'rgba(171,220,255,0)');
ctx.fillStyle
=
lingrad;
ctx.fill();
//
画折线图上的小圆点
ctx.beginPath();
data.forEach((item,
index)
=>
{
const
x
=
startX
+
diffX
*
index,
y
=
baseY
-
(item
-
Min)
*
diffY;
ctx.moveTo(x,
y);
ctx.arc(x,
y,
3,
0,
2
*
Math.PI);
});
ctx.fillStyle
=
'#0396FF';
ctx.fill();
},
},
});data就是温度数组,如[1,2,...]因为不知道温度数值有多少个,因此这里的width动态传入有个小问题,就是宽度过大的话真机不会显示...
//
获取
scroll-view
的总宽度
wx.createSelectorQuery()
.select('.hourly')
.boundingClientRect(rect
=>
{
this.setData({
scrollWidth:
rect.right
-
rect.left,
});
})
.exec();<view
class="title">小时概述</view>
<scroll-view
scroll-x
scroll-y
class="scroll"
show-scrollbar="{{false}}"
enhanced="{{true}}">
<view
class="hourly">
<view
wx:for="{{time}}"
wx:key="index">{{item}}</view>
</view>
<line-chart
line-class="line"
width="{{scrollWidth}}"
height="100"
data="{{temp}}"
/>
</scroll-view>这里写scroll-x和scroll-y,要不会出现绝对定位偏移的问题,也不知道为什么.scroll
{
position:
relative;
height:
150px;
width:
100%;
}
.hourly
{
display:
flex;
height:
150px;
position:
absolute;
top:
0;
}
.hourly
>
view
{
min-width:
3.5em;
text-align:
center;
}
.line
{
//
折线图绝对定位到底部
position:
absolute;
bottom:
0;
}这里使用绝对定位其实是想模拟墨迹天气这种折线图和每一天在一个块内的效果,所以hourly要和scroll-view等高,canvas需要定位一下主要是不知道墨迹天气怎么实现的,只能暂时这样三阶贝塞尔曲线效果图emmm,好像并不怎么圆滑计算控制点首先写一个点类class
Point
{
constructor(x,
y)
{
this.x
=
x;
this.y
=
y;
}
}也就是使用bezierCurveTo的时候最后一个点是下一个点,前两个是控制点浓缩一下就是这里的a和b可以是任意正数因此定义一个计算某点的控制点A和B的方法/**
*
计算当前点的贝塞尔曲线控制点
*
@param
{Point}
previousPoint:
前一个点
*
@param
{Point}
currentPoint:
当前点
*
@param
{Point}
nextPoint1:
下一个点
*
@param
{Point}
nextPoint2:
下下个点
*
@param
{Number}
scale:
系数
*/
calcBezierControlPoints(
previousPoint,
currentPoint,
nextPoint1,
nextPoint2,
scale
=
0.25
)
{
let
x
=
currentPoint.x
+
scale
*
(nextPoint1.x
-
previousPoint.x);
let
y
=
currentPoint.y
+
scale
*
(nextPoint1.y
-
previousPoint.y);
const
controlPointA
=
new
Point(x,
y);
//
控制点
A
x
=
nextPoint1.x
-
scale
*
(nextPoint2.x
-
currentPoint.x);
y
=
nextPoint1.y
-
scale
*
(nextPoint2.y
-
currentPoint.y);
const
controlPointB
=
new
Point(x,
y);
//
控制点
B
return
{
controlPointA,
controlPointB
};
}这里scale就是a和b,不过将它们的取值相等但是第一个点没有previousPoint,倒数第二个点没有nextPoint2因此当点是第一个的时候,使用currentPoint代替previousPoint当倒数第二个点的时候,使用nextPoint1代替nextPoint2至于最后一个点,不需要做任何事,因为bezierCurveTo第三个参数就是下一个点,只需要提供坐标就能连起来,不需要计算控制点因此绘制三阶贝塞尔曲线的方法:/**
*
绘制贝塞尔曲线
*
ctx.bezierCurveTo(控制点1,
控制点2,
当前点);
*/
drawBezierLine(ctx,
data,
options)
{
const
{
startX,
diffX,
baseY,
diffY,
Min
}
=
options;
ctx.beginPath();
//
先移动到第一个点
ctx.moveTo(startX,
baseY
-
(data[0]
-
Min)
*
diffY);
data.forEach((e,
i)
=>
{
let
curPoint,
prePoint,
nextPoint1,
nextPoint2,
x,
y;
//
当前点
x
=
startX
+
diffX
*
i;
y
=
baseY
-
(e
-
Min)
*
diffY;
curPoint
=
new
Point(x,
y);
//
前一个点
x
=
startX
+
diffX
*
(i
-
1);
y
=
baseY
-
(data[i
-
1]
-
Min)
*
diffY;
prePoint
=
new
Point(x,
y);
//
下一个点
x
=
startX
+
diffX
*
(i
+
1);
y
=
baseY
-
(data[i
+
1]
-
Min)
*
diffY;
nextPoint1
=
new
Point(x,
y);
//
下下个点
x
=
startX
+
diffX
*
(i
+
2);
y
=
baseY
-
(data[i
+
2]
-
Min)
*
diffY;
nextPoint2
=
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 《理解成语的方法》课件
- 《教师演示技能》课件
- 《骨骼系统MRI袁飞》课件
- 《中长链脂肪乳》课件
- 三年级语文作文指导课-我爱吃的水果课件
- 确定合同完成进度的方法
- 探索本科理科研究
- 强化“五个认同”筑牢新时代内蒙古民族团结基石
- 快速制作网页的方法
- 2025年皮革、毛皮及其制品加工专用设备项目发展计划
- 中国水利水电第十二工程局有限公司招聘笔试真题2023
- DB37-T3953-2020医疗卫生机构安全风险分级管控体系实施指南
- 工业机器人系统运维员(中级)课件全套 宋永昌 项目1-3 机械系统检查与诊断-工业机器人运行维护与保养
- T-CSPSTC 111-2022 表层混凝土低渗透高密实化施工技术规程
- 医院急救中心劳务外包采购项目评标办法(评分细则表)
- 浩顺一卡通软件新版说明书
- JTG H12-2015 公路隧道养护技术规范
- 2024年高考英语新课标1卷讲评(七选五+完形填空+语法填空)-2025届高三英语一轮复习
- 植物检疫员岗位职责说明书
- 2023~2024学年二年级下册语文期末模考试卷·创意情境 统编版
- 2024年高考历史总复习中外历史大事年表
评论
0/150
提交评论