1e41f4b71Sopenharmony_ci# Using the Mirroring Capability 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ci## Overview 4e41f4b71Sopenharmony_ci 5e41f4b71Sopenharmony_ciTo accommodate diverse user reading habits, ArkUI provides a mirroring capability that can reverse the display content along the x-axis, switching the layout from left-to-right to right-to-left. 6e41f4b71Sopenharmony_ci 7e41f4b71Sopenharmony_ci| Before Mirroring | After Mirroring | 8e41f4b71Sopenharmony_ci| ----------- | ----------------------------------- | 9e41f4b71Sopenharmony_ci||| 10e41f4b71Sopenharmony_ci 11e41f4b71Sopenharmony_ciThe mirroring capability is activated on a component under either of these conditions: 12e41f4b71Sopenharmony_ci 13e41f4b71Sopenharmony_ci1. The component's **direction** attribute is set to **Direction.Rtl**. 14e41f4b71Sopenharmony_ci 15e41f4b71Sopenharmony_ci2. The component's **direction** attribute is set to **Direction.Auto**, and the system language in use (such as Uyghur) is read from right to left. 16e41f4b71Sopenharmony_ci 17e41f4b71Sopenharmony_ci## Basic Concepts 18e41f4b71Sopenharmony_ci 19e41f4b71Sopenharmony_ci- LTR: left-to-right reading direction 20e41f4b71Sopenharmony_ci- RTL: right-to-Left reading direction 21e41f4b71Sopenharmony_ci 22e41f4b71Sopenharmony_ci## Constraints 23e41f4b71Sopenharmony_ci 24e41f4b71Sopenharmony_ciArkUI has default mirroring support for the following capabilities: 25e41f4b71Sopenharmony_ci 26e41f4b71Sopenharmony_ci| Category | Name | 27e41f4b71Sopenharmony_ci| -------- | ------------------------------------------------------------ | 28e41f4b71Sopenharmony_ci| Basic components| [Swiper](../reference/apis-arkui/arkui-ts/ts-container-swiper.md), [Tab](../reference/apis-arkui/arkui-ts/ts-container-tabs.md), [TabContent](../reference/apis-arkui/arkui-ts/ts-container-tabcontent.md), [List](../reference/apis-arkui/arkui-ts/ts-container-list.md), [Progress](../reference/apis-arkui/arkui-ts/ts-basic-components-progress.md), [CalendarPicker](../reference/apis-arkui/arkui-ts/ts-basic-components-calendarpicker.md), [CalendarPickerDialog](../reference/apis-arkui/arkui-ts/ts-methods-calendarpicker-dialog.md), [TextPicker](../reference/apis-arkui/arkui-ts/ts-basic-components-textpicker.md), [TextPickerDialog](../reference/apis-arkui/arkui-ts/ts-methods-textpicker-dialog.md), [DatePicker](../reference/apis-arkui/arkui-ts/ts-basic-components-datepicker.md), [DatePickerDialog](../reference/apis-arkui/arkui-ts/ts-methods-datepicker-dialog.md), [Grid](../reference/apis-arkui/arkui-ts/ts-container-grid.md), [WaterFlow](../reference/apis-arkui/arkui-ts/ts-container-waterflow.md), [Scroll](../reference/apis-arkui/arkui-ts/ts-container-scroll.md), [ScrollBar](../reference/apis-arkui/arkui-ts/ts-basic-components-scrollbar.md), [AlphabetIndexer](../reference/apis-arkui/arkui-ts/ts-container-alphabet-indexer.md), [Stepper](../reference/apis-arkui/arkui-ts/ts-basic-components-stepper.md), [SideBarContainer](../reference/apis-arkui/arkui-ts/ts-container-sidebarcontainer.md), [Navigation](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md), [NavDestination](../reference/apis-arkui/arkui-ts/ts-basic-components-navdestination.md), [Rating](../reference/apis-arkui/arkui-ts/ts-basic-components-rating.md), [Slider](../reference/apis-arkui/arkui-ts/ts-basic-components-slider.md), [Toggle](../reference/apis-arkui/arkui-ts/ts-basic-components-toggle.md), [Badge](../reference/apis-arkui/arkui-ts/ts-container-badge.md), [Counter](../reference/apis-arkui/arkui-ts/ts-container-counter.md), [Chip](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-Chip.md), [SegmentButton](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-SegmentButton.md), [bindMenu](../reference/apis-arkui/arkui-ts/ts-universal-attributes-menu.md#bindmenu), [bindContextMenu](../reference/apis-arkui/arkui-ts/ts-universal-attributes-menu.md#bindcontextmenu8), [TextInput](../reference/apis-arkui/arkui-ts/ts-basic-components-textinput.md), [TextArea](../reference/apis-arkui/arkui-ts/ts-basic-components-textarea.md), [Search](../reference/apis-arkui/arkui-ts/ts-basic-components-search.md), [Stack](../reference/apis-arkui/arkui-ts/ts-container-stack.md), [GridRow](../reference/apis-arkui/arkui-ts/ts-container-gridrow.md), [Text](../reference/apis-arkui/arkui-ts/ts-basic-components-text.md), [Select](../reference/apis-arkui/arkui-ts/ts-basic-components-select.md), [Marquee](../reference/apis-arkui/arkui-ts/ts-basic-components-marquee.md), [Row](../reference/apis-arkui/arkui-ts/ts-container-row.md), [Column](../reference/apis-arkui/arkui-ts/ts-container-column.md), [Flex](../reference/apis-arkui/arkui-ts/ts-container-flex.md), [RelativeContainer](../reference/apis-arkui/arkui-ts/ts-container-relativecontainer.md), [ListItemGroup](../reference/apis-arkui/arkui-ts/ts-container-listitemgroup.md)| 29e41f4b71Sopenharmony_ci| Advanced components| [SelectionMenu](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-SelectionMenu.md) , [TreeView](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-TreeView.md) , [Filter](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-Filter.md), [SplitLayout](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-SplitLayout.md), [ToolBar](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-ToolBar.md), [ComposeListItem](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-ComposeListItem.md), [EditableTitleBar](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-EditableTitleBar.md), [ProgressButton](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-ProgressButton.md), [SubHeader](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-SubHeader.md) , [Popup](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-Popup.md), [Dialog](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-Dialog.md), [SwipeRefresher](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-SwipeRefresher.md)| 30e41f4b71Sopenharmony_ci| Universal attributes| [position](../reference/apis-arkui/arkui-ts/ts-universal-attributes-location.md#position), [markAnchor](../reference/apis-arkui/arkui-ts/ts-universal-attributes-location.md#markanchor), [offset](../reference/apis-arkui/arkui-ts/ts-universal-attributes-location.md#offset), [alignRules](../reference/apis-arkui/arkui-ts/ts-universal-attributes-location.md#alignrules9), [borderWidth](../reference/apis-arkui/arkui-ts/ts-universal-attributes-border.md#borderwidth), [borderColor](../reference/apis-arkui/arkui-ts/ts-universal-attributes-border.md#bordercolor), [borderRadius](../reference/apis-arkui/arkui-ts/ts-universal-attributes-border.md#borderradius), [padding](../reference/apis-arkui/arkui-ts/ts-universal-attributes-size.md#padding), [margin](../reference/apis-arkui/arkui-ts/ts-universal-attributes-size.md#margin)| 31e41f4b71Sopenharmony_ci| APIs | [AlertDialog](../reference/apis-arkui/arkui-ts/ts-methods-alert-dialog-box.md), [ActionSheet](../reference/apis-arkui/arkui-ts/ts-methods-action-sheet.md), [promptAction.showDialog](../reference/apis-arkui/js-apis-promptAction.md#promptactionshowdialog), [promptAction.showToast](../reference/apis-arkui/js-apis-promptAction.md#promptactionshowtoast)| 32e41f4b71Sopenharmony_ci 33e41f4b71Sopenharmony_ciHowever, adaptation is still required in the following three scenarios: 34e41f4b71Sopenharmony_ci 35e41f4b71Sopenharmony_ci1. For layout and border settings, use the generalized direction terms **start** and **end** as parameter types instead of absolute terms such as **left**, **right**, **x**, and **y**, to accommodate mirroring. 36e41f4b71Sopenharmony_ci 37e41f4b71Sopenharmony_ci2. The **Canvas** component offers limited support for mirroring in text drawing only. 38e41f4b71Sopenharmony_ci 39e41f4b71Sopenharmony_ci3. The **XComponent** component does not support mirroring capabilities. 40e41f4b71Sopenharmony_ci 41e41f4b71Sopenharmony_ci## Layout and Border Settings 42e41f4b71Sopenharmony_ci 43e41f4b71Sopenharmony_ciTo adapt to mirroring capabilities, update the following universal attributes with new parameter types: 44e41f4b71Sopenharmony_ci 45e41f4b71Sopenharmony_ciPosition settings: [position](../reference/apis-arkui/arkui-ts/ts-universal-attributes-location.md#position), [markAnchor](../reference/apis-arkui/arkui-ts/ts-universal-attributes-location.md#markanchor), [offset](../reference/apis-arkui/arkui-ts/ts-universal-attributes-location.md#offset), [alignRules](../reference/apis-arkui/arkui-ts/ts-universal-attributes-location.md#alignrules12) 46e41f4b71Sopenharmony_ci 47e41f4b71Sopenharmony_ciBorder settings: [borderWidth](../reference/apis-arkui/arkui-ts/ts-universal-attributes-border.md#borderwidth), [borderColor](../reference/apis-arkui/arkui-ts/ts-universal-attributes-border.md#bordercolor), [borderRadius](../reference/apis-arkui/arkui-ts/ts-universal-attributes-border.md#borderradius) 48e41f4b71Sopenharmony_ci 49e41f4b71Sopenharmony_ciSize settings: [padding](../reference/apis-arkui/arkui-ts/ts-universal-attributes-size.md#padding), [margin](../reference/apis-arkui/arkui-ts/ts-universal-attributes-size.md#margin) 50e41f4b71Sopenharmony_ci 51e41f4b71Sopenharmony_ciFor example, with **position**, change the absolute directional descriptions of **x** and **y** to the new parameter types of **start** and **end**. 52e41f4b71Sopenharmony_ci 53e41f4b71Sopenharmony_ci```typeScript 54e41f4b71Sopenharmony_ciimport { LengthMetrics } from '@kit.ArkUI'; 55e41f4b71Sopenharmony_ci 56e41f4b71Sopenharmony_ci@Entry 57e41f4b71Sopenharmony_ci@Component 58e41f4b71Sopenharmony_cistruct Index1 { 59e41f4b71Sopenharmony_ci build() { 60e41f4b71Sopenharmony_ci Stack({ alignContent: Alignment.TopStart }) { 61e41f4b71Sopenharmony_ci Stack({ alignContent: Alignment.TopStart }) { 62e41f4b71Sopenharmony_ci Column() 63e41f4b71Sopenharmony_ci .width(100) 64e41f4b71Sopenharmony_ci .height(100) 65e41f4b71Sopenharmony_ci .backgroundColor(Color.Red) 66e41f4b71Sopenharmony_ci .position({ start: LengthMetrics.px(200), top: LengthMetrics.px(200) }) // Use the new LocalizedEdges parameter type added since API version 12 for supporting both LTR and RTL. 67e41f4b71Sopenharmony_ci // It is equivalent to .position({ x: '200px', y: '200px' }) when only LTR is supported. 68e41f4b71Sopenharmony_ci 69e41f4b71Sopenharmony_ci }.backgroundColor(Color.Blue) 70e41f4b71Sopenharmony_ci }.width("100%").height("100%").border({ color: '#880606' }) 71e41f4b71Sopenharmony_ci } 72e41f4b71Sopenharmony_ci} 73e41f4b71Sopenharmony_ci``` 74e41f4b71Sopenharmony_ci 75e41f4b71Sopenharmony_ci## Custom Drawing with the Canvas Component 76e41f4b71Sopenharmony_ci 77e41f4b71Sopenharmony_ciThe drawings and coordinates of the **Canvas** component do not support mirroring. Content drawn on it does not automatically mirror when the system language changes. 78e41f4b71Sopenharmony_ci 79e41f4b71Sopenharmony_ci[CanvasRenderingContext2D](../reference/apis-arkui/arkui-ts/ts-canvasrenderingcontext2d.md) supports mirroring for text rendering, which should be used with the **Canvas** component's **direction** attribute and the **direction** attribute of **CanvasRenderingContext2D**. The specific specifications are as follows: 80e41f4b71Sopenharmony_ci 81e41f4b71Sopenharmony_ci1. Priority: The **direction** attribute of **CanvasRenderingContext2D** takes precedence over the **Canvas** component's **direction** attribute, which in turn follows the system language's horizontal display direction. 82e41f4b71Sopenharmony_ci2. The **Canvas** component does not automatically mirror with system language changes; applications must listen for system language changes and redraw the content on their own. 83e41f4b71Sopenharmony_ci3. Only symbols follow the direction setting during text drawing with **CanvasRenderingContext2D**; Latin characters and numbers do not. 84e41f4b71Sopenharmony_ci 85e41f4b71Sopenharmony_ci```typeScript 86e41f4b71Sopenharmony_ciimport { BusinessError, commonEventManager } from '@kit.BasicServicesKit'; 87e41f4b71Sopenharmony_ci 88e41f4b71Sopenharmony_ci@Entry 89e41f4b71Sopenharmony_ci@Component 90e41f4b71Sopenharmony_cistruct Index { 91e41f4b71Sopenharmony_ci @State message: string = 'Hello world'; 92e41f4b71Sopenharmony_ci private settings: RenderingContextSettings = new RenderingContextSettings(true) 93e41f4b71Sopenharmony_ci private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) 94e41f4b71Sopenharmony_ci 95e41f4b71Sopenharmony_ci aboutToAppear(): void { 96e41f4b71Sopenharmony_ci // Listen for the system language changes. 97e41f4b71Sopenharmony_ci let subscriber: commonEventManager.CommonEventSubscriber | null = null; 98e41f4b71Sopenharmony_ci let subscribeInfo2: commonEventManager.CommonEventSubscribeInfo = { 99e41f4b71Sopenharmony_ci events: ["usual.event.LOCALE_CHANGED"], 100e41f4b71Sopenharmony_ci } 101e41f4b71Sopenharmony_ci commonEventManager.createSubscriber(subscribeInfo2, (err: BusinessError, data: commonEventManager.CommonEventSubscriber) => { 102e41f4b71Sopenharmony_ci if (err) { 103e41f4b71Sopenharmony_ci console.error(`Failed to create subscriber. Code is ${err.code}, message is ${err.message}`); 104e41f4b71Sopenharmony_ci return; 105e41f4b71Sopenharmony_ci } 106e41f4b71Sopenharmony_ci 107e41f4b71Sopenharmony_ci subscriber = data; 108e41f4b71Sopenharmony_ci if (subscriber !== null) { 109e41f4b71Sopenharmony_ci commonEventManager.subscribe(subscriber, (err: BusinessError, data: commonEventManager.CommonEventData) => { 110e41f4b71Sopenharmony_ci if (err) { 111e41f4b71Sopenharmony_ci console.error(`Failed to subscribe to the language and region status change event. Code: ${err.code}; message: ${err.message}`); 112e41f4b71Sopenharmony_ci return; 113e41f4b71Sopenharmony_ci } 114e41f4b71Sopenharmony_ci console.info('Successfully subscribed to the language and region status change event: data: ' + JSON.stringify(data)) 115e41f4b71Sopenharmony_ci // After detecting the language switch, redraw the content on the Canvas component. 116e41f4b71Sopenharmony_ci this.drawText(); 117e41f4b71Sopenharmony_ci }) 118e41f4b71Sopenharmony_ci } else { 119e41f4b71Sopenharmony_ci console.error(`MayTest Need create subscriber`); 120e41f4b71Sopenharmony_ci } 121e41f4b71Sopenharmony_ci }) 122e41f4b71Sopenharmony_ci } 123e41f4b71Sopenharmony_ci 124e41f4b71Sopenharmony_ci drawText(): void { 125e41f4b71Sopenharmony_ci console.error("MayTest drawText") 126e41f4b71Sopenharmony_ci this.context.reset() 127e41f4b71Sopenharmony_ci this.context.direction = "inherit" 128e41f4b71Sopenharmony_ci this.context.font = '30px sans-serif' 129e41f4b71Sopenharmony_ci this.context.fillText("ab%123&*@", 50, 50) 130e41f4b71Sopenharmony_ci } 131e41f4b71Sopenharmony_ci 132e41f4b71Sopenharmony_ci build() { 133e41f4b71Sopenharmony_ci Row() { 134e41f4b71Sopenharmony_ci Canvas(this.context) 135e41f4b71Sopenharmony_ci .direction(Direction.Auto) 136e41f4b71Sopenharmony_ci .width("100%") 137e41f4b71Sopenharmony_ci .height("100%") 138e41f4b71Sopenharmony_ci .onReady(() =>{ 139e41f4b71Sopenharmony_ci this.drawText() 140e41f4b71Sopenharmony_ci }) 141e41f4b71Sopenharmony_ci .backgroundColor(Color.Pink) 142e41f4b71Sopenharmony_ci } 143e41f4b71Sopenharmony_ci .height('100%') 144e41f4b71Sopenharmony_ci } 145e41f4b71Sopenharmony_ci 146e41f4b71Sopenharmony_ci} 147e41f4b71Sopenharmony_ci``` 148e41f4b71Sopenharmony_ci 149e41f4b71Sopenharmony_ci| Before Mirroring | After Mirroring | 150e41f4b71Sopenharmony_ci| ----------- | ----------------------------------- | 151e41f4b71Sopenharmony_ci||| 152