一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何通過Canvas組件實(shí)現(xiàn)涂鴉功能

OpenAtom OpenHarmony ? 來源:OpenAtom OpenHarmony ? 作者:OpenAtom OpenHarmony ? 2022-09-20 16:31 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

ArkUI是一套UI開發(fā)框架,提供了開發(fā)者進(jìn)行應(yīng)用UI開發(fā)時所需具備的能力。隨著OpenAtom OpenHarmony(以下簡稱“OpenHarmony”)不斷更新迭代,ArkUI也提供了很多新的組件,例如Canvas、OffscreenCanvas、XComponent組件等。

新增的功能可以幫助開發(fā)者開發(fā)出更流暢、更美觀的應(yīng)用。本篇文章將為大家分享如何通過Canvas組件實(shí)現(xiàn)涂鴉功能,用戶可以選擇空白畫布或者簡筆圖進(jìn)行自由繪畫。

效果展示

以下為效果圖:19d4008c-3728-11ed-ba43-dac502259ad0.jpg19f85068-3728-11ed-ba43-dac502259ad0.jpg1a0b5852-3728-11ed-ba43-dac502259ad0.jpg ? 詳細(xì)效果請看下方視頻: 從視頻中可見,首頁顯示了涂鴉的圖片以及最后一張空白圖片,在點(diǎn)擊圖片進(jìn)入涂鴉頁面后,可以對畫筆的顏色、粗細(xì)進(jìn)行設(shè)置。如果涂鴉過程中有錯誤,可以用橡皮擦將畫面擦除,也可點(diǎn)擊清除按鈕,清空涂鴉的內(nèi)容,重新進(jìn)行涂鴉操作。 ? ?

相關(guān)代碼已經(jīng)上傳至SIG倉庫,鏈接如下:

https://gitee.com/openharmony-sig/knowledge_demo_entainment/tree/master/FA/FreeDraw

目錄結(jié)構(gòu)

1a1fbbe4-3728-11ed-ba43-dac502259ad0.jpg ?

源碼分析

一、Canvas組件介紹 本篇樣例主要利用ArkUI的Canvas組件實(shí)現(xiàn)涂鴉的功能,首先介紹一下Canvas組件。 Canvas組件主要包含了Canvas和CanvasRenderingContext2D,Canvas提供了畫布功能,CanvasRenderingContext2D提供了繪畫的屬性和方法。通過CanvasRenderingContext2D可以修改畫筆的樣色、粗細(xì)等屬性,從而畫出各式各樣的圖形。 以下是Canvas和CanvasRenderingContext2D在樣例開發(fā)中使用的相關(guān)接口信息。 1a322356-3728-11ed-ba43-dac502259ad0.png ? CanvasRenderingContext2D ?1a45ae94-3728-11ed-ba43-dac502259ad0.png ?二、分析源碼頁面布局 第一個模塊是首頁布局,首頁顯示所有涂鴉包含的圖片,點(diǎn)擊圖片可以進(jìn)入頁面;第二個模塊是涂鴉模塊,可以設(shè)置畫筆的顏色、邊條寬度等。 1. 首頁布局

		Column() { Text('選擇涂鴉的圖片:').margin('10vp').fontSize('30fp').fontColor(Color.Blue).height('5%') Grid() { ForEach(this.images, (item, index) => { GridItem() { Image(this.images[index]) .onClick((event) => { router.push( { url: "pages/detailPage", params: { imgSrc: this.images[index], }, } ) }) .width('100%') .height('100%') .objectFit(ImageFit.Contain) } }) } .padding({left: this.columnSpace, right: this.columnSpace}) .columnsTemplate("1fr 1fr 1fr") // Grid寬度均分成3份 .rowsTemplate("1fr 1fr") // Grid高度均分成2份 .rowsGap(this.rowSpace) // 設(shè)置行間距 .columnsGap(this.columnSpace) // 設(shè)置列間距 .width('100%') .height('95%') }.backgroundColor(Color.Pink)
		
		2. 涂鴉頁面 - 畫布Canvas的布局
		通過Stack組件進(jìn)行包裹,并將Canvas畫布覆蓋在選擇的背景圖片之上,這些背景圖片主要是水果簡筆畫。

		Stack() {  Image(this.imgSrc).width('100%').height('100%').objectFit(ImageFit.Contain)  Canvas(this.context) .width('100%') .height('100%')// .backgroundColor('#00ffff00') .onReady(() => { }) .onTouch((event) => { if (event.type === TouchType.Down) { this.eventType = 'Down'; this.drawing = true; [this.x, this.y] = [event.touches[0].x, event.touches[0].y]; this.context.beginPath(); this.context.lineCap = 'round'; if (this.isEraserMode) { //橡皮擦模式 this.context.clearRect(this.x, this.y, 20, 20); }  console.log('gyf Down'); } if (event.type === TouchType.Up) { this.eventType = 'Up'; this.drawing = false; console.log('gyf Up!'); this.context.closePath(); } if (event.type === TouchType.Move) { if (!this.drawing) return; this.eventType = 'Move'; console.log('gyf Move');  if (this.isEraserMode) { //橡皮擦模式 this.context.clearRect(event.touches[0].x, event.touches[0].y, 20, 20); } else { this.context.lineWidth = this.lineWidth; this.context.strokeStyle = this.color;  this.context.moveTo(this.x, this.y); this.x = event.touches[0].x; this.y = event.touches[0].y; this.context.lineTo(this.x, this.y); this.context.stroke(); } } }) }.width('100%').height('75%')
		
		3.涂鴉頁面 - 畫筆設(shè)置區(qū)域的布局

		Column() { Row() { Text('粗細(xì):')  Button('小').onClick(() => { //設(shè)置畫筆的寬度 this.lineWidth = 5; this.context.lineWidth = this.lineWidth; this.isEraserMode = false; console.log('gyf small button'); }).margin($r('app.float.wh_value_10'))  Button('中').onClick(() => { //設(shè)置畫筆的寬度 this.lineWidth = 15; this.context.lineWidth = this.lineWidth; this.isEraserMode = false; console.log('gyf middle button'); }).margin($r('app.float.wh_value_10'))  Button('大').onClick(() => { //設(shè)置畫筆的寬度 this.lineWidth = 25; this.context.lineWidth = this.lineWidth; this.isEraserMode = false; console.log('gyf big button'); }).margin($r('app.float.wh_value_10'))  Button('超大').onClick(() => { //設(shè)置畫筆的寬度 this.lineWidth = 40; this.context.lineWidth = this.lineWidth; this.isEraserMode = false; console.log('gyf super big button'); }) }.padding($r('app.float.wh_value_10')).margin($r('app.float.wh_value_5'))  //畫筆顏色 Scroll() { Row() { Text('顏色:')  Button(' ', { type: ButtonType.Circle }) .onClick(() => { //黑色 this.color = '#000000'; this.context.strokeStyle = this.color; this.isEraserMode = false; console.log('gyf black button'); }) .backgroundColor('#000000') .width('40vp') .width('40vp') .margin($r('app.float.wh_value_10'))  Button(' ', { type: ButtonType.Circle }) .onClick(() => { //紅色 this.color = '#FF0000'; this.context.strokeStyle = this.color; this.isEraserMode = false; console.log('gyf red button'); }) .backgroundColor('#FF0000') .width('40vp') .width('40vp') .margin($r('app.float.wh_value_10'))  Button(' ', { type: ButtonType.Circle }) .onClick(() => { //綠色 this.color = '#00FF00'; this.context.strokeStyle = this.color; this.isEraserMode = false; console.log('gyf green button'); }) .backgroundColor('#00FF00') .width('40vp') .width('40vp') .margin($r('app.float.wh_value_10'))  Button(' ', { type: ButtonType.Circle }) .onClick(() => { //藍(lán)色 this.color = '#0000FF'; this.context.strokeStyle = this.color; this.isEraserMode = false; }) .backgroundColor('#0000FF') .width('40vp') .width('40vp') .margin($r('app.float.wh_value_10'))  Button(' ', { type: ButtonType.Circle }) .onClick(() => { //棕色 this.color = '#A52A2A'; this.context.strokeStyle = this.color; this.isEraserMode = false; }) .backgroundColor('#A52A2A') .width('40vp') .width('40vp') .margin($r('app.float.wh_value_10'))  Button(' ', { type: ButtonType.Circle }) .onClick(() => { //紫色 this.color = '#800080'; this.context.strokeStyle = this.color; this.isEraserMode = false; }) .backgroundColor('#800080') .width('40vp') .width('40vp') .margin($r('app.float.wh_value_10'))  Button(' ', { type: ButtonType.Circle }) .onClick(() => { //紫紅色 this.color = '#FF00FF'; this.context.strokeStyle = this.color; this.isEraserMode = false; }) .backgroundColor('#FF00FF') .width('40vp') .width('40vp') .margin($r('app.float.wh_value_10'))  Button(' ', { type: ButtonType.Circle }) .onClick(() => { //深藍(lán)色 this.color = '#00008B'; this.context.strokeStyle = this.color; this.isEraserMode = false; }) .backgroundColor('#00008B') .width('40vp') .width('40vp') .margin($r('app.float.wh_value_10'))  Button(' ', { type: ButtonType.Circle }) .onClick(() => { //深天藍(lán) this.color = '#00BFFF'; this.context.strokeStyle = this.color; this.isEraserMode = false; }) .backgroundColor('#00BFFF') .width('40vp') .width('40vp') .margin($r('app.float.wh_value_10'))  Button(' ', { type: ButtonType.Circle }) .onClick(() => { //綠色 this.color = '#008000'; this.context.strokeStyle = this.color; this.isEraserMode = false; }) .backgroundColor('#008000') .width('40vp') .width('40vp') .margin($r('app.float.wh_value_10'))  Button(' ', { type: ButtonType.Circle }) .onClick(() => { //青綠色 this.color = '#32CD32'; this.context.strokeStyle = this.color; this.isEraserMode = false; }) .backgroundColor('#32CD32') .width('40vp') .width('40vp') .margin($r('app.float.wh_value_10'))  Button(' ', { type: ButtonType.Circle }) .onClick(() => { //橙色 this.color = '#FFA500'; this.context.strokeStyle = this.color; this.isEraserMode = false; }) .backgroundColor('#FFA500') .width('40vp') .width('40vp') .margin($r('app.float.wh_value_10'))  Button(' ', { type: ButtonType.Circle }) .onClick(() => { //黃色 this.color = '#FFFF00'; this.context.strokeStyle = this.color; this.isEraserMode = false; }) .backgroundColor('#FFFF00') .width('40vp') .width('40vp') .margin($r('app.float.wh_value_10'))  }.padding('10vp') } .scrollable(ScrollDirection.Horizontal) // 設(shè)置滾動條水平方向滾動 .margin($r('app.float.wh_value_5'))  Row() { Image('/common/images/eraser.png') .onClick(() => { //橡皮擦模式 this.isEraserMode = true; console.log('gyf eraser button'); }) .width('50vp') .height('50vp') .margin('10vp')  Button('清理畫板').onClick(() => { this.context.clearRect(0, 0, 1000, 1000); }) } .margin($r('app.float.wh_value_5'))  } .width('100%') .height('25%').alignItems(HorizontalAlign.Start)
		三、邏輯代碼
		邏輯代碼存在于Canvas的onTouch事件中,通過TouchType的Down、Up、Move來判斷開始、移動和結(jié)束的動作。一筆完整的繪制包含一次Down和Up,其中有若干次的Move。橡皮擦模式通過clearRect接口實(shí)現(xiàn)擦除的功能。

		.onTouch((event) => { if (event.type === TouchType.Down) { this.eventType = 'Down'; this.drawing = true; [this.x, this.y] = [event.touches[0].x, event.touches[0].y]; this.context.beginPath(); this.context.lineCap = 'round'; if (this.isEraserMode) { //橡皮擦模式 this.context.clearRect(this.x, this.y, 20, 20); }  console.log('gyf Down'); } if (event.type === TouchType.Up) { this.eventType = 'Up'; this.drawing = false; console.log('gyf Up!'); this.context.closePath(); } if (event.type === TouchType.Move) { if (!this.drawing) return; this.eventType = 'Move'; console.log('gyf Move');  if (this.isEraserMode) { //橡皮擦模式 this.context.clearRect(event.touches[0].x, event.touches[0].y, 20, 20); } else { this.context.lineWidth = this.lineWidth; this.context.strokeStyle = this.color;  this.context.moveTo(this.x, this.y); this.x = event.touches[0].x; this.y = event.touches[0].y; this.context.lineTo(this.x, this.y); this.context.stroke(); } }})
		

總結(jié)

本文介紹了如何使用ArkUI框架提供的Canvas組件實(shí)現(xiàn)涂鴉功能。首先,通過Canvas的onTouch事件來跟蹤Down、Move和Up的事件,再設(shè)置CanvasRenderingContext2D的相關(guān)屬性并調(diào)用相關(guān)的方法,最終實(shí)現(xiàn)涂鴉的功能。除了文中分享的涂鴉樣例,開發(fā)者還可以通過拓展其他相關(guān)的屬性和方法,實(shí)現(xiàn)更多好玩的、高性能的樣例。
審核編輯:彭靜

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • Canvas
    +關(guān)注

    關(guān)注

    0

    文章

    20

    瀏覽量

    11209
  • 涂鴉
    +關(guān)注

    關(guān)注

    0

    文章

    14

    瀏覽量

    4300
  • OpenHarmony
    +關(guān)注

    關(guān)注

    29

    文章

    3847

    瀏覽量

    18346

原文標(biāo)題:如何利用OpenHarmony ArkUI的Canvas組件實(shí)現(xiàn)涂鴉功能?

文章出處:【微信號:gh_e4f28cfa3159,微信公眾號:OpenAtom OpenHarmony】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點(diǎn)推薦

    鴻蒙ArkTS開始實(shí)例:【canvas實(shí)現(xiàn)簽名板功能

    使用ArkTS中的canvas實(shí)現(xiàn)簽名板的功能,canvas畫布大家都很熟悉,我們會用它經(jīng)常實(shí)現(xiàn)一些畫板或者圖表、表格之類的
    的頭像 發(fā)表于 04-08 10:10 ?1413次閱讀
    鴻蒙ArkTS開始實(shí)例:【<b class='flag-5'>canvas</b><b class='flag-5'>實(shí)現(xiàn)</b>簽名板<b class='flag-5'>功能</b>】

    涂鴉標(biāo)準(zhǔn)模組MCU SDK開發(fā)流程 精選資料推薦

    的對接成本,MCU SDK 已搭建通訊及協(xié)議解析架構(gòu)。將 MCU SDK 添加至自己的工程并配置相關(guān)信息后,既可以快速的完成 MCU 程序開發(fā)。在涂鴉 IoT 平臺通過自定義產(chǎn)品功能自動生成MCU
    發(fā)表于 07-20 06:28

    通過一個圓形抽獎轉(zhuǎn)盤演示HarmonyOS自定義組件實(shí)現(xiàn)

    實(shí)現(xiàn)Component.EstimateSizeListener接口需要HarmonyOS SDK版本在2.1.0.13或以上。本教程將通過以下內(nèi)容為您展示如何使用自定義組件實(shí)現(xiàn)圓形抽
    發(fā)表于 09-22 14:41

    canvas繪制“飛機(jī)大戰(zhàn)”小游戲,真香!

    行聲明式UI語法擴(kuò)展,從組件、動效和狀態(tài)管理三個維度提供了UI繪制能力。目前,eTS語言已經(jīng)提供了canvas組件繪制能力,但功能仍在完善中。下面我們將
    發(fā)表于 02-09 17:26

    如何用canvas組件實(shí)現(xiàn)在JS UI上畫出連續(xù)的線條?

    在使用框架的過程中,我想使用canvas這個畫布組件實(shí)現(xiàn)【筆】的功能,可以在JS UI上畫出連續(xù)的線條,如下圖:仔細(xì)查看文檔中很多JS UI中關(guān)于
    發(fā)表于 04-02 10:47

    OpenHarmony 3.1 Beta 版本關(guān)鍵特性解析——ArkUI canvas組件

    布局搭建、CSS 文件進(jìn)行樣式描述,并通過 JS 語言進(jìn)行邏輯處理。目前,JS 語言的 canvas 繪圖功能已經(jīng)基本上完善,下面我們將通過兩個示例,展示基于 JS 語言的
    發(fā)表于 04-12 10:34

    通過組件實(shí)現(xiàn)ec20模塊撥號的功能

    我想通過ec20模塊實(shí)現(xiàn)撥號的功能,能通過組件實(shí)現(xiàn)嗎?我沒有找到相應(yīng)的接口。
    發(fā)表于 08-15 10:07

    如何利用OpenHarmony ArkUI的Canvas組件實(shí)現(xiàn)涂鴉功能?

    新的組件,例如Canvas、OffscreenCanvas、XComponent組件等。新增的功能可以幫助開發(fā)者開發(fā)出更流暢、更美觀的應(yīng)用。本篇文章將為大家分享如何
    發(fā)表于 09-17 16:41

    如何利用OpenHarmony ArkUI的Canvas組件實(shí)現(xiàn)涂鴉功能?

    、更美觀的應(yīng)用。本篇文章將為大家分享如何通過Canvas組件實(shí)現(xiàn)涂鴉功能,用戶可以選擇空白畫布或
    發(fā)表于 09-20 11:31

    本周四晚19:00知識賦能第八期第3課丨涂鴉小游戲的實(shí)現(xiàn)

    了ArkUI自定義組件流程和實(shí)踐操作自定義組件,開發(fā)者們紛紛留言參與互動,營造了積極的學(xué)習(xí)氛圍。而本節(jié)直播將繼續(xù)由巴延興老師講解《涂鴉小游戲的實(shí)現(xiàn)》——本次分享將主要介紹三方面內(nèi)容,包
    發(fā)表于 09-28 11:56

    【直播回顧】OpenHarmony知識賦能第八期:手把手教你實(shí)現(xiàn)涂鴉小游戲

    實(shí)現(xiàn)鏈接:https://bbs.elecfans.com/jishu_2308126_1_1.html內(nèi)容介紹:本次分享將主要介紹三方面內(nèi)容,包括OpenHarmony新增組件的介紹、新增組件的實(shí)際應(yīng)用以及使用
    發(fā)表于 10-10 15:58

    HarmonyOS/OpenHarmony應(yīng)用開發(fā)-ArkTS畫布組件Canvas

    提供畫布組件,用于自定義繪制圖形。該組件從API Version 8開始支持。后續(xù)版本如有新增內(nèi)容,則采用上角標(biāo)單獨(dú)標(biāo)記該內(nèi)容的起始版本。子組件,不支持。接口: Canvas(cont
    發(fā)表于 02-27 09:49

    手把手教你使用ArkTS中的canvas實(shí)現(xiàn)簽名板功能

    問題,接下來實(shí)現(xiàn)簽名功能。因?yàn)樵谥熬鸵呀?jīng)開發(fā)過,只要將對應(yīng)的語法轉(zhuǎn)成 ArkTS 的語法就好。以下是代碼解析:2.1 按照官方文檔使用 canvas 組件 @Entry@Compon
    發(fā)表于 12-20 10:33

    canvas基礎(chǔ)繪制方法介紹

      canvas是ArkUI開發(fā)框架里的畫布組件,常用于自定義繪制圖形。因?yàn)槠漭p量、靈活、高效等優(yōu)點(diǎn),被廣泛應(yīng)用于UI界面開發(fā)中。本期,我們將為大家介紹canvas組件的使用。
    的頭像 發(fā)表于 02-12 10:09 ?4491次閱讀
    <b class='flag-5'>canvas</b>基礎(chǔ)繪制方法介紹

    canvas組件的使用介紹

    canvas是ArkUI開發(fā)框架里的畫布組件,常用于自定義繪制圖形。因?yàn)槠漭p量、靈活、高效等優(yōu)點(diǎn),被廣泛應(yīng)用于UI界面開發(fā)中。本期,我們將為大家介紹canvas組件的使用。
    的頭像 發(fā)表于 03-18 11:16 ?3270次閱讀