1# Creating an Arc Carousel Component (ArcSwiper) (Recommended for Circular Screens) 2 3 4**ArcSwiper** is an arc carousel component designed specifically for circular screens, allowing you to display content in an arc layout. For details, see [ArcSwiper](../reference/apis-arkui/arkui-ts/ts-container-arcswiper.md). 5 6Before using the **ArcSwiper** component, you need to import the **ArcSwiper** module in your code: 7 8```ts 9import { 10 ArcSwiper, 11 ArcSwiperAttribute, 12 ArcDotIndicator, 13 ArcDirection, 14 ArcSwiperController 15} from '@kit.ArkUI' 16``` 17 18## Setting the Navigation Point Indicator Style 19 20**ArcSwiper** provides a default arc-shaped navigation point style, with the navigation points displayed centered below the **ArcSwiper**. You can customize the style of the arc-shaped navigation points using the [indicator](../reference/apis-arkui/arkui-ts/ts-container-arcswiper.md#indicator) attribute. 21 22Using the **indicator** attribute, you can set the direction of the arc-shaped navigation points and customize the colors of the points and the selected point. 23 24- Example of using the navigation point indicator in its default style: 25 26 ```ts 27 ArcSwiper() { 28 Text('0') 29 .width(233) 30 .height(233) 31 .backgroundColor(Color.Gray) 32 .textAlign(TextAlign.Center) 33 .fontSize(30) 34 35 Text('1') 36 .width(233) 37 .height(233) 38 .backgroundColor(Color.Green) 39 .textAlign(TextAlign.Center) 40 .fontSize(30) 41 42 Text('2') 43 .width(233) 44 .height(233) 45 .backgroundColor(Color.Pink) 46 .textAlign(TextAlign.Center) 47 .fontSize(30) 48 } 49 ``` 50  51 52- Example of customizing the style of the navigation point indicator: 53 54 In this example, the navigation dots are positioned at the 6 o'clock direction of the **ArcSwiper** component, with the dot color set to red and the selected point color set to blue. 55 56 ```ts 57 ArcSwiper() { 58 // ... 59 } 60 .indicator( 61 new ArcDotIndicator() 62 .arcDirection(ArcDirection.SIX_CLOCK_DIRECTION) // Set the dots at the 6 o'clock direction. 63 .itemColor (Color.Red) // Set the dot color to red. 64 .selectedItemColor (Color.Blue) // Set the selected dot color to blue. 65 ) 66 ``` 67  68 69## Controlling Page Switching Modes 70 71The **ArcSwiper** component supports four page switching modes: swiping with fingers, touching navigation points, rotating the digital crown, and using a controller. The following examples demonstrate how to use a controller and the digital crown to switch between pages. 72 73- Using a controller to switch between pages 74 75 ```ts 76 // Import the ArcButton and ArcSwiper modules. 77 import { 78 ArcButton, 79 ArcButtonOptions, 80 ArcButtonStatus, 81 ArcButtonStyleMode, 82 ArcButtonPosition, 83 ArcSwiper, 84 ArcSwiperAttribute, 85 ArcDotIndicator, 86 ArcDirection, 87 ArcSwiperController 88 } from '@kit.ArkUI'; 89 90 @Entry 91 @Component 92 struct SwiperCustomAnimationExample { 93 private wearableSwiperController: ArcSwiperController = new ArcSwiperController() 94 95 build() { 96 Column() { 97 Stack() { 98 ArcSwiper(this.wearableSwiperController) { 99 // ... 100 } 101 .vertical(true) 102 .indicator(false) 103 104 Column() { 105 ArcButton({ 106 options: new ArcButtonOptions({ 107 label: 'previous', 108 position: ArcButtonPosition.TOP_EDGE, 109 styleMode: ArcButtonStyleMode.EMPHASIZED_LIGHT, 110 onClick: () => { 111 this.wearableSwiperController.showPrevious(); // Switch to the previous page using the controller. 112 } 113 }) 114 }) 115 116 Blank() 117 118 ArcButton({ 119 options: new ArcButtonOptions({ 120 label: 'next', 121 position: ArcButtonPosition.BOTTOM_EDGE, 122 styleMode: ArcButtonStyleMode.EMPHASIZED_LIGHT, 123 onClick: () => { 124 this.wearableSwiperController.showNext(); // Switch to the next page using the controller. 125 } 126 }) 127 }) 128 }.width('100%').height('100%') 129 } 130 } 131 } 132 } 133 ``` 134 135  136 137- Using the digital crown to switch between pages 138 139 When the **ArcSwiper** component is focused, it can respond to digital crown rotations. Users can scroll through the **ArcSwiper** component by rotating the crown to browse content. 140 141 ```ts 142 ArcSwiper() { 143 // ... 144 } 145 .focusable(true) 146 .focusOnTouch(true) 147 .defaultFocus(true) 148 ``` 149 150 You can also adjust the sensitivity of the digital crown to events using the [digitalCrownSensitivity](../reference/apis-arkui/arkui-ts/ts-container-arcswiper.md#digitalcrownsensitivity) attribute to adapt to different scales of data. For large datasets, you can increase the sensitivity; for smaller datasets, you can decrease it. 151 152 ```ts 153 ArcSwiper() { 154 // ... 155 } 156 .digitalCrownSensitivity(CrownSensitivity.MEDIUM) 157 ``` 158 159## Setting the Swiping Direction 160 161The **ArcSwiper** component supports both horizontal and vertical swiping, controlled primarily by the [vertical](../reference/apis-arkui/arkui-ts/ts-container-arcswiper.md#vertical) attribute. 162 163When **vertical** is set to **true**, swiping occurs in the vertical direction. When **vertical** is set to **false**, swiping occurs in the horizontal direction. The default value is **false**. 164 165- Example of using horizontal swiping: 166 167 ```ts 168 ArcSwiper() { 169 // ... 170 } 171 .indicator(true) 172 .vertical(false) 173 ``` 174  175 176 177- Example of using vertical swiping with dots at the 3 o'clock direction: 178 179 ```ts 180 ArcSwiper() { 181 // ... 182 } 183 .indicator(new ArcDotIndicator() 184 .arcDirection(ArcDirection.THREE_CLOCK_DIRECTION)) 185 .vertical(true) 186 ``` 187  188 189## Customizing the Transition Animation 190 191Use the [customContentTransition](../reference/apis-arkui/arkui-ts/ts-container-arcswiper.md#customcontenttransition) attribute to set a custom transition animation for **ArcSwiper**. Define the animation by adjusting opacity, scale, translation, and rendering layer for all pages within the viewport frame by frame in the callback. 192 193```ts 194import { Decimal } from '@kit.ArkTS' 195 196@Entry 197@Component 198struct SwiperCustomAnimationExample { 199 private MIN_SCALE: number = 0.1 200 @State backgroundColors: Color[] = [Color.Green, Color.Blue, Color.Yellow, Color.Pink, Color.Gray, Color.Orange] 201 @State opacityList: number[] = [] 202 @State scaleList: number[] = [] 203 204 aboutToAppear(): void { 205 for (let i = 0; i < this.backgroundColors.length; i++) { 206 this.opacityList.push(1.0) 207 this.scaleList.push(1.0) 208 } 209 } 210 211 build() { 212 Column() { 213 ArcSwiper() { 214 ForEach(this.backgroundColors, (backgroundColor: Color, index: number) => { 215 Text(index.toString()) 216 .width(233) 217 .height(233) 218 .fontSize(50) 219 .textAlign(TextAlign.Center) 220 .backgroundColor(backgroundColor) 221 .opacity(this.opacityList[index]) 222 .scale({ x: this.scaleList[index], y: this.scaleList[index] }) 223 }) 224 } 225 .customContentTransition({ 226 timeout: 1000, 227 transition: (proxy: SwiperContentTransitionProxy) => { 228 if (proxy.position <= -1 || proxy.position >= 1) { 229 // When a group of pages is completely scrolled out of the viewport, reset the attribute values. 230 this.opacityList[proxy.index] = 1.0 231 this.scaleList[proxy.index] = 1.0 232 } else { 233 let position: number = Decimal.abs(proxy.position).toNumber() 234 this.opacityList[proxy.index] = 1 - position 235 this.scaleList[proxy.index] = 236 this.MIN_SCALE + (1 - this.MIN_SCALE) * (1 - position) 237 } 238 } 239 }) 240 }.width('100%') 241 } 242} 243``` 244 245 246 247## Implementing Swipe-to-Return 248 249The swipe gesture of the **ArcSwiper** component may conflict with the swipe-to-return functionality. To resolve this, you can use [gesture judgment](../reference/apis-arkui/arkui-ts/ts-gesture-blocking-enhancement.md#ongesturerecognizerjudgebegin) to determine whether **ArcSwiper** has scrolled to the beginning. This allows you to intercept the swipe gesture and enable the swipe-to-return functionality. 250 251```ts 252@Entry 253@Component 254struct SwiperCustomAnimationExample { 255 @State backgroundColors: Color[] = [Color.Green, Color.Blue, Color.Yellow, Color.Pink, Color.Gray, Color.Orange] 256 innerSelectedIndex: number = 0 257 258 build() { 259 Column() { 260 ArcSwiper() { 261 ForEach(this.backgroundColors, (backgroundColor: Color, index: number) => { 262 Text(index.toString()) 263 .width(233) 264 .height(233) 265 .fontSize(50) 266 .textAlign(TextAlign.Center) 267 .backgroundColor(backgroundColor) 268 }) 269 } 270 .onAnimationStart((index: number, targetIndex: number) => { 271 this.innerSelectedIndex = targetIndex 272 }) 273 .onGestureRecognizerJudgeBegin((event: BaseGestureEvent, current: GestureRecognizer, 274 others: Array<GestureRecognizer>): GestureJudgeResult => { // When the implementation is about to succeed, set the recognizer enabling state based on the current component state. 275 if (current) { 276 let target = current.getEventTargetInfo(); 277 if (target && current.isBuiltIn() && current.getType() == GestureControl.GestureType.PAN_GESTURE) { 278 let swiperTaget = target as ScrollableTargetInfo 279 if (swiperTaget instanceof ScrollableTargetInfo && 280 (swiperTaget.isBegin() || this.innerSelectedIndex === 0)) { // This condition checks whether ArcSwiper has scrolled to the beginning. 281 let panEvent = event as PanGestureEvent; 282 if (panEvent && panEvent.offsetX > 0 && (swiperTaget.isBegin() || this.innerSelectedIndex === 0)) { 283 return GestureJudgeResult.REJECT; 284 } 285 } 286 } 287 } 288 return GestureJudgeResult.CONTINUE; 289 }) 290 }.width('100%') 291 } 292} 293``` 294<!--no_check-->