Problem Description
After obtaining the absolute coordinates of the click location through the child component's click event, how can these coordinates be converted to their relative coordinates with respect to the parent component?
Background Knowledge
componentUtils.getRectangleById: Retrieves the component instance object based on the component ID, and returns the obtained coordinates and size to the developer through the component instance object. The coordinates of the component refer to the coordinates of the top-left vertex of the component.
The onAreaChange callback is triggered when the component's area changes. It returns the width and height of the target element after the change, as well as the coordinates of the target element relative to the parent element and the top-left corner of the page.
Solution
Solution 1: The localOffset obtained using componentUtils.getRectangleById represents the coordinates of the child component within the parent component. The x, y coordinates obtained from the onTouch event represent the touch point's coordinates within the child component. By adding these two together, you can obtain the touch point's coordinates within the parent component.
The complete code is as follows:
@Entry
@Component
struct Index {
@State startXIn: number = 0;
@State startYIn: number = 0;
build() {
Column() {
Column() {
Image($r('app.media.background'))
.id('123456')
.width(150)
.height(200)
.onTouch((event) => {
let modePosition = this.getUIContext().getComponentUtils().getRectangleById('123456')
// Component position relative to its parent
let imageX = this.getUIContext().px2vp(modePosition.localOffset.x)
let imageY = this.getUIContext().px2vp(modePosition.localOffset.y)
console.info('localOffset is', `${imageX} `, `${imageY}`)
// Touch offset within the child component
let startX = event.touches[0].x
let startY = event.touches[0].y
console.info(`touches are`, `${startX}`, `${startY}`)
// Convert coordinates to be relative to the parent component
this.startXIn = startX + imageX;
this.startYIn = startY + imageY;
})
}
.width(200)
.height(250)
.backgroundColor('#61CFBE')
.justifyContent(FlexAlign.Center)
Text(`X coordinate relative to parent: ${this.startXIn}`)
Text(`Y coordinate relative to parent: ${this.startYIn}`)
}
.height('100%')
.width('100%')
}
}
Solution 2: Using onAreaChange, you can obtain the coordinates offsetX and offsetY of the child component relative to the parent component. The x and y values in ClickEvent represent the coordinates of the click within the child component. By adding these two sets of coordinates, you can obtain the coordinates of the touch point within the parent component.
The complete code is as follows:
@Entry
@Component
struct Index2 {
@State startXIn: number = 0;
@State startYIn: number = 0;
@State offsetX: number = 0
@State offsetY: number = 0
build() {
Column() {
Column() {
Image($r('app.media.background'))
.width(150)
.height(200)
.onAreaChange((oldValue: Area, newValue: Area) => {
this.offsetX = Number(newValue.position.x)
this.offsetY = Number(newValue.position.y)
})
.onClick((event?: ClickEvent) => {
if (event) {
let startX = event.x
let startY = event.y
console.info(`touches are`, `${startX}`, `${startY}`)
this.startXIn = startX + this.offsetX;
this.startYIn = startY + this.offsetY;
}
})
}
.width(200)
.height(250)
.backgroundColor('#61CFBE')
.justifyContent(FlexAlign.Center)
Text(`X coordinate relative to parent: ${this.startXIn}`)
Text(`Y coordinate relative to parent: ${this.startYIn}`)
}
.height('100%')
.width('100%')
}
}
The implementation ideas for both are the same; they only differ in the methods used. Both involve adding the coordinates of the click position within the child component to the coordinates of the child component within the parent component, thereby obtaining the coordinates of the click position relative to the parent component.
Code Running Effect Diagram

Top comments (0)