【移動應用開發(fā)技術】在微信小程序中如何使用canvas繪制天氣折線圖_第1頁
【移動應用開發(fā)技術】在微信小程序中如何使用canvas繪制天氣折線圖_第2頁
【移動應用開發(fā)技術】在微信小程序中如何使用canvas繪制天氣折線圖_第3頁
【移動應用開發(fā)技術】在微信小程序中如何使用canvas繪制天氣折線圖_第4頁
【移動應用開發(fā)技術】在微信小程序中如何使用canvas繪制天氣折線圖_第5頁
已閱讀5頁,還剩6頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

【移動應用開發(fā)技術】在微信小程序中如何使用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)聽

width

變化重繪

canvas

//

動態(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;

//

畫布寬度

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

的寬度,

高度按一定規(guī)則平分

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動態(tài)傳入有個小問題,就是寬度過大的話真機不會顯示...

//

獲取

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. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論