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'; 195import { 196 ArcSwiper, 197 ArcSwiperAttribute, 198 ArcDotIndicator, 199 ArcDirection, 200 ArcSwiperController 201} from '@kit.ArkUI'; 202 203@Entry 204@Component 205struct SwiperCustomAnimationExample { 206 private MIN_SCALE: number = 0.1; 207 @State backgroundColors: Color[] = [Color.Green, Color.Blue, Color.Yellow, Color.Pink, Color.Gray, Color.Orange]; 208 @State opacityList: number[] = []; 209 @State scaleList: number[] = []; 210 211 aboutToAppear(): void { 212 for (let i = 0; i < this.backgroundColors.length; i++) { 213 this.opacityList.push(1.0); 214 this.scaleList.push(1.0); 215 } 216 } 217 218 build() { 219 Column() { 220 ArcSwiper() { 221 ForEach(this.backgroundColors, (backgroundColor: Color, index: number) => { 222 Text(index.toString()) 223 .width(233) 224 .height(233) 225 .fontSize(50) 226 .textAlign(TextAlign.Center) 227 .backgroundColor(backgroundColor) 228 .opacity(this.opacityList[index]) 229 .scale({ x: this.scaleList[index], y: this.scaleList[index] }) 230 }) 231 } 232 .customContentTransition({ 233 timeout: 1000, 234 transition: (proxy: SwiperContentTransitionProxy) => { 235 if (proxy.position <= -1 || proxy.position >= 1) { 236 // When a group of pages is completely scrolled out of the viewport, reset the attribute values. 237 this.opacityList[proxy.index] = 1.0; 238 this.scaleList[proxy.index] = 1.0; 239 } else { 240 let position: number = Decimal.abs(proxy.position).toNumber(); 241 this.opacityList[proxy.index] = 1 - position; 242 this.scaleList[proxy.index] = 243 this.MIN_SCALE + (1 - this.MIN_SCALE) * (1 - position); 244 } 245 } 246 }) 247 }.width('100%') 248 } 249} 250``` 251 252 253 254## Implementing Swipe-to-Return 255 256The 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. 257 258```ts 259import { 260 ArcSwiper, 261 ArcSwiperAttribute, 262 ArcDotIndicator, 263 ArcDirection, 264 ArcSwiperController 265} from '@kit.ArkUI'; 266 267@Entry 268@Component 269struct SwiperCustomAnimationExample { 270 @State backgroundColors: Color[] = [Color.Green, Color.Blue, Color.Yellow, Color.Pink, Color.Gray, Color.Orange]; 271 innerSelectedIndex: number = 0; 272 273 build() { 274 Column() { 275 ArcSwiper() { 276 ForEach(this.backgroundColors, (backgroundColor: Color, index: number) => { 277 Text(index.toString()) 278 .width(233) 279 .height(233) 280 .fontSize(50) 281 .textAlign(TextAlign.Center) 282 .backgroundColor(backgroundColor) 283 }) 284 } 285 .onAnimationStart((index: number, targetIndex: number) => { 286 this.innerSelectedIndex = targetIndex; 287 }) 288 .onGestureRecognizerJudgeBegin((event: BaseGestureEvent, current: GestureRecognizer, 289 others: Array<GestureRecognizer>): GestureJudgeResult => { // When the implementation is about to succeed, set the recognizer enabling state based on the current component state. 290 if (current) { 291 let target = current.getEventTargetInfo(); 292 if (target && current.isBuiltIn() && current.getType() == GestureControl.GestureType.PAN_GESTURE) { 293 let swiperTarget = target as ScrollableTargetInfo; 294 if (swiperTarget instanceof ScrollableTargetInfo && 295 (swiperTarget.isBegin() || this.innerSelectedIndex === 0)) { // Check whether the ArcSwiper has scrolled to the beginning: swiperTarget.isBegin() or innerSelectedIndex === 0. 296 let panEvent = event as PanGestureEvent; 297 if (panEvent && panEvent.offsetX > 0 && (swiperTarget.isBegin() || this.innerSelectedIndex === 0)) { 298 return GestureJudgeResult.REJECT; 299 } 300 } 301 } 302 } 303 return GestureJudgeResult.CONTINUE; 304 }) 305 }.width('100%') 306 } 307} 308``` 309