动态

详情 返回 返回

使用 OffscreenCanvas 在 HarmonyOS 中生成動態五角星評分圖 - 动态 详情

在移動端和小型設備應用中,動態顯示評分通常使用五角星圖形更直觀。本文將結合 HarmonyOS 的 OffscreenCanvas 與 OffscreenCanvasRenderingContext2D,演示如何生成可按分數填充的五角星圖像。

1. OffscreenCanvas 簡介

在 HarmonyOS 中,OffscreenCanvas 是一種在後台線程中進行繪製的畫布對象,它不直接顯示在界面上,而是生成 ImageBitmap 或 Blob 後再渲染到主線程或 UI 組件上。相比普通 Canvas,它有以下優勢:

支持多線程繪製:不會阻塞主線程,提高 UI 流暢度。

靈活生成圖像資源:可生成 ImageBitmap,用於 Image 組件或其他渲染場景。

適合動態圖形繪製:如評分星、進度條、遊戲元素等。

使用示例:

const canvas = new OffscreenCanvas(width, height);
const ctx = canvas.getContext('2d') as OffscreenCanvasRenderingContext2D;

參考:OffscreenCanvas API

2. 使用 OffscreenCanvasRenderingContext2D 繪製五角星

OffscreenCanvasRenderingContext2D 提供了豐富的繪圖 API,可實現路徑繪製、顏色填充和漸變效果。

在我們的示例中,需要實現如下功能:

繪製標準五角星路徑;

繪製整顆灰色背景星;

根據分數比例繪製黃色填充;

返回 ImageBitmap 對象供 UI 使用。

核心代碼如下:

export class CanvasUtil {
  /**
   * 生成五角星
   * @param starSize 寬高
   * @param score 分數
   * @param fullScore 總分
   * @returns 返回ImageBitmap對象,使用之後需要立即調用close防止內存泄露
   */
  static generateStar(starSize: number, score: number, fullScore: number): ImageBitmap {
    const canvas = new OffscreenCanvas(starSize, starSize);
    const ctx = canvas.getContext('2d') as OffscreenCanvasRenderingContext2D;

    // 創建五角星路徑
    const createStarPath = (cx: number, cy: number, spikes: number, outer: number, inner: number) => {
      const path = new Path2D();
      let rot = Math.PI / 2 * 3;
      const step = Math.PI / spikes;
      path.moveTo(cx + Math.cos(rot) * outer, cy + Math.sin(rot) * outer);
      for (let i = 0; i < spikes; i++) {
        rot += step;
        path.lineTo(cx + Math.cos(rot) * inner, cy + Math.sin(rot) * inner);
        rot += step;
        path.lineTo(cx + Math.cos(rot) * outer, cy + Math.sin(rot) * outer);
      }
      path.closePath();
      return path;
    }

    const path = createStarPath(starSize / 2, starSize / 2, 5, starSize / 2, starSize / 4.5);

    // 繪製灰色底星
    ctx.fillStyle = getContext().resourceManager.getColorSync($r("app.color.star_blank_color"));
    ctx.fill(path);

    // 根據 score 繪製黃色填充
    if (score > 0) {
      const ratio = Math.min(Math.max(score / fullScore, 0), 1); // 限制 0~1
      ctx.save();
      ctx.beginPath();
      ctx.clip(path); // 限制填充在星形內

      const grad = ctx.createLinearGradient(0, starSize, 0, 0);
      grad.addColorStop(0, getContext().resourceManager.getColorSync($r("app.color.star_fill_color")).toString());
      grad.addColorStop(ratio, getContext().resourceManager.getColorSync($r("app.color.star_fill_color")).toString());
      grad.addColorStop(ratio, getContext().resourceManager.getColorSync($r("app.color.star_blank_color")).toString());
      grad.addColorStop(1, getContext().resourceManager.getColorSync($r("app.color.star_blank_color")).toString());

      ctx.fillStyle = grad;
      ctx.fill(path);
      ctx.restore();
    }

    // 返回 ImageBitmap
    return ctx.transferToImageBitmap();
  }
}

3. 使用注意事項

內存管理:生成 ImageBitmap 後,使用完成需要調用 close() 釋放內存。

線程安全:OffscreenCanvas 可在工作線程中繪製,避免阻塞 UI。

漸變填充:通過 clip() 限制填充範圍,實現分數按比例顯示。
參考:OffscreenCanvasRenderingContext2D API

4. 總結

通過 OffscreenCanvas 與 OffscreenCanvasRenderingContext2D,我們可以在 HarmonyOS 中輕鬆實現動態五角星評分效果:

支持多線程繪製;

按分數比例填充顏色;

高效生成可複用圖像資源。

這為開發評分組件、遊戲 UI 或進度顯示提供了靈活且高性能的解決方案。

user avatar user_2dx56kla 头像 zaoying 头像 xinggandemuer_b5u1v2 头像 qian5201314 头像 zhuifengdekaomianbao 头像 jinshidemaodou 头像 kukudejiqimao_bns3pe 头像 xiaoyuindebuilder 头像 benpaodekaixinguo 头像 cryptorzz 头像 finally-vince 头像 wodekouwei 头像
点赞 47 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.