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

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

手把手教你在微信小程序中使用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號
AV人摸人人人澡人人超碰手机版| YY111111人妻影院| 性姿势108式大全图解| 国产人成视频在线观看| 成人乱码一区二区三区四区 | 国产精品自产拍高潮在线观看 | 秋霞网一区二区三区| 久久国产精品无码HDAV| 国产日韩精品欧美一区喷水| 精品人妻久久久久久888| 人妻熟妇久久久久久精品无码专区 | 水蜜桃国产成人精品网站| 亚洲变态另类调教久久久| 丁香婷婷激情俺也去俺来也| 少妇被三个黑人调教| 亚洲国产成人无码AV在线播放| 国产成人精品亚洲一区| 国外精品视频在线观看免费| 丰满岳跪趴高撅肥臀| 办公室撕开奶罩揉吮奶漫画| JLZZJLZZ全部女高潮| JIZZ在线观看中国少妇| 国产AV无码专区亚洲精品| 高清国产亚洲精品自在久久| 国产AⅤ无码专区亚洲AV琪琪| 国产亚洲精品A在线观看APP| 国内精品国产成人国产三级| 国内精品视频一区二区三区八戒| 久久无码高潮喷水免费看| 久久午夜私人影院| 麻豆一区二区在我观看| 老头的大龟挺进秀婷小说| 理论片午午伦夜理片影院| 日韩中文人妻无码不卡| 色狠狠久久AV北条麻妃| 色综合伊人色综合网站| 亚洲欧美日韩综合久久久| 亚洲中文字幕一区精品自拍| 一面膜上边一面膜下边日本| 亚洲中文字幕无码一久久区| 差差漫画页面免费漫画欢迎你| YOUJIZZCOM中国熟妇| 国产午夜精品一区二区三区极品| 免费A级毛片无码视频| 欧美性巨大╳╳╳╳╳高跟鞋| 日本免费人成视频播放试看| 少妇一级无码精品| 午夜免费无码福利视频网址| 亚洲精品卡2卡3卡4卡5卡区 | 国产成人剧情AV麻豆果冻| 国产成人愉拍免费视频| 国内精品伊人久久久久影院对白 | 锕锕锕锕锕锕锕好痛免费网址| 成 人 综合 亚洲另类| 精品无码国产污污污免费网站| 久久精品久久精品中文字幕| 免费无码成人AV片在线| 人妻精品无码一区二区三区| 亚洲国产一区二区三区亚瑟| 又湿又紧又大又爽A视频| CAOPORN国产精品免费视频| А√中文在线资源库| 精品国精品国产自在久国产不卡| 麻豆蜜桃AV蜜臀AV色欲AV| 欧美午夜性春猛交ⅩXXX| 亚洲国产精品美女久久久久| 房东老头揉捏吃我奶头影片| 国产又大又硬又粗| 久拍国产在线观看| 人人添人人妻人人爽频| 性饥渴XXXXXⅩHD| 又湿又黄裸乳漫画无遮挡网站| 国产精品无码一区二区三区在| 久久精品中文字幕无码绿巨人| 玩弄丰满少妇XXXXX| 亚洲午夜福利精品久久| WW久久综合久中文字幕| 久久精品国产99国产精品导航| 秋霞在线观看视频| 野花香电视剧全集免费观看高清 | 国外免费IPHONE网站| 少妇BBW搡BBBB搡| JAPANESE厨房乱TUB偷| 国产精品亚洲VA在线| 清区二三区国产好的精华液| 影音先锋AV天堂| 公车上拨开丁字裤进入电影| 欧美丰满熟妇BBB久久久| 无码专区 丝袜美腿 制服师生 | 麻豆国产蜜桃臀视频在线观看 | 天美传媒MV高清版在线观看| 亚洲乱码无码永久不卡在线| A阿V天堂亚洲阿∨天堂在线| 久久久久久久波多野结衣高潮| 日本人妻丰满大屁股a v| 18禁黄网站禁片免费观看在线 | 麻豆果冻传媒2021精品传媒一| 亚洲成在人线AV中文字幕喷水| AV成人无码无在线观看| 乱精品一区字幕二区| 亚洲色精品88色婷婷七月丁香| 被三个男人绑着躁我好爽| 精品卡一卡二卡3卡高清乱码 | 国产一区二区三区水蜜桃| 无码超级大爆乳在线播放 | 亚洲AV专区无码观看精品天堂| 国产精品视频色拍拍| 特黄三级又爽又粗又大| 成人免费毛片内射美女APP| 欧美午夜理伦三级在线观看| FREE性欧美精品VIDEOS| 欧美人C交ZOOZOOXX| 亚洲国产精品无码久久电影| 国产亚洲AV寡妇| 亚洲 欧美 偷自乱 图片| 国产乱理伦片A级在线观看| 调教狠扇打肿私密跪撅屁股作文| 最新国产成人无码久久| 国偷自产视频一区二区久| 小说 亚洲 无码 精品| 国产青草视频在线观看| 无码专区AAAAAA免费视频| 国产乱码卡二卡三卡43| 新JAPANESEVIDEO乱| 国产一二三四2021精字窝| 亚洲AⅤ中文无码字幕色本草| 成年免费A级毛片| 日本一二三四高清观看视频| 正在播放国产剧情亂倫| 国产亚洲日韩网曝欧美台湾| 性姿势108式大全图解| 交换玩弄两个美妇教师韩国电影| 深入浅出糙汉X软妹V1V| 国产23在线 | 传媒麻豆| 欧美一区在线视频| 再深点灬舒服灬太大了添视频软件| 国产午夜精品一区二区三区| 午夜三级手机在线电影| 国产在线无码视频一区二区三区| 亚洲AV之男人的天堂| 久久不见久久见免费视频3| 一区二区av在线| 欧美丰满多毛少妇XXXXX性| 野花高清中文免费观看视频| 老熟妇午夜毛片一区二区三区| 2023年新番肉食系| 久久99青青精品免费观看| 一个吃我奶头两个舔我下面| 女儿国在线观看免费版高清 | 亚洲 欧美 叧类人妖| 精品久久久久久中文字幕| 伊人久久大香线蕉成人| 欧美激情一区二区三区蜜桃| 边做饭边被躁BD在线播放| 天天爱天天做天天做天天吃中文| 超高清欧美VIDEOSSEXO| 熟妇人妻中文字幕| 狠狠五月激情六月丁香| 亚洲AV成人精品午夜一区二区| 精品第一国产综合精品AⅤ| 影音先锋中文字幕人妻| 人妻妺妺窝人体色WWW聚色窝| 国产精华最好的产品有哪些| 亚洲精品卡一卡2卡3卡4卡| 免费人妻无码不卡中文字幕18禁| 波多野结衣好大好紧好爽| 午夜影视免费观看2023| 久久久99精品成人片中文字幕| AE射频电源成色| 未满十八岁可以去日本留学吗 | 人妻蜜と1~4中文字幕月野定规 | 日本丰满熟妇BBxBB| 国产美女被遭高潮免费网站| 无码人妻精品中文字幕| 国产成人无码AV在线播放无广告| 亚洲AV综合色区无码专区蜜桃 | 69无人区卡一卡二卡| 妺妺窝人体色聚窝窝www偷窥 | 亚洲AV喷水无码XXX| 国精产品一区二区三区有限| 又大又硬又粗再深一点视频| 日韩AV片无码一区二区不卡电影| 成人性生交大片免费看中文| 色噜噜狠狠色综合成人网| 黄网站色视频免费观看| 亚洲欧美日韩国产手机在线| 欧美性猛交XXXXXⅩXX| 国产丝袜无码一区二区三区视频| 性色AV一区二区三区咪爱四虎| 里番本子侵犯肉全彩无码| 粉嫩av一区二区三区四区| 亚洲精品成人AV| 强制高潮18XXXXHD日韩| 出租房里的交互高康张睿| 色欲人妻综合AAAAAAAA网| 国产黄在线观看免费观看不卡| 亚洲中文字幕乱码电影| 少妇 精69XXXXXx白浆| 老熟妇毛茸茸BBW视频| 国产精品-区区久久久狼|