Read the original article:Smart Watch - Stage - Smart Watch Circle Encircling Text Effect
Problem Description
How to implement the text effect around the circle of the smart watch?
Background Knowledge
Canvas or RichText can be used. Canvas is recommended (the drawing method is simple).
Solution
1、Use Canvas to implement the function.
@Entry
@Component
@Preview
export struct Index {
private settings: RenderingContextSettings = new RenderingContextSettings(true);
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
// Convert to radian value
private getAngle(n: number) {
return Math.PI / 180 * n;
}
private drawCircleText(text: string) {
const width = this.context.width, height = this.context.height;
const fontSize = 14;
const r = width / 2 - fontSize;
this.context.clearRect(0, 0, width, height); // Clear canvas
this.context.save();
this.context.font = `${fontSize}vp`
this.context.textBaseline = 'top';
const charRadius = 360 / text.length; // Arc length per character
this.context.translate(width / 2, height / 2);
for (let i = 0; i < text.length; i++) {
this.context.fillText(text.charAt(i), 0, -r);
this.context.rotate(this.getAngle(charRadius));
}
this.context.restore();
}
build() {
Row() {
Column() {
Canvas(this.context)
// .margin({top:50})
.width(200)
.height(200)
.borderColor('green')
.borderWidth(1)
.onReady(() => this.drawCircleText('Hello,World!Hello,World!'))
}
.width('100%')
}
.height('100%')
.backgroundColor(Color.White)
}
}
2、Implemented by using RichText
interface RichTextProps {
width: number;
height: number;
fontSize: number;
fontColor: string;
text: string;
}
function getRichTextStr(props: RichTextProps) {
const width = props.width, height = props.height;
const fontSize = props.fontSize, fontColor = props.fontColor;
const str = `<div style="width: 100%; height: 100%; display: flex; align-items: center; justify-content: center;">
<svg style="overflow: visible; display: inline-block;" viewBox="0 0 100 100" width="${width}" height="${height}">
<path fill='none' d="M 0,50 a 50,50 0 1, 1 0, 1 z" id="circle"></path>
<text font-size='${fontSize}' fill='${fontColor}'>
<textPath xlink:href="#circle">
${props.text}
</textPath>
</text>
</svg>
</div>`;
return str;
};
@Entry
@Component
@Preview
export struct Index {
defaultRichTextProps: RichTextProps = {
width: 600,
height: 600,
fontSize: 14,
fontColor: 'red',
text: 'Hello,World!Hel!Hello,World!HelHello,World!HelWorld!Hel',
};
build() {
Row() {
Column() {
Text('Implemented using RichText') // Implemented using RichText
.width('100%')
.margin({ bottom: 10, left: 10 })
RichText(getRichTextStr(this.defaultRichTextProps))
.borderColor('green')
.borderWidth(1)
.width(300)
.height(300)
}
.width('100%')
}
}
}

Top comments (0)