HarmonyOS 鸿蒙Next 有没有多阶贝赛尔曲线实现案例?
HarmonyOS 鸿蒙Next 有没有多阶贝赛尔曲线实现案例? 有没有多阶贝赛尔曲线实现案例?目前看到函数只是最多三阶
![无图片]
提供drawing接口实现的多阶贝赛尔曲线demo
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 = screen.width;
let screenHeight = 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);
}
}
三方库链接:https://gitee.com/openharmony-tpc/ohos_mpchart#mpchart
请看下是否有效
更多关于HarmonyOS 鸿蒙Next 有没有多阶贝赛尔曲线实现案例?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
针对帖子标题“HarmonyOS 鸿蒙Next 有没有多阶贝赛尔曲线实现案例?”的问题,以下是专业且简洁的回答:
HarmonyOS 鸿蒙Next系统中,确实支持多阶贝赛尔曲线的实现。贝赛尔曲线作为一种重要的数学工具,在图形绘制、动画效果等领域有着广泛应用。在鸿蒙系统的开发框架中,你可以通过其提供的图形绘制API来实现多阶贝赛尔曲线。
具体来说,鸿蒙系统提供了丰富的图形绘制接口,这些接口支持绘制各种复杂的图形,包括多阶贝赛尔曲线。开发者可以利用这些接口,根据贝赛尔曲线的数学定义,传入相应的控制点坐标,从而绘制出所需的多阶贝赛尔曲线。
不过,需要注意的是,鸿蒙系统的API可能会随着版本的更新而有所变化,因此建议查阅最新的鸿蒙系统开发者文档,以获取最准确的信息和示例代码。
如果你正在寻找具体的实现案例,可以尝试在鸿蒙系统的开发者社区或者相关论坛中搜索,通常会有其他开发者分享他们的实现经验和代码片段。
如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html