示例参考如下:import { DrawContext, FrameNode, NodeController, RenderNode } from '@ohos.arkui.node'; import { UIContext } from '@ohos.arkui.UIContext'; import drawing from '@ohos.graphics.drawing'; import display from '@ohos.display'; import image from '@ohos.multimedia.image'; const TAG = 'DrawingTSSample'; let screen = display.getDefaultDisplaySync(); let screenWidth: number = screen.width; let screenHeight: number = screen.height; let pixelMap_: image.PixelMap | undefined; class MyRenderNode extends RenderNode { private getPixmapFromMedia(resource: Resource): PixelMap { const unit8Array = getContext(this)?.resourceManager?.getMediaContentSync({ bundleName: resource.bundleName, moduleName: resource.moduleName, id: resource.id }) const imageSource = image.createImageSource(unit8Array.buffer.slice(0, unit8Array.buffer.byteLength)); const createPixelMap: image.PixelMap = imageSource.createPixelMapSync({ desiredPixelFormat: image.PixelMapFormat.RGBA_8888 }); createPixelMap.scaleSync(1, 1); return createPixelMap; } private getPath(startX: number, startY: number): drawing.Path { //滑块高度 const blockHeight: number = vp2px(50); //滑块凸起部分高度 const bulgingHeight: number = vp2px(10); //四个角圆弧半径 const arcHeight: number = vp2px(5); //上下左右半圆半径大小 const circleRadius: number = vp2px(6.5); //凸起半圆距边缘的间距 const circleSpacing: number = vp2px(3.5); //上下左右半圆半径大小 const edgeHeight: number = vp2px(13.5); //上下左右半圆贝塞尔曲线系数 const circleBezierRatio: number = 0.5523; const path = new drawing.Path(); path.moveTo(startX, startY + bulgingHeight + edgeHeight); path.lineTo(startX, startY + bulgingHeight + arcHeight); //左上角圆弧 path.quadTo(startX, startY + bulgingHeight, startX + arcHeight, startY + bulgingHeight); path.lineTo(startX + edgeHeight, startY + bulgingHeight); //顶部半圆 path.arcTo(startX + edgeHeight, startY, startX + edgeHeight + circleRadius * 2, startY + circleRadius * 2, 180, 180); path.lineTo(startX + edgeHeight + circleRadius * 2, startY + bulgingHeight); //右上角圆弧 path.arcTo(startX + blockHeight - bulgingHeight * 2, startY + bulgingHeight, startX + blockHeight - bulgingHeight, startY + bulgingHeight * 2, 270, 90); path.lineTo(startX + blockHeight - bulgingHeight, startY + bulgingHeight + edgeHeight); //右侧半圆 path.arcTo(startX + blockHeight - circleRadius * 2, startY + +bulgingHeight + edgeHeight, startX + blockHeight, startY + +bulgingHeight + edgeHeight + circleRadius * 2, 270, 180); path.lineTo(startX + blockHeight - bulgingHeight, startY + +bulgingHeight + edgeHeight + circleRadius * 2); //右下角圆弧 path.arcTo(startX + blockHeight - bulgingHeight * 2, startY + blockHeight - bulgingHeight, startX + blockHeight - bulgingHeight, startY + blockHeight, 0, 90); path.lineTo(startX + blockHeight - bulgingHeight - edgeHeight, startY + blockHeight); //底部半圆 path.lineTo(startX + blockHeight - bulgingHeight - edgeHeight, startY + blockHeight - circleSpacing); //底部半圆中心点坐标 const bottomCenterX = startX + bulgingHeight * 2; const bottomCenterY = startY + blockHeight - circleSpacing; //底部半圆右侧1/4圆弧 path.cubicTo(bottomCenterX + circleRadius, bottomCenterY - circleRadius * circleBezierRatio, bottomCenterX + circleRadius * circleBezierRatio, bottomCenterY - circleRadius, bottomCenterX, bottomCenterY - circleRadius); //底部半圆左侧1/4圆弧 path.cubicTo(bottomCenterX - circleRadius * circleBezierRatio, bottomCenterY - circleRadius, bottomCenterX - circleRadius, bottomCenterY - circleRadius * circleBezierRatio, bottomCenterX - circleRadius, bottomCenterY); path.lineTo(startX + edgeHeight, startY + blockHeight); //左下角圆弧 path.arcTo(startX, startY + blockHeight - bulgingHeight, startX + bulgingHeight, startY + blockHeight, 90, 90); path.lineTo(startX, startY + blockHeight - edgeHeight); //左侧半圆 //左侧半圆中心点坐标 path.lineTo(startX + circleSpacing, startY + blockHeight - edgeHeight); const leftCenterX = startX + circleSpacing; const leftCenterY = startY + edgeHeight + bulgingHeight + circleRadius; //左侧半圆右侧1/4圆弧 path.cubicTo(leftCenterX + circleRadius * circleBezierRatio, leftCenterY + circleRadius, leftCenterX + circleRadius, leftCenterY + circleRadius * circleBezierRatio, leftCenterX + circleRadius, leftCenterY); //左侧半圆左侧1/4圆弧 path.cubicTo(leftCenterX + circleRadius, leftCenterY - circleRadius * circleBezierRatio, leftCenterX + circleRadius * circleBezierRatio, leftCenterY - circleRadius, leftCenterX, leftCenterY - circleRadius); path.lineTo(startX, startY + edgeHeight + bulgingHeight); return path; } // 在RenderNode的draw中使用drawing自定义绘制 async draw(context: DrawContext) { const canvas = context.canvas; let pixelMap: image.PixelMap = this.getPixmapFromMedia($r('app.media.icon_yummy_half_block_pic_02')); canvas.clipPath(this.getPath(600, 100), drawing.ClipOp.INTERSECT, true); let options = new drawing.SamplingOptions(drawing.FilterMode.FILTER_MODE_NEAREST); if (pixelMap != null) { canvas.drawImage(pixelMap, 0, 0, options); } } } // 创建一个MyRenderNode对象 const newNode = new MyRenderNode(); // 定义newNode的像素格式 newNode.frame = { x: 0, y: 0, width: screenWidth, height: screenHeight }; class TextRenderNode extends RenderNode { async draw(context: DrawContext) { const canvas = context.canvas; let brush = new drawing.Brush(); brush.setColor({ alpha: 255, red: 255, green: 0, blue: 0 }); let font = new drawing.Font(); font.setSize(50); const textBlob = drawing.TextBlob.makeFromString("Hello World", font, drawing.TextEncoding.TEXT_ENCODING_UTF8); canvas.attachBrush(brush); canvas.drawTextBlob(textBlob, 60, screenHeight / 4); canvas.detachBrush(); } } // 创建一个TextRenderNode对象 const textNode = new TextRenderNode(); // 定义textNode的像素格式 textNode.frame = { x: 0, y: 0, width: screenWidth, height: screenHeight }; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode { this.rootNode = new FrameNode(uiContext); if (this.rootNode === null) { return this.rootNode; } const renderNode = this.rootNode.getRenderNode(); if (renderNode !== null) { renderNode.frame = { x: 0, y: 0, width: 10, height: 500 }; renderNode.pivot = { x: 50, y: 50 }; } return this.rootNode; } addNode(node: RenderNode): void { if (this.rootNode === null) { return; } const renderNode = this.rootNode.getRenderNode(); if (renderNode !== null) { renderNode.appendChild(node); } } clearNodes(): void { if (this.rootNode === null) { return; } const renderNode = this.rootNode.getRenderNode(); if (renderNode !== null) { renderNode.clearChildren(); } } } @Entry @Component struct RenderTest { private settings: RenderingContextSettings = new RenderingContextSettings(true); private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); private myNodeController: MyNodeController = new MyNodeController(); build() { Column() { Row() { NodeContainer(this.myNodeController) .height('100%') Button("Draw Path") .margin({ bottom: 20, right: 12 }) .onClick(() => { this.myNodeController.clearNodes(); this.myNodeController.addNode(newNode); }) } .width('100%') .justifyContent(FlexAlign.Center) .shadow(ShadowStyle.OUTER_DEFAULT_SM) .alignItems(VerticalAlign.Bottom) .layoutWeight(1) } } // 将离屏绘制好的bitmap绘制到屏幕上 public async drawImage() { if (pixelMap_ === null) { console.error(TAG, 'draw image pixelMap_ is null'); return; } console.log(TAG, 'drawImage success'); this.context.drawImage(pixelMap_, 0, 100); } }
示例参考如下: