久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合

站長資訊網
最全最豐富的資訊網站

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

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

手把手教你在微信小程序中使用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,要不會出現絕對定位偏移的問題,也不知道為什么

手把手教你在微信小程序中使用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 { // 折線圖絕對定位到底部   position: absolute;   bottom: 0; }

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

主要是不知道墨跡天氣怎么實現的,只能暫時這樣

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

三階貝塞爾曲線

效果圖

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

emmm,好像并不怎么圓滑

計算控制點

首先寫一個點類

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

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

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

通過上面這個網站可以知道三階貝塞爾曲線各個參數的意義

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

也就是使用 bezierCurveTo 的時候最后一個點是下一個點,前兩個是控制點

控制點的計算參考: 貝塞爾曲線控制點確定的方法 – 百度文庫

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

濃縮一下就是

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

這里的 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

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

至于最后一個點,不需要做任何事,因為 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 = new Point(x, y);      if (i === 0) {       // 如果是第一個點, 則前一個點用當前點代替       prePoint = curPoint;     } else if (i === data.length - 2) {       // 如果是倒數第二個點, 則下下個點用下一個點代替       nextPoint2 = nextPoint1;     } else if (i === data.length - 1) {       // 最后一個點直接退出       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(); },

【相關學習推薦:小程序開發教程】

贊(0)
分享到: 更多 (0)
?
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合
日韩欧美一区二区三区在线视频| 一区福利视频| 日韩一区中文| 少妇精品在线| 日本午夜精品| 国产福利亚洲| 国产日韩一区| 精品国内亚洲2022精品成人| 国产精区一区二区| 久久亚洲国产精品尤物| 精品国产午夜肉伦伦影院| 国语精品一区| 欧美gv在线| 午夜欧美在线| 亚洲影院天堂中文av色| 91免费精品国偷自产在线在线| 日韩不卡一区二区三区| 国产精品视频一区视频二区| 久久影视三级福利片| 黄色在线网站噜噜噜| 三上亚洲一区二区| 日韩综合精品| 免费视频久久| 国产日本亚洲| 日本久久黄色| 欧美日韩国产精品一区二区亚洲| 国产亚洲精品v| 日韩精品免费视频人成| 嫩草伊人久久精品少妇av杨幂| 国产高潮在线| 午夜欧美精品久久久久久久| 日韩一区二区三区在线看| 国产精品一线| 精品亚洲美女网站| 亚洲三级网址| 精品中文在线| 激情欧美一区| 日韩国产欧美视频| 亚洲黄色中文字幕| 在线精品亚洲| 久久精品午夜| 尤物精品在线| 国产亚洲电影| 999久久久91| 日韩激情av在线| 日韩伦理福利| 亚洲视频二区| 国产一区2区在线观看| 欧洲毛片在线视频免费观看| 91亚洲精品在看在线观看高清| 欧美片第1页| 亚洲无线观看| 欧美sm一区| 国产一级成人av| 欧美91福利在线观看| 国产欧美日韩在线一区二区| 亚洲1234区| 日韩欧美三区| 99精品综合| 欧美影院精品| 欧美日韩国产在线观看网站| 国产日韩欧美三区| 欧美午夜不卡影院在线观看完整版免费| 欧美一区精品| 国产精品毛片在线| 欧美激情国产在线| 在线精品亚洲| 日韩在线免费| 久久国产生活片100| 亚洲成人一区| 精品视频一二| 日本91福利区| 免费精品视频| 午夜av成人| 欧美国产亚洲精品| 亚洲精品乱码| 99视频一区| 欧美日韩视频免费观看| 国产精品v一区二区三区| 免费日本视频一区| 久久精品成人| 麻豆极品一区二区三区| 丝袜美腿亚洲一区| 国内亚洲精品| 成人国产精品一区二区免费麻豆| 日韩精品免费视频一区二区三区 | 亚洲欧洲美洲av| 国产精品一区二区三区av麻| 人人爽香蕉精品| 国产字幕视频一区二区| 精品国产麻豆| 国产精品成人国产| 日韩成人午夜精品| 亚洲永久精品唐人导航网址| 韩国精品主播一区二区在线观看| 免费在线观看一区| 久久国产视频网| 日韩超碰人人爽人人做人人添| 日韩在线a电影| 尤物精品在线| 婷婷成人基地| 久久久精品久久久久久96| 国产成人精品一区二区三区免费| 亚洲天堂免费| 亚洲婷婷丁香| 午夜在线一区二区| 精品欧美久久| 国产真实久久| 国产专区一区| 久久一区二区三区电影| 日韩av福利| 捆绑调教日本一区二区三区| 欧美黑人做爰爽爽爽| 日本aⅴ免费视频一区二区三区| 蜜臀av在线播放一区二区三区| 国产综合婷婷| 亚洲v在线看| 99国产精品一区二区| 欧美久久天堂| 在线亚洲人成| 亚洲四虎影院| 欧美精品一区二区三区精品| 激情综合网站| 欧美中文日韩| 免费视频久久| 亚洲91在线| 日本精品国产| 国产精品17p| 红杏一区二区三区| 高清av不卡| 欧美aa国产视频| 国产精品呻吟| 亚洲精品大全| 欧美一级一区| 国产精品xxxav免费视频| 精品一区二区三区中文字幕| 日产精品一区二区| 国产麻豆久久| 美日韩精品视频| 中文字幕亚洲精品乱码| 欧美亚洲专区| 丁香婷婷久久| 国产中文一区| 亚洲日产国产精品| 国产精品网址| 日韩av一级| 蜜桃久久精品一区二区| 欧美亚洲一级| 国产精品蜜芽在线观看| 今天的高清视频免费播放成人| 久久成人精品| 国产精品入口久久| 中文字幕系列一区| 鲁大师成人一区二区三区| 亚洲精品日本| 麻豆国产精品一区二区三区| 国产精品毛片久久| 欧美在线网站| 日韩二区三区在线观看| 久久影院一区二区三区| 亚洲午夜一级| 日韩欧美三区| av综合电影网站| 亚洲天堂日韩在线| 精品九九久久| 久热精品在线| 麻豆精品视频在线观看| 激情丁香综合| 国产欧美69| 日韩欧美一区二区三区在线视频| 红桃视频欧美| 国产欧美日韩亚洲一区二区三区| 国产在线观看www| 乱人伦精品视频在线观看| 国产日韩在线观看视频| 日韩高清中文字幕一区二区| 免费日本视频一区| 国产成人精品三级高清久久91| 免费观看久久av| 91伊人久久| 在线成人动漫av| 国产情侣久久| 亚洲欧洲一区二区天堂久久| 国产精品第十页| 91精品91| 精品久久久网| 亚洲另类av| 日韩国产网站| 日本午夜精品久久久| 亚洲高清成人| 久久的色偷偷| 一区二区三区网站| 亚洲天堂1区| 麻豆国产精品| 亚洲97av| 九色精品91| 精品一区二区三区中文字幕视频 | 国产精品sm| 日韩午夜精品| 国产美女高潮在线|