• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  ![indicator](figures/arcswiper_indicator.png)
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  ![indicator2](figures/arcswiper_indicator2.png)
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  ![controller](figures/arcswiper_controll.gif)
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  ![vertical](figures/arcswiper_indicator.png)
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  ![vertical2](figures/arcswiper_vertical.png)
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![customContentTransition](figures/arcswiper_custom_animation.gif)
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