🚀一、Canvas
Canvas元件是一種圖形渲染元件,它提供了一個畫布(canvas),開發者可以在上面繪製各種圖形、文字等。Canvas元件通常用於建立遊戲、資料視覺化等需要動態繪製圖形的應用程式。
Canvas元件提供了多個API,開發者可以使用這些API進行繪製操作。常用的API包括繪製矩形、圓形、線條、文字等。開發者可以設定畫布的大小、背景色、繪製的顏色、線條的寬度等屬性。
在Canvas元件中,開發者可以監聽滑鼠事件(如點選、移動等)和鍵盤事件,以便根據使用者的互動來實現相應的操作。
Canvas元件的使用通常需要一定的程式設計知識和技巧,開發者需要了解如何使用API進行繪圖操作,以及如何處理使用者的互動事件。
🔎1.使用畫布元件繪製自定義圖形
🦋1.1 直接繪製
Canvas直接繪製圖形的原理是透過Canvas API呼叫一系列繪製方法來在Canvas元素上繪製圖形和影像。Canvas元素本身是一個空的矩形區域,透過獲取Canvas的上下文(context),可以使用上下文提供的繪製方法來進行繪製。
@Entry
@Component
struct CanvasExample1 {
//用來配置CanvasRenderingContext2D物件的引數,包括是否開啟抗鋸齒,true表明開啟抗鋸齒。
private settings: RenderingContextSettings = new RenderingContextSettings(true)
//用來建立CanvasRenderingContext2D物件,透過在canvas中呼叫CanvasRenderingContext2D物件來繪製。
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
//在canvas中呼叫CanvasRenderingContext2D物件。
Canvas(this.context)
.width('100%')
.height('100%')
.backgroundColor('#F5DC62')
.onReady(() => {
//可以在這裡繪製內容。
this.context.strokeRect(50, 50, 200, 150);
})
}
.width('100%')
.height('100%')
}
}
🦋1.2 離屏繪製
離屏繪製(offscreen rendering)是指將渲染結果繪製到與螢幕不直接相關的緩衝區中進行處理。傳統的渲染方式是直接將影像渲染到螢幕上,而離屏繪製則是在一個特定的緩衝區中進行渲染,然後再將渲染結果顯示到螢幕上。
離屏繪製的主要作用是實現一些特殊效果,比如陰影、模糊、遮罩等。這些效果通常需要在渲染過程中進行多次操作,直接在螢幕上渲染會導致效率低下。使用離屏繪製可以在一個獨立的緩衝區中進行這些操作,然後再將結果繪製到螢幕上。
離屏繪製可以透過一些圖形庫或引擎來實現,例如OpenGL、DirectX等。在移動裝置上,離屏繪製通常使用Frame Buffer來實現。開發者可以透過指定一個離屏渲染的目標緩衝區,然後在這個緩衝區中進行渲染操作,最後再將結果繪製到螢幕上。
離屏繪製雖然可以實現一些特殊效果,但由於需要額外的資源和計算開銷,使用不當會導致效能問題。因此,在使用離屏繪製時應該注意減少不必要的操作和資源消耗,以提高效能和使用者體驗。
@Entry
@Component
struct CanvasExample2 {
//用來配置CanvasRenderingContext2D物件和OffscreenCanvasRenderingContext2D物件的引數,包括是否開啟抗鋸齒。true表明開啟抗鋸齒
private settings: RenderingContextSettings = new RenderingContextSettings(true)
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
//用來建立OffscreenCanvasRenderingContext2D物件,width為離屏畫布的寬度,height為離屏畫布的高度。透過在canvas中呼叫OffscreenCanvasRenderingContext2D物件來繪製。
private offContext: OffscreenCanvasRenderingContext2D = new OffscreenCanvasRenderingContext2D(600, 600, this.settings)
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Canvas(this.context)
.width('100%')
.height('100%')
.backgroundColor('#F5DC62')
.onReady(() =>{
//可以在這裡繪製內容
this.offContext.strokeRect(50, 50, 200, 150);
//將離屏繪值渲染的影像在普通畫布上顯示
let image = this.offContext.transferToImageBitmap();
this.context.transferFromImageBitmap(image);
})
}
.width('100%')
.height('100%')
}
}
在Canvas上載入Lottie動畫時,需要先按照如下方式下載Lottie,具體使用:https://ohpm.openharmony.cn/#/cn/detail/@ohos/lottie
🔎2.初始化畫布元件
在HarmonyOS中,Canvas類是用於繪製圖形的核心類。Canvas類提供了onReady方法,用於在Canvas準備好進行繪製之後的回撥操作。
當Canvas準備好進行繪製時,會呼叫onReady方法。開發者可以重寫onReady方法,實現一些繪製前的準備工作,例如設定畫筆顏色、繪製區域等。
要使用Canvas的onReady方法,需要建立一個Canvas例項,然後透過例項呼叫onReady方法。
@Entry
@Component
struct CanvasExample2 {
//用來配置CanvasRenderingContext2D物件和OffscreenCanvasRenderingContext2D物件的引數,包括是否開啟抗鋸齒。true表明開啟抗鋸齒
private settings: RenderingContextSettings = new RenderingContextSettings(true)
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
//用來建立OffscreenCanvasRenderingContext2D物件,width為離屏畫布的寬度,height為離屏畫布的高度。透過在canvas中呼叫OffscreenCanvasRenderingContext2D物件來繪製。
private offContext: OffscreenCanvasRenderingContext2D = new OffscreenCanvasRenderingContext2D(600, 600, this.settings)
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Canvas(this.context)
.width('100%')
.height('100%')
.backgroundColor('#F5DC62')
.onReady(() => {
this.context.fillStyle = '#0097D4';
this.context.fillRect(50, 50, 100, 100);
})
}
.width('100%')
.height('100%')
}
}
🔎3.畫布元件繪製方式
Canvas類支援使用Path2D物件來繪製複雜的路徑圖形。
Path2D是一個可重用的路徑物件,用於描述二維空間中的路徑。開發者可以使用Path2D物件來定義路徑的輪廓,並在Canvas上繪製出來。
@Entry
@Component
struct CanvasExample2 {
//用來配置CanvasRenderingContext2D物件和OffscreenCanvasRenderingContext2D物件的引數,包括是否開啟抗鋸齒。true表明開啟抗鋸齒
private settings: RenderingContextSettings = new RenderingContextSettings(true)
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
//用來建立OffscreenCanvasRenderingContext2D物件,width為離屏畫布的寬度,height為離屏畫布的高度。透過在canvas中呼叫OffscreenCanvasRenderingContext2D物件來繪製。
private offContext: OffscreenCanvasRenderingContext2D = new OffscreenCanvasRenderingContext2D(600, 600, this.settings)
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Canvas(this.context)
.width('100%')
.height('100%')
.backgroundColor('#F5DC62')
.onReady(() =>{
this.context.beginPath();
this.context.moveTo(50, 50);
this.context.lineTo(280, 160);
this.context.stroke();
})
Canvas(this.context)
.width('100%')
.height('100%')
.backgroundColor('#F5DC62')
.onReady(() =>{
let region = new Path2D();
region.arc(100, 75, 50, 0, 6.28);
this.context.stroke(region);
})
}
.width('100%')
.height('100%')
}
}
🔎4.畫布元件常用方法
🦋4.1 基礎形狀繪製
可以透過arc(繪製弧線路徑)、 ellipse(繪製一個橢圓)、rect(建立矩形路徑)等介面繪製基礎形狀
@Entry
@Component
struct CanvasExample2 {
//用來配置CanvasRenderingContext2D物件和OffscreenCanvasRenderingContext2D物件的引數,包括是否開啟抗鋸齒。true表明開啟抗鋸齒
private settings: RenderingContextSettings = new RenderingContextSettings(true)
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
//用來建立OffscreenCanvasRenderingContext2D物件,width為離屏畫布的寬度,height為離屏畫布的高度。透過在canvas中呼叫OffscreenCanvasRenderingContext2D物件來繪製。
private offContext: OffscreenCanvasRenderingContext2D = new OffscreenCanvasRenderingContext2D(600, 600, this.settings)
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Canvas(this.context)
.width('100%')
.height('100%')
.backgroundColor('#F5DC62')
.onReady(() =>{
//繪製矩形
this.context.beginPath();
this.context.rect(100, 50, 100, 100);
this.context.stroke();
//繪製圓形
this.context.beginPath();
this.context.arc(150, 250, 50, 0, 6.28);
this.context.stroke();
//繪製橢圓
this.context.beginPath();
this.context.ellipse(150, 450, 50, 100, Math.PI * 0.25, Math.PI * 0, Math.PI * 2);
this.context.stroke();
})
}
.width('100%')
.height('100%')
}
}
🦋4.2 文字繪製
可以透過fillText(繪製填充類文字)、strokeText(繪製描邊類文字)等介面進行文字繪製。
@Entry
@Component
struct CanvasExample2 {
//用來配置CanvasRenderingContext2D物件和OffscreenCanvasRenderingContext2D物件的引數,包括是否開啟抗鋸齒。true表明開啟抗鋸齒
private settings: RenderingContextSettings = new RenderingContextSettings(true)
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
//用來建立OffscreenCanvasRenderingContext2D物件,width為離屏畫布的寬度,height為離屏畫布的高度。透過在canvas中呼叫OffscreenCanvasRenderingContext2D物件來繪製。
private offContext: OffscreenCanvasRenderingContext2D = new OffscreenCanvasRenderingContext2D(600, 600, this.settings)
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Canvas(this.context)
.width('100%')
.height('100%')
.backgroundColor('#F5DC62')
.onReady(() =>{
//繪製填充類文字
this.context.font = '50px sans-serif';
this.context.fillText("Hello World!", 50, 100);
//繪製描邊類文字
this.context.font = '55px sans-serif';
this.context.strokeText("Hello World!", 50, 150);
})
}
.width('100%')
.height('100%')
}
}
🦋4.3 繪製圖片和影像畫素資訊處理
@Entry
@Component
struct GetImageData {
private settings: RenderingContextSettings = new RenderingContextSettings(true)
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
private offContext: OffscreenCanvasRenderingContext2D = new OffscreenCanvasRenderingContext2D(600, 600, this.settings)
private img:ImageBitmap = new ImageBitmap("1702344909275.jpg")
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Canvas(this.context)
.width('100%')
.height('100%')
.backgroundColor('#F5DC62')
.onReady(() =>{
// 使用drawImage介面將圖片畫在(0,0)為起點,寬高130的區域
this.offContext.drawImage(this.img,0,0,130,130);
// 使用getImageData介面,獲得canvas元件區域中,(50,50)為起點,寬高130範圍內的繪製內容
let imagedata = this.offContext.getImageData(50,50,130,130);
// 使用putImageData介面將得到的ImageData畫在起點為(150, 150)的區域中
this.offContext.putImageData(imagedata,150,150);
// 將離屏繪製的內容畫到canvas元件上
let image = this.offContext.transferToImageBitmap();
this.context.transferFromImageBitmap(image);
})
}
.width('100%')
.height('100%')
}
}
🦋4.4 其他方法
Canvas中還提供其他型別的方法。漸變(CanvasGradient物件)相關的方法:createLinearGradient(建立一個線性漸變色)、createRadialGradient(建立一個徑向漸變色)等。
Canvas的createRadialGradient方法用於建立一個徑向漸變色。
語法:
createRadialGradient(x0, y0, r0, x1, y1, r1)
引數說明:
- x0:漸變的起始圓的x座標
- y0:漸變的起始圓的y座標
- r0:漸變的起始圓的半徑
- x1:漸變的結束圓的x座標
- y1:漸變的結束圓的y座標
- r1:漸變的結束圓的半徑
@Entry
@Component
struct GetImageData {
private settings: RenderingContextSettings = new RenderingContextSettings(true)
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
private offContext: OffscreenCanvasRenderingContext2D = new OffscreenCanvasRenderingContext2D(600, 600, this.settings)
private img:ImageBitmap = new ImageBitmap("1702344909275.jpg")
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Canvas(this.context)
.width('100%')
.height('100%')
.backgroundColor('#F5DC62')
.onReady(() =>{
//建立一個徑向漸變色的CanvasGradient物件
let grad = this.context.createRadialGradient(200,200,50, 200,200,200)
//為CanvasGradient物件設定漸變斷點值,包括偏移和顏色
grad.addColorStop(0.0, '#E87361');
grad.addColorStop(0.5, '#FFFFF0');
grad.addColorStop(1.0, '#BDDB69');
//用CanvasGradient物件填充矩形
this.context.fillStyle = grad;
this.context.fillRect(0, 0, 400, 400);
})
}
.width('100%')
.height('100%')
}
}
🔎5.場景示例
🦋5.1 規則基礎形狀繪製
@Entry
@Component
struct ClearRect {
private settings: RenderingContextSettings = new RenderingContextSettings(true);
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Canvas(this.context)
.width('100%')
.height('100%')
.backgroundColor('#F5DC62')
.onReady(() =>{
// 設定填充樣式,填充顏色設為藍色
this.context.fillStyle = '#0097D4';
// 以(50, 50)為左上頂點,畫一個寬高200的矩形
this.context.fillRect(50,50,200,200);
// 以(70, 70)為左上頂點,清除寬150高100的區域
this.context.clearRect(70,70,150,100);
})
}
.width('100%')
.height('100%')
}
}
🦋5.2 不規則圖形繪製
@Entry
@Component
struct Path2d {
private settings: RenderingContextSettings = new RenderingContextSettings(true);
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
build() {
Row() {
Column() {
Canvas(this.context)
.width('100%')
.height('100%')
.backgroundColor('#F5DC62')
.onReady(() =>{
// 使用Path2D的介面構造一個五邊形
let path = new Path2D();
path.moveTo(150, 50);
path.lineTo(50, 150);
path.lineTo(100, 250);
path.lineTo(200, 250);
path.lineTo(250, 150);
path.closePath();
// 設定填充色為藍色
this.context.fillStyle = '#0097D4';
// 使用填充的方式,將Path2D描述的五邊形繪製在canvas元件內部
this.context.fill(path);
})
}
.width('100%')
}
.height('100%')
}
}
🚀寫在最後
- 如果你覺得這篇內容對你還蠻有幫助,我想邀請你幫我三個小忙:
- 點贊,轉發,有你們的 『點贊和評論』,才是我創造的動力。
- 關注小編,同時可以期待後續文章ing🚀,不定期分享原創知識。
- 更多鴻蒙最新技術知識點,請關注作者部落格:https://t.doruo.cn/14DjR1rEY