手把手教你在微信小程式中使用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, ...]
// 获取 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 {
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 需要定位一下
#主要是不知道墨跡天氣怎麼實現的,只能暫時這樣.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; }
三階貝塞爾曲線
效果圖
emmm,好像不太圓滑計算控制點
先寫一個點類別
class Point { constructor(x, y) { this.x = x; this.y = y; } }
Canvas貝塞爾曲線繪製工具(karlew.com)
http://wx.karlew.com/canvas/bezier/
#透過上面這個網站可以知道三階貝塞爾曲線各個參數的意義
也就是使用bezierCurveTo 的時候最後一個點是下一個點,前兩個是控制點
控制點的計算參考: 貝塞爾曲線控制點確定的方法- 百度文庫
https://wenku.baidu.com/view/c790f8d46bec0975f565e211.html
#濃縮一下就是這裡的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,不過將它們的取值相等
/** * 绘制贝塞尔曲线 * 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(); },
以上是手把手教你在微信小程式中使用canvas繪製天氣折線圖(附代碼)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

閒魚官方微信小程式悄悄上線,在小程式中可以發布閒置與買家/賣家私訊交流、查看個人資料及訂單、搜尋物品等,有用好奇閒魚微信小程式叫什麼,現在快來看一下。閒魚微信小程式叫什麼答案:閒魚,閒置交易二手買賣估價回收。 1、在小程式中可以發布閒置、與買家/賣家私訊交流、查看個人資料及訂單、搜尋指定物品等功能;2、在小程式的頁面中有首頁、附近、發閒置、訊息、我的5項功能;3、想要使用的話必要要開通微信支付才可以購買;

微信小程式實現圖片上傳功能隨著行動網路的發展,微信小程式已經成為了人們生活中不可或缺的一部分。微信小程式不僅提供了豐富的應用場景,還支援開發者自訂功能,其中包括圖片上傳功能。本文將介紹如何在微信小程式中實作圖片上傳功能,並提供具體的程式碼範例。一、前期準備工作在開始編寫程式碼之前,我們需要先下載並安裝微信開發者工具,並註冊成為微信開發者。同時,也需要了解微信

實現微信小程式中的圖片濾鏡效果隨著社群媒體應用程式的流行,人們越來越喜歡在照片中應用濾鏡效果,以增強照片的藝術效果和吸引力。在微信小程式中也可以實現圖片濾鏡效果,為使用者提供更多有趣和創意的照片編輯功能。本文將介紹如何在微信小程式中實現圖片濾鏡效果,並提供具體的程式碼範例。首先,我們需要在微信小程式中使用canvas元件來載入和編輯圖片。 canvas元件可以在頁面

實現微信小程式中的下拉式選單效果,需要具體程式碼範例隨著行動互聯網的普及,微信小程式成為了網路開發的重要一環,越來越多的人開始關注和使用微信小程式。微信小程式的開發相比傳統的APP開發更加簡單快捷,但也需要掌握一定的開發技巧。在微信小程式的開發中,下拉式選單是一個常見的UI元件,實現了更好的使用者操作體驗。本文將詳細介紹如何在微信小程式中實現下拉式選單效果,並提供具

使用微信小程式實現輪播圖切換效果微信小程式是一種輕量級的應用程序,具有簡單、高效的開發和使用特點。在微信小程式中,實作輪播圖切換效果是常見的需求。本文將介紹如何使用微信小程式實現輪播圖切換效果,並給出具體的程式碼範例。首先,在微信小程式的頁面檔案中,新增一個輪播圖元件。例如,可以使用<swiper>標籤來實現輪播圖的切換效果。在該組件中,可以透過b

閒魚官方微信小程式已經悄悄上線,它為用戶提供了一個便捷的平台,讓你可以輕鬆地發布和交易閒置物品。在小程式中,你可以與買家或賣家進行私訊交流,查看個人資料和訂單,以及搜尋你想要的物品。那麼閒魚在微信小程式中究竟叫什麼呢,這篇教學攻略將為您詳細介紹,想要了解的用戶們快來跟著本文繼續閱讀吧!閒魚微信小程式叫什麼答案:閒魚,閒置交易二手買賣估價回收。 1、在小程式中可以發布閒置、與買家/賣家私訊交流、查看個人資料及訂單、搜尋指定物品等功能;2、在小程式的頁面中有首頁、附近、發閒置、訊息、我的5項功能;3、

實現微信小程式中的圖片旋轉效果,需要具體程式碼範例微信小程式是一種輕量級的應用程序,為用戶提供了豐富的功能和良好的用戶體驗。在小程式中,開發者可以利用各種元件和API來實現各種效果。其中,圖片旋轉效果是一種常見的動畫效果,可以為小程式增添趣味性和視覺效果。在微信小程式中實作圖片旋轉效果,需要使用小程式提供的動畫API。以下是一個具體的程式碼範例,展示如何在小程

實作微信小程式中的滑動刪除功能,需要具體程式碼範例隨著微信小程式的流行,開發者在開發過程中經常會遇到一些常見功能的實作問題。其中,滑動刪除功能是常見、常用的功能需求。本文將為大家詳細介紹如何在微信小程式中實現滑動刪除功能,並給出具體的程式碼範例。一、需求分析在微信小程式中,滑動刪除功能的實作涉及以下要點:列表展示:要顯示可滑動刪除的列表,每個列表項目需要包
