成人怡红院-成人怡红院视频在线观看-成人影视大全-成人影院203nnxyz-美女毛片在线看-美女免费黄

站長(zhǎng)資訊網(wǎng)
最全最豐富的資訊網(wǎng)站

手把手教你在微信小程序中使用canvas繪制天氣折線圖(附代碼)

微信小程序中如何繪制天氣折線圖?下面本篇文章就來(lái)給大家介紹一下在微信小程序中使用canvas繪制天氣折線圖的方法,以及使用三階貝塞爾曲線擬合溫度點(diǎn),使之變得圓滑,曲線底部有背景色,希望對(duì)大家有所幫助!

手把手教你在微信小程序中使用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() {       // 這里監(jiān)聽(tīng) width 變化重繪 canvas       // 動(dòng)態(tài)傳入 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; // 畫(huà)布寬度           const height = res[0].height; // 畫(huà)布高度            console.log(`寬度: ${width}, 高度: ${height}`);            const dpr = wx.getSystemInfoSync().pixelRatio;           canvas.width = width * dpr;           canvas.height = height * dpr;           ctx.scale(dpr, dpr);            // 開(kāi)始繪圖           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 的寬度, 高度按一定規(guī)則平分       const startX = width / (data.length * 2), // 起始點(diǎn)的橫坐標(biāo) X         baseY = height * 0.9, // 基線縱坐標(biāo) Y         diffX = width / data.length,         diffY = (height * 0.7) / (Max - Min); // 高度預(yù)留 0.2 寫(xiě)溫度        ctx.beginPath();       ctx.textAlign = 'center';       ctx.font = '13px Microsoft YaHei';       ctx.lineWidth = 2;       ctx.strokeStyle = '#ABDCFF';        // 畫(huà)折線圖的線       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();        // 畫(huà)折線圖背景       ctx.lineTo(startX + (data.length - 1) * diffX, baseY); // 基線終點(diǎn)       ctx.lineTo(startX, baseY); // 基線起點(diǎn)       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();        // 畫(huà)折線圖上的小圓點(diǎn)       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 就是溫度數(shù)組,如 [1, 2, …]

因?yàn)椴恢罍囟葦?shù)值有多少個(gè),因此這里的 width 動(dòng)態(tài)傳入

有個(gè)小問(wèn)題,就是寬度過(guò)大的話真機(jī)不會(huì)顯示…

 // 獲取 scroll-view 的總寬度  wx.createSelectorQuery()       .select('.hourly')       .boundingClientRect(rect => {         this.setData({           scrollWidth: rect.right - rect.left,         });       })       .exec();
<view class="title">小時(shí)概述</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>

這里寫(xiě) scroll-x 和 scroll-y,要不會(huì)出現(xiàn)絕對(duì)定位偏移的問(wèn)題,也不知道為什么

手把手教你在微信小程序中使用canvas繪制天氣折線圖(附代碼)

.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 { // 折線圖絕對(duì)定位到底部   position: absolute;   bottom: 0; }

這里使用絕對(duì)定位其實(shí)是想模擬墨跡天氣這種折線圖和每一天在一個(gè)塊內(nèi)的效果,所以 hourly 要和 scroll-view 等高,canvas 需要定位一下

主要是不知道墨跡天氣怎么實(shí)現(xiàn)的,只能暫時(shí)這樣

手把手教你在微信小程序中使用canvas繪制天氣折線圖(附代碼)

三階貝塞爾曲線

效果圖

手把手教你在微信小程序中使用canvas繪制天氣折線圖(附代碼)

emmm,好像并不怎么圓滑

計(jì)算控制點(diǎn)

首先寫(xiě)一個(gè)點(diǎn)類(lèi)

class Point {   constructor(x, y) {     this.x = x;     this.y = y;   } }

Canvas貝塞爾曲線繪制工具 (karlew.com)

http://wx.karlew.com/canvas/bezier/

通過(guò)上面這個(gè)網(wǎng)站可以知道三階貝塞爾曲線各個(gè)參數(shù)的意義

手把手教你在微信小程序中使用canvas繪制天氣折線圖(附代碼)

也就是使用 bezierCurveTo 的時(shí)候最后一個(gè)點(diǎn)是下一個(gè)點(diǎn),前兩個(gè)是控制點(diǎn)

控制點(diǎn)的計(jì)算參考: 貝塞爾曲線控制點(diǎn)確定的方法 – 百度文庫(kù)

https://wenku.baidu.com/view/c790f8d46bec0975f565e211.html

濃縮一下就是

手把手教你在微信小程序中使用canvas繪制天氣折線圖(附代碼)

這里的 a 和 b 可以是任意正數(shù)

因此定義一個(gè)計(jì)算某點(diǎn)的控制點(diǎn) A 和 B 的方法

/**  * 計(jì)算當(dāng)前點(diǎn)的貝塞爾曲線控制點(diǎn)  * @param {Point} previousPoint: 前一個(gè)點(diǎn)  * @param {Point} currentPoint: 當(dāng)前點(diǎn)  * @param {Point} nextPoint1: 下一個(gè)點(diǎn)  * @param {Point} nextPoint2: 下下個(gè)點(diǎn)  * @param {Number} scale: 系數(shù)  */ 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); // 控制點(diǎn) A    x = nextPoint1.x - scale * (nextPoint2.x - currentPoint.x);   y = nextPoint1.y - scale * (nextPoint2.y - currentPoint.y);    const controlPointB = new Point(x, y); // 控制點(diǎn) B    return { controlPointA, controlPointB }; }

這里 scale 就是 a 和 b,不過(guò)將它們的取值相等

但是第一個(gè)點(diǎn)沒(méi)有 previousPoint,倒數(shù)第二個(gè)點(diǎn)沒(méi)有 nextPoint2

因此當(dāng)點(diǎn)是第一個(gè)的時(shí)候,使用 currentPoint 代替 previousPoint

當(dāng)?shù)箶?shù)第二個(gè)點(diǎn)的時(shí)候,使用 nextPoint1 代替 nextPoint2

手把手教你在微信小程序中使用canvas繪制天氣折線圖(附代碼)

至于最后一個(gè)點(diǎn),不需要做任何事,因?yàn)?bezierCurveTo 第三個(gè)參數(shù)就是下一個(gè)點(diǎn),只需要提供坐標(biāo)就能連起來(lái),不需要計(jì)算控制點(diǎn)

因此繪制三階貝塞爾曲線的方法:

/**  * 繪制貝塞爾曲線  * ctx.bezierCurveTo(控制點(diǎn)1, 控制點(diǎn)2, 當(dāng)前點(diǎn));  */ drawBezierLine(ctx, data, options) {   const { startX, diffX, baseY, diffY, Min } = options;    ctx.beginPath();   // 先移動(dòng)到第一個(gè)點(diǎn)   ctx.moveTo(startX, baseY - (data[0] - Min) * diffY);    data.forEach((e, i) => {     let curPoint, prePoint, nextPoint1, nextPoint2, x, y;      // 當(dāng)前點(diǎn)     x = startX + diffX * i;     y = baseY - (e - Min) * diffY;     curPoint = new Point(x, y);      // 前一個(gè)點(diǎn)     x = startX + diffX * (i - 1);     y = baseY - (data[i - 1] - Min) * diffY;     prePoint = new Point(x, y);      // 下一個(gè)點(diǎn)     x = startX + diffX * (i + 1);     y = baseY - (data[i + 1] - Min) * diffY;     nextPoint1 = new Point(x, y);      // 下下個(gè)點(diǎn)     x = startX + diffX * (i + 2);     y = baseY - (data[i + 2] - Min) * diffY;     nextPoint2 = new Point(x, y);      if (i === 0) {       // 如果是第一個(gè)點(diǎn), 則前一個(gè)點(diǎn)用當(dāng)前點(diǎn)代替       prePoint = curPoint;     } else if (i === data.length - 2) {       // 如果是倒數(shù)第二個(gè)點(diǎn), 則下下個(gè)點(diǎn)用下一個(gè)點(diǎn)代替       nextPoint2 = nextPoint1;     } else if (i === data.length - 1) {       // 最后一個(gè)點(diǎn)直接退出       return;     }      const { controlPointA, controlPointB } = this.calcBezierControlPoints(       prePoint,       curPoint,       nextPoint1,       nextPoint2     );      ctx.bezierCurveTo(       controlPointA.x,       controlPointA.y,       controlPointB.x,       controlPointB.y,       nextPoint1.x,       nextPoint1.y     );   });    ctx.stroke(); },

【相關(guān)學(xué)習(xí)推薦:小程序開(kāi)發(fā)教程】

贊(0)
分享到: 更多 (0)
?
網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)
林静公交车被做到高C的原因| 欧美 亚洲 日本 成人| 老太太 GRANNY| 欧美成人精品 一区二区三区| 亲孑伦视频一区二区三区视频| 色狠狠久久AV五月综合| 无忧传媒剧国产剧情MV| 亚洲乱码日产精品BD在线看| 中文字幕无码精品三级在线电影| JAPANESE护士高潮SEX| 丰满少妇A级毛片野外| 国产欧美久久久精品影院| 久久精品99国产精品蜜桃| 哦┅┅快┅┅用力啊┅┅在线观看 | 无码少妇一区二区三区| 亚洲国产精品一区二区成人片国内| 在线亚洲97SE亚洲综合在线| 被蹂躏的她 电影| 国产美女被遭强高潮开双腿网站| 久久久久琪琪去精品色无码| 人妻丰满熟妇无码区免费| 无码人妻精品一区二区蜜桃天美| 亚洲手机看片AV| 拔萝卜视频免费播放在线观看| 国产麻豆剧果冻传媒星空视频| 久久久久久久久久国产精品免费| 欧洲美女与动交ZOZ0Z| 午夜亚洲乱码伦小说区69堂| 永久免费看啪啪的网站| 成年女人WWXX免费国产| 狠狠88综合久久久久综合网| 欧美多人片高潮野外做片黑人| 色欲色香天天天综合无码| 亚洲精品在看在线观看| 巴西女人与禽2O2O性论交| 国产小视频A在线观看| 农民人伦一区二区三区| 无码一区二区三区AV免费| 中国老太太X×××XHD| 国产成人精品人人2020视频| 久久水蜜桃网国产无线网欧美日韩| 日本老黄AAAAAAAAAAAA| 亚洲国产精品一区二区久久HS | 日本一线和三线的区别| 亚洲国产精品成人网址天堂| WWW久久无码天堂MV| 好男人资源在线观看好| 人妻跪趴高撅肥臀| 亚洲乱亚洲乱少妇无码| 成人A级毛片免费播放| 极品少妇被黑人白浆直流| 人人妻人人澡人人爽人人蜜臀| 亚洲国产精品无码久久九九大片| 宝宝都湿透了还嘴硬疼怎么回事| 精品JAVAPARSER乱偷| 日韩精品无码中文字幕一区二区| 亚洲性夜夜综合久久7777| 公交车被多男摁住灌浓精| 久久久久久久久久精品电影| 我趁老师睡觉偷偷的脱她内裤| 中文字幕无码日韩专区免费| 国产午夜成人无码免费| 人妻 偷拍 无码 中文字幕| 亚洲精品无码久久久久秋霞| 绯色AV永久无码一区二区蜜臀| 亂倫近親相姦中文字幕| 亚洲AV福利天堂一区二区三| 白丝JK高潮喷水在线观看| 久久久久久A亚洲欧洲AV冫| 天天躁夜夜躁狠狠是什么心态| 88国产精品视频一区二区三区| 狠狠躁夜夜躁人人躁婷婷 | 国产精品视频色拍拍| 欧美亚洲国产成人一区二区三区| 亚洲人成电影一区二区在线| 国产福利精品一区二区| 欧美熟妇黑人ⅩXXXXX| 亚洲午夜福利在线观看| 国产情侣疯狂作爱系列| 日日碰狠狠添天天爽超碰97| 77777欧美毛片777777| 久久99精品久久久久久野外| 午夜成人无码福利免费视频| 成人国产精品一区二区免费看 | 1000部啪啪未满十八勿入| 精品国产国语对白久久免费 | 国产精品亚洲一区二区三区| 日本三线和韩国三线的市场定位 | 亚洲成AV人在线视| 国产成人一区二区精品视频| 强壮公弄得我次次高潮小说| 制服 丝袜 亚洲 中文 综合| 精品久久久久久亚洲中文字幕| 污污免费看锕锕锕锕锕锕| 成年免费视频黄网站ZXGK| 女人18毛片A级毛片| 一区二区三区国产亚洲网站| 精产国品一二三产品区别视频| 无码纯肉视频在线观看| 儿子耕了母亲荒废的田| 日本丰满人妻熟妇BBBBB③B| 99精品国产综合久久久久五月天| 浪货两个都满足不了你| 亚洲熟妇AV一区二区三区下载| 狠狠噜天天噜日日噜AV| 亚州日本乱码一区二区三区| 国产成人福利在线视频播放下载| 日本少妇自慰高清喷浆| 凹凸在线无码免费视频| 欧美性爱小说网站| HD极品FREE性XXⅩ护士I| 女人扒下裤让男人桶到爽| 中文弹幕日产无线码一区| 久久亚洲AⅤ精品网站| 亚洲一线产区二线产区区别在| 极品丰满熟妇人妻无码| 亚洲AV喷水无码XXX| 国产男男猛烈无遮挡A片小说| 婷婷成人丁香五月综合激情| 国产GAYSEXCHINA男同| 四川绿帽人妻51分钟在线| 国产★蜜臀AV无码| 四虎精品成人免费视频| 国产SP调教打屁股视频网站| 少妇被又大又粗又爽毛片| 国产69精品久久久久久人妻精品| 少妇无码太爽了在线播放| 国产99网站免在线观看| 玩弄放荡人妻一区二区三| 国产精品久久久久久久久鸭无码| 无码AⅤ最新AV无码专区| 国产精品成人亚洲777| 人妻av中年熟妇无码系列| 色综合视频一区二区三区44| 曰批免费视频播放免费直播| 久久亚洲AV成人无码国产电影| 亚洲制服无码一区二区三区| 久久久精品人妻久久影视| 亚洲综合无码精品一区二区三区| 久久久久亚洲精品天堂| 伊人久久大香线蕉AV仙人| 胯下硕大征服冰山女神| 再深点灬舒服灬太大了AV| 妺妺窝人体色7777777| CAOPORN最新地址| 日本伦奷在线播放| 国产SUV精品一区二区88L| 午夜精品久久久久久毛片| 韩国理论电费2023最| 亚洲精品成A人在线观看| 久久人人爽爽爽人久久久| 7777精品久久久大香线蕉| 人妻Av一区二区三区| 国产7色在线 | 国产| 亚洲AV乱码一区二区三区| 久久精品国产精品青草| 13小箩利洗澡无码视频网站| 日本大胆欧美人术艺术| 国产成人AV一区二区三区| 亚洲AV永久无码精品无码少妇 | 久久久久久久久精品无码中文字幕| 撞击到最深处她抽搐喷水| 人妻系列无码专区AV在线| 国产精品99无码一区二区| 亚洲国产天堂久久综合网| 久拍国产在线观看| 插插插精品亚洲一区| 无遮挡十八禁污污网站免费| 久久久精品妓女影院妓女网| JIZZJIZZ日本人妻| 污到你下面流水的小黄文| 精品无码国产自产拍在线观看蜜桃 | 少妇荡乳情欲办公室456视频| 韩漫网站在线看免费无删减漫画| 真人无码作爱免费视频网站 | 从厨房一路顶撞到卧室门好吗| 性啪啪CHINESE东北女人| 久久人人玩人妻潮喷内射人人| 暗交拗一区二区三区| 无套内谢的新婚少妇国语播放| 久久精品国产亚洲7777| らだ天堂√在线中文WWW| 小12箩利洗澡无码视频网站| 久久亚洲SM情趣捆绑调教| 成人免费A级毛片无码片在线播放| 亚洲AV嫩草AV极品在线观看| 男人的天堂在线视频| 国产精品久久久久9999小说| 一本一本久久A久久精品综合| 人人澡人人透人人爽| 极品少妇的粉嫩小泬看片| AV香港经典A毛片免费观看| 五十路丰满熟女av名单大全| 美女裸身裸乳免费视频的APP| 丰满熟妇人妻风流农村视频| 亚洲人成网77777色在线播放| 日本处ⅩⅩ人╳护士19| 近親五十路六十被亲子中出 | 美国ZOOM人与ZOOM视频| 丁香花在线观看免费观看图片 |