鴻蒙繪制凹形布局,滑動進(jìn)行大小重繪

當(dāng)系統(tǒng)布局無法滿足需求的時候,就需要自己繪制了,我的需求是繪制如下圖,且跟跟隨上下滑動調(diào)整凹形大小。


snapshot_2024-11-11_10-33-59 拷貝.png

布局分析

對關(guān)鍵點拆分如下圖:


image.png
  1. 三個一樣大小的圓
  • 進(jìn)行外切
  1. 中間的凹形
  • DG弧度繪制
  • AD/GE弧度繪制
  1. 上下滑動凹形大小尺寸變化
  • 通過官網(wǎng)查詢,最合適是使用Canvas,但Canvas.onReady只繪制一次,可以通過@Watch監(jiān)聽變量(圓的直徑)大小變化解決

用到的知識

1. 勾股定理

在平面上的一個直角三角形中,兩個直角邊邊長的平方加起來等于斜邊長的平方。如果設(shè)直角三角形的兩條直角邊長度分別是和,斜邊長度是,那么可以用數(shù)學(xué)語言表達(dá):


image.png

2. 弧度與角度轉(zhuǎn)化

弧度與角度轉(zhuǎn)換公式
1)將弧度轉(zhuǎn)換為角度:乘以 180,除以 π
2)將角度轉(zhuǎn)換為弧度:乘以 π,除以 180

這是弧度與角度的對照列表:

角度 弧度(精確) 弧度(近似)
30° π/6 0.524
45° π/4 0.785
60° π/3 1.047
90° π/2 1.571
180° π 3.142
270° 3π/2 4.712
360° 6.283

布局開始繪制

對于以上的布局分析,可以知道,布局繪制,其實畫三個弧線就可以完成了,代碼如下:

// AD左上弧-起始角度270,終點角度330
this.context.arc(centerX - mar, radius, radius, 270 * Math.PI / 180, 330 * Math.PI / 180)
// DG底部弧-起始角度150,終點角度30
this.context.arc(centerX, 0, radius, 150 * Math.PI / 180, 30 * Math.PI / 180, true)
// GE右上弧-起始角度210,終點角度270
this.context.arc(centerX + mar, radius, radius, 210 * Math.PI / 180, 270 * Math.PI / 180)

完整代碼如下

// 上下滑動修改fabSize的大小,使Canvas重新繪制
@State @Watch('drawBottomBar') fabSize: number = 80

drawBottomBar() {
    let width = this.context.width
    let height = this.context.height
    // 刪除之前繪制的,重新繪制
    this.context.clearRect(0, 0, width, height)
    this.context.beginPath()

    let centerX = width / 2
    let radius = this.fabSize / 2
    // AB/BE的距離
    let mar = Math.sqrt(Math.pow(this.fabSize, 2) - Math.pow(radius, 2))
    // 左上直線
    this.context.lineTo(centerX - mar, 0)
    // AD左上弧-起始角度270,終點角度330
    this.context.arc(centerX - mar, radius, radius, 270 * Math.PI / 180, 330 * Math.PI / 180)
    // DG底部弧-起始角度150,終點角度30
    this.context.arc(centerX, 0, radius, 150 * Math.PI / 180, 30 * Math.PI / 180, true)
    // GE右上弧-起始角度210,終點角度270
    this.context.arc(centerX + mar, radius, radius, 210 * Math.PI / 180, 270 * Math.PI / 180)
    // 右上直線
    this.context.lineTo(width, 0)
    // 右下直線
    this.context.lineTo(width, height)
    // 底部直線
    this.context.lineTo(0, height)
    // 閉合
    this.context.closePath()
    // 顏色
    this.context.fillStyle = '#344955'
    // 填充
    this.context.fill()
}

build() {
    Stack() {
      Canvas(this.context)
        .height(80)
        .width('100%')
        .onReady(() => {
          this.drawBottomBar()
        })
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容