This module provides the stylus frame boost capability. By calling the stylus frame boost API, you can reduce the stylus writing latency of handwriting apps at a high frame rate.
Since: 26.0.0
forceRefreshOneFrame(action: number): number
Reduces the stylus writing latency of handwriting apps at a high frame rate.
Model restriction: This API can be used only in the stage model.
System capability: SystemCapability.Stylus.Handwrite
Since: 26.0.0
Parameters:
| Parameter | Type | Mandatory | Description |
|---|---|---|---|
| action | number | Yes | Stylus touch event. 0: down 1: up 2: move 3: cancel |
Returns:
| Type | Description |
|---|---|
| number | Query result. 0: The stylus frame boost is successfully executed. 1: The stylus frame boost fails to be executed. |
Example:
import { LengthMetricsUnit } from '@kit.ArkUI';
import { inputDevice } from '@kit.InputKit';
import { StylusFrameBoost } from '@kit.Penkit';
@Entry
@Component
struct StylusFrameBoostDemo {
private device: PencilHelper = new PencilHelper()
private settings: RenderingContextSettings = new RenderingContextSettings(false)
private ctx: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings, LengthMetricsUnit.PX)
private stylusFrameBoost: StylusFrameBoost = new StylusFrameBoost();
build() {
Column() {
Canvas(this.ctx)
.width('100%')
.height('100%')
.onReady(() => {
this.ctx.lineWidth = 20
this.ctx.beginPath()
this.ctx.lineCap = 'round'
this.ctx.strokeStyle = Color.Black;
})
.onTouch((event: TouchEvent) => {
// Check whether a stylus is connected. This API depends on the stylus service.
if (this.device.hasPencil) {
if (event.sourceTool === SourceTool.Pen || event.sourceTool === SourceTool.MOUSE ||
event.sourceTool === SourceTool.Finger) {
this.handleWriteEvent(event)
}
}
})
}
}
aboutToAppear(): void {
this.device.init();
}
handleWriteEvent(event: TouchEvent) {
if (event.touches.length <= 0) {
return
}
const touch = event.changedTouches[0]
let x = touch.x
let y = touch.y
switch (event.type) {
case TouchType.Down:
this.ctx.moveTo(vp2px(x), vp2px(y));
try {
this.stylusFrameBoost.forceRefreshOneFrame(event.type);
} catch (error) {
console.error('stylusFrameBoost failed: ', error);
}
break
case TouchType.Move:
this.ctx.lineTo(vp2px(x), vp2px(y));
try {
this.stylusFrameBoost.forceRefreshOneFrame(event.type);
} catch (error) {
console.error('stylusFrameBoost failed: ', error);
}
break
case TouchType.Up:
case TouchType.Cancel:
this.ctx.lineTo(vp2px(x), vp2px(y))
try {
this.stylusFrameBoost.forceRefreshOneFrame(event.type);
} catch (error) {
console.error('stylusFrameBoost failed: ', error);
}
break
}
this.ctx.stroke();
}
}
class PencilHelper {
private _hasPencil: boolean = false
private pencilId: number = 0
public get hasPencil(): boolean {
return this._hasPencil
}
async init() {
const deviceIds = await inputDevice.getDeviceList()
inputDevice.on('change', async (device: inputDevice.DeviceListener) => {
if (device.type === 'add') {
const isPencil = await this.isPencil(device.deviceId)
if (isPencil) {
this._hasPencil = true
this.pencilId = device.deviceId
}
} else if (this.pencilId === device.deviceId) {
// Delete the information that cannot be queried. You can determine the information only based on the previous ID.
this._hasPencil = false
this.pencilId = 0
}
})
for (const id of deviceIds) {
const info = await inputDevice.getDeviceInfo(id)
const isPencil = await this.isPencil(id)
if (isPencil) {
this._hasPencil = true
this.pencilId = id
break
}
}
}
async isPencil(deviceId: number) {
const info = await inputDevice.getDeviceInfo(deviceId)
return info.name.toLowerCase().indexOf('pencil') >= 0
}
}