在移動端和小型設備應用中,動態顯示評分通常使用五角星圖形更直觀。本文將結合 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 或進度顯示提供了靈活且高性能的解決方案。