1e41f4b71Sopenharmony_ci# Component Animation 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ci 4e41f4b71Sopenharmony_ciIn addition to universal property animation and transition animation APIs, ArkUI provides default animation effects for certain components, for example, the swipe effect for the [List](../reference/apis-arkui/arkui-ts/ts-container-list.md) component and the click effect of the [Button](../reference/apis-arkui/arkui-ts/ts-basic-components-button.md) component. Based on these default animation effects, you can apply custom animations to the child components through the property animation and transition animation APIs. 5e41f4b71Sopenharmony_ci 6e41f4b71Sopenharmony_ci 7e41f4b71Sopenharmony_ci## Using Default Component Animation 8e41f4b71Sopenharmony_ci 9e41f4b71Sopenharmony_ciThe default animation of a component exhibits the following features: 10e41f4b71Sopenharmony_ci 11e41f4b71Sopenharmony_ci- Indicate the current state of the component. For example, after the user clicks a **Button** component, the component turns gray, indicating that it is selected. 12e41f4b71Sopenharmony_ci 13e41f4b71Sopenharmony_ci- Make UI interactions more intuitive and pleasurable. 14e41f4b71Sopenharmony_ci 15e41f4b71Sopenharmony_ci- Reduce development workload, as the APIs are readily available. 16e41f4b71Sopenharmony_ci 17e41f4b71Sopenharmony_ciFor more effects, see [Component Overview](../reference/apis-arkui/arkui-ts/ts-container-flex.md). 18e41f4b71Sopenharmony_ci 19e41f4b71Sopenharmony_ciBelow is the sample code and effect: 20e41f4b71Sopenharmony_ci 21e41f4b71Sopenharmony_ci 22e41f4b71Sopenharmony_ci```ts 23e41f4b71Sopenharmony_ci@Entry 24e41f4b71Sopenharmony_ci@Component 25e41f4b71Sopenharmony_cistruct ComponentDemo { 26e41f4b71Sopenharmony_ci build() { 27e41f4b71Sopenharmony_ci Row() { 28e41f4b71Sopenharmony_ci Checkbox({ name: 'checkbox1', group: 'checkboxGroup' }) 29e41f4b71Sopenharmony_ci .select(true) 30e41f4b71Sopenharmony_ci .shape(CheckBoxShape.CIRCLE) 31e41f4b71Sopenharmony_ci .size({ width: 50, height: 50 }) 32e41f4b71Sopenharmony_ci } 33e41f4b71Sopenharmony_ci .width('100%') 34e41f4b71Sopenharmony_ci .height('100%') 35e41f4b71Sopenharmony_ci .justifyContent(FlexAlign.Center) 36e41f4b71Sopenharmony_ci } 37e41f4b71Sopenharmony_ci} 38e41f4b71Sopenharmony_ci``` 39e41f4b71Sopenharmony_ci 40e41f4b71Sopenharmony_ci 41e41f4b71Sopenharmony_ci 42e41f4b71Sopenharmony_ci 43e41f4b71Sopenharmony_ci 44e41f4b71Sopenharmony_ci## Customizing Component Animation 45e41f4b71Sopenharmony_ci 46e41f4b71Sopenharmony_ciSome components allow for animation customization for their child components through the [property animation](arkts-attribute-animation-overview.md) and [transition animation](arkts-transition-overview.md) APIs. For example, you can customize the swipe animation for child components of [Scroll](../reference/apis-arkui/arkui-ts/ts-container-scroll.md). 47e41f4b71Sopenharmony_ci 48e41f4b71Sopenharmony_ci- For a scroll or click gesture, you can implement various effects by changing affine properties of the child component. 49e41f4b71Sopenharmony_ci 50e41f4b71Sopenharmony_ci- To customize the animation for a scroll , you can add a listener to listen for scroll distance in the **onScroll** callback and calculate the affine property of each component. You can also define gestures, monitor positions through the gestures, and manually call **ScrollTo** to change the scrolled-to position. 51e41f4b71Sopenharmony_ci 52e41f4b71Sopenharmony_ci- Fine-tune the final scrolled-to position in the **onScrollStop** callback or gesture end callback. 53e41f4b71Sopenharmony_ci 54e41f4b71Sopenharmony_ciThe following is an example of customizing the swipe animation for the **Scroll** component: 55e41f4b71Sopenharmony_ci 56e41f4b71Sopenharmony_ci 57e41f4b71Sopenharmony_ci```ts 58e41f4b71Sopenharmony_ciimport { curves, window, display, mediaquery } from '@kit.ArkUI'; 59e41f4b71Sopenharmony_ciimport { UIAbility } from '@kit.AbilityKit'; 60e41f4b71Sopenharmony_ci 61e41f4b71Sopenharmony_ciexport default class GlobalContext extends AppStorage{ 62e41f4b71Sopenharmony_ci static mainWin: window.Window|undefined = undefined; 63e41f4b71Sopenharmony_ci static mainWindowSize:window.Size|undefined = undefined; 64e41f4b71Sopenharmony_ci} 65e41f4b71Sopenharmony_ci/** 66e41f4b71Sopenharmony_ci * Encapsulates the WindowManager class. 67e41f4b71Sopenharmony_ci */ 68e41f4b71Sopenharmony_ciexport class WindowManager { 69e41f4b71Sopenharmony_ci private static instance: WindowManager|null = null; 70e41f4b71Sopenharmony_ci private displayInfo: display.Display|null = null; 71e41f4b71Sopenharmony_ci private orientationListener = mediaquery.matchMediaSync('(orientation: landscape)'); 72e41f4b71Sopenharmony_ci 73e41f4b71Sopenharmony_ci constructor() { 74e41f4b71Sopenharmony_ci this.orientationListener.on('change', (mediaQueryResult: mediaquery.MediaQueryResult) => { this.onPortrait(mediaQueryResult) }) 75e41f4b71Sopenharmony_ci this.loadDisplayInfo() 76e41f4b71Sopenharmony_ci } 77e41f4b71Sopenharmony_ci 78e41f4b71Sopenharmony_ci /** 79e41f4b71Sopenharmony_ci * Sets the main window. 80e41f4b71Sopenharmony_ci * @param win Indicates the current application window. 81e41f4b71Sopenharmony_ci */ 82e41f4b71Sopenharmony_ci setMainWin(win: window.Window) { 83e41f4b71Sopenharmony_ci if (win == null) { 84e41f4b71Sopenharmony_ci return 85e41f4b71Sopenharmony_ci } 86e41f4b71Sopenharmony_ci GlobalContext.mainWin = win; 87e41f4b71Sopenharmony_ci win.on("windowSizeChange", (data: window.Size) => { 88e41f4b71Sopenharmony_ci if (GlobalContext.mainWindowSize == undefined || GlobalContext.mainWindowSize == null) { 89e41f4b71Sopenharmony_ci GlobalContext.mainWindowSize = data; 90e41f4b71Sopenharmony_ci } else { 91e41f4b71Sopenharmony_ci if (GlobalContext.mainWindowSize.width == data.width && GlobalContext.mainWindowSize.height == data.height) { 92e41f4b71Sopenharmony_ci return 93e41f4b71Sopenharmony_ci } 94e41f4b71Sopenharmony_ci GlobalContext.mainWindowSize = data; 95e41f4b71Sopenharmony_ci } 96e41f4b71Sopenharmony_ci 97e41f4b71Sopenharmony_ci let winWidth = this.getMainWindowWidth(); 98e41f4b71Sopenharmony_ci AppStorage.setOrCreate<number>('mainWinWidth', winWidth) 99e41f4b71Sopenharmony_ci let winHeight = this.getMainWindowHeight(); 100e41f4b71Sopenharmony_ci AppStorage.setOrCreate<number>('mainWinHeight', winHeight) 101e41f4b71Sopenharmony_ci let context:UIAbility = new UIAbility() 102e41f4b71Sopenharmony_ci context.context.eventHub.emit("windowSizeChange", winWidth, winHeight) 103e41f4b71Sopenharmony_ci }) 104e41f4b71Sopenharmony_ci } 105e41f4b71Sopenharmony_ci 106e41f4b71Sopenharmony_ci static getInstance(): WindowManager { 107e41f4b71Sopenharmony_ci if (WindowManager.instance == null) { 108e41f4b71Sopenharmony_ci WindowManager.instance = new WindowManager(); 109e41f4b71Sopenharmony_ci } 110e41f4b71Sopenharmony_ci return WindowManager.instance 111e41f4b71Sopenharmony_ci } 112e41f4b71Sopenharmony_ci 113e41f4b71Sopenharmony_ci private onPortrait(mediaQueryResult: mediaquery.MediaQueryResult) { 114e41f4b71Sopenharmony_ci if (mediaQueryResult.matches == AppStorage.get<boolean>('isLandscape')) { 115e41f4b71Sopenharmony_ci return 116e41f4b71Sopenharmony_ci } 117e41f4b71Sopenharmony_ci AppStorage.setOrCreate<boolean>('isLandscape', mediaQueryResult.matches) 118e41f4b71Sopenharmony_ci this.loadDisplayInfo() 119e41f4b71Sopenharmony_ci } 120e41f4b71Sopenharmony_ci 121e41f4b71Sopenharmony_ci /** 122e41f4b71Sopenharmony_ci * Changes the screen orientation. 123e41f4b71Sopenharmony_ci * @param ori Indicates the orientation. 124e41f4b71Sopenharmony_ci */ 125e41f4b71Sopenharmony_ci changeOrientation(ori: window.Orientation) { 126e41f4b71Sopenharmony_ci if (GlobalContext.mainWin != null) { 127e41f4b71Sopenharmony_ci GlobalContext.mainWin.setPreferredOrientation(ori) 128e41f4b71Sopenharmony_ci } 129e41f4b71Sopenharmony_ci } 130e41f4b71Sopenharmony_ci 131e41f4b71Sopenharmony_ci private loadDisplayInfo() { 132e41f4b71Sopenharmony_ci this.displayInfo = display.getDefaultDisplaySync() 133e41f4b71Sopenharmony_ci AppStorage.setOrCreate<number>('displayWidth', this.getDisplayWidth()) 134e41f4b71Sopenharmony_ci AppStorage.setOrCreate<number>('displayHeight', this.getDisplayHeight()) 135e41f4b71Sopenharmony_ci } 136e41f4b71Sopenharmony_ci 137e41f4b71Sopenharmony_ci /** 138e41f4b71Sopenharmony_ci * Obtains the width of the main window, in vp. 139e41f4b71Sopenharmony_ci */ 140e41f4b71Sopenharmony_ci getMainWindowWidth(): number { 141e41f4b71Sopenharmony_ci return GlobalContext.mainWindowSize != null ? px2vp(GlobalContext.mainWindowSize.width) : 0 142e41f4b71Sopenharmony_ci } 143e41f4b71Sopenharmony_ci 144e41f4b71Sopenharmony_ci /** 145e41f4b71Sopenharmony_ci * Obtains the height of the main window, in vp. 146e41f4b71Sopenharmony_ci */ 147e41f4b71Sopenharmony_ci getMainWindowHeight(): number { 148e41f4b71Sopenharmony_ci return GlobalContext.mainWindowSize != null ? px2vp(GlobalContext.mainWindowSize.height) : 0 149e41f4b71Sopenharmony_ci } 150e41f4b71Sopenharmony_ci 151e41f4b71Sopenharmony_ci /** 152e41f4b71Sopenharmony_ci * Obtains the screen width, in vp. 153e41f4b71Sopenharmony_ci */ 154e41f4b71Sopenharmony_ci getDisplayWidth(): number { 155e41f4b71Sopenharmony_ci return this.displayInfo != null ? px2vp(this.displayInfo.width) : 0 156e41f4b71Sopenharmony_ci } 157e41f4b71Sopenharmony_ci 158e41f4b71Sopenharmony_ci /** 159e41f4b71Sopenharmony_ci * Obtains the screen height, in vp. 160e41f4b71Sopenharmony_ci */ 161e41f4b71Sopenharmony_ci getDisplayHeight(): number { 162e41f4b71Sopenharmony_ci return this.displayInfo != null ? px2vp(this.displayInfo.height) : 0 163e41f4b71Sopenharmony_ci } 164e41f4b71Sopenharmony_ci 165e41f4b71Sopenharmony_ci /** 166e41f4b71Sopenharmony_ci * Releases resources. 167e41f4b71Sopenharmony_ci */ 168e41f4b71Sopenharmony_ci release() { 169e41f4b71Sopenharmony_ci if (this.orientationListener) { 170e41f4b71Sopenharmony_ci this.orientationListener.off('change', (mediaQueryResult: mediaquery.MediaQueryResult) => { this.onPortrait(mediaQueryResult)}) 171e41f4b71Sopenharmony_ci } 172e41f4b71Sopenharmony_ci if (GlobalContext.mainWin != null) { 173e41f4b71Sopenharmony_ci GlobalContext.mainWin.off('windowSizeChange') 174e41f4b71Sopenharmony_ci } 175e41f4b71Sopenharmony_ci WindowManager.instance = null; 176e41f4b71Sopenharmony_ci } 177e41f4b71Sopenharmony_ci} 178e41f4b71Sopenharmony_ci 179e41f4b71Sopenharmony_ci/** 180e41f4b71Sopenharmony_ci * Encapsulates the TaskData class. 181e41f4b71Sopenharmony_ci */ 182e41f4b71Sopenharmony_ciexport class TaskData { 183e41f4b71Sopenharmony_ci bgColor: Color | string | Resource = Color.White; 184e41f4b71Sopenharmony_ci index: number = 0; 185e41f4b71Sopenharmony_ci taskInfo: string = 'music'; 186e41f4b71Sopenharmony_ci 187e41f4b71Sopenharmony_ci constructor(bgColor: Color | string | Resource, index: number, taskInfo: string) { 188e41f4b71Sopenharmony_ci this.bgColor = bgColor; 189e41f4b71Sopenharmony_ci this.index = index; 190e41f4b71Sopenharmony_ci this.taskInfo = taskInfo; 191e41f4b71Sopenharmony_ci } 192e41f4b71Sopenharmony_ci} 193e41f4b71Sopenharmony_ci 194e41f4b71Sopenharmony_ciexport const taskDataArr: Array<TaskData> = 195e41f4b71Sopenharmony_ci [ 196e41f4b71Sopenharmony_ci new TaskData('#317AF7', 0, 'music'), 197e41f4b71Sopenharmony_ci new TaskData('#D94838', 1, 'mall'), 198e41f4b71Sopenharmony_ci new TaskData('#DB6B42 ', 2, 'photos'), 199e41f4b71Sopenharmony_ci new TaskData('#5BA854', 3, 'setting'), 200e41f4b71Sopenharmony_ci new TaskData('#317AF7', 4, 'call'), 201e41f4b71Sopenharmony_ci new TaskData('#D94838', 5, 'music'), 202e41f4b71Sopenharmony_ci new TaskData('#DB6B42', 6, 'mall'), 203e41f4b71Sopenharmony_ci new TaskData('#5BA854', 7, 'photos'), 204e41f4b71Sopenharmony_ci new TaskData('#D94838', 8, 'setting'), 205e41f4b71Sopenharmony_ci new TaskData('#DB6B42', 9, 'call'), 206e41f4b71Sopenharmony_ci new TaskData('#5BA854', 10, 'music') 207e41f4b71Sopenharmony_ci 208e41f4b71Sopenharmony_ci ]; 209e41f4b71Sopenharmony_ci 210e41f4b71Sopenharmony_ci@Entry 211e41f4b71Sopenharmony_ci@Component 212e41f4b71Sopenharmony_ciexport struct TaskSwitchMainPage { 213e41f4b71Sopenharmony_ci displayWidth: number = WindowManager.getInstance().getDisplayWidth(); 214e41f4b71Sopenharmony_ci scroller: Scroller = new Scroller(); 215e41f4b71Sopenharmony_ci cardSpace: number = 0; // Widget spacing 216e41f4b71Sopenharmony_ci cardWidth: number = this.displayWidth / 2 - this.cardSpace / 2; // Widget width 217e41f4b71Sopenharmony_ci cardHeight: number = 400; // Widget height 218e41f4b71Sopenharmony_ci cardPosition: Array<number> = []; // Initial position of the widget 219e41f4b71Sopenharmony_ci clickIndex: boolean = false; 220e41f4b71Sopenharmony_ci @State taskViewOffsetX: number = 0; 221e41f4b71Sopenharmony_ci @State cardOffset: number = this.displayWidth / 4; 222e41f4b71Sopenharmony_ci lastCardOffset: number = this.cardOffset; 223e41f4b71Sopenharmony_ci startTime: number|undefined=undefined 224e41f4b71Sopenharmony_ci 225e41f4b71Sopenharmony_ci // Initial position of each widget 226e41f4b71Sopenharmony_ci aboutToAppear() { 227e41f4b71Sopenharmony_ci for (let i = 0; i < taskDataArr.length; i++) { 228e41f4b71Sopenharmony_ci this.cardPosition[i] = i * (this.cardWidth + this.cardSpace); 229e41f4b71Sopenharmony_ci } 230e41f4b71Sopenharmony_ci } 231e41f4b71Sopenharmony_ci 232e41f4b71Sopenharmony_ci // Position of each widget 233e41f4b71Sopenharmony_ci getProgress(index: number): number { 234e41f4b71Sopenharmony_ci let progress = (this.cardOffset + this.cardPosition[index] - this.taskViewOffsetX + this.cardWidth / 2) / this.displayWidth; 235e41f4b71Sopenharmony_ci return progress 236e41f4b71Sopenharmony_ci } 237e41f4b71Sopenharmony_ci 238e41f4b71Sopenharmony_ci build() { 239e41f4b71Sopenharmony_ci Stack({ alignContent: Alignment.Bottom }) { 240e41f4b71Sopenharmony_ci // Background 241e41f4b71Sopenharmony_ci Column() 242e41f4b71Sopenharmony_ci .width('100%') 243e41f4b71Sopenharmony_ci .height('100%') 244e41f4b71Sopenharmony_ci .backgroundColor(0xF0F0F0) 245e41f4b71Sopenharmony_ci 246e41f4b71Sopenharmony_ci // <Scroll> component 247e41f4b71Sopenharmony_ci Scroll(this.scroller) { 248e41f4b71Sopenharmony_ci Row({ space: this.cardSpace }) { 249e41f4b71Sopenharmony_ci ForEach(taskDataArr, (item:TaskData, index) => { 250e41f4b71Sopenharmony_ci Column() 251e41f4b71Sopenharmony_ci .width(this.cardWidth) 252e41f4b71Sopenharmony_ci .height(this.cardHeight) 253e41f4b71Sopenharmony_ci .backgroundColor(item.bgColor) 254e41f4b71Sopenharmony_ci .borderStyle(BorderStyle.Solid) 255e41f4b71Sopenharmony_ci .borderWidth(1) 256e41f4b71Sopenharmony_ci .borderColor(0xAFEEEE) 257e41f4b71Sopenharmony_ci .borderRadius(15) 258e41f4b71Sopenharmony_ci // Calculate the affine properties of child components. 259e41f4b71Sopenharmony_ci .scale((this.getProgress(index) >= 0.4 && this.getProgress(index) <= 0.6) ? 260e41f4b71Sopenharmony_ci { 261e41f4b71Sopenharmony_ci x: 1.1 - Math.abs(0.5 - this.getProgress(index)), 262e41f4b71Sopenharmony_ci y: 1.1 - Math.abs(0.5 - this.getProgress(index)) 263e41f4b71Sopenharmony_ci } : 264e41f4b71Sopenharmony_ci { x: 1, y: 1 }) 265e41f4b71Sopenharmony_ci .animation({ curve: Curve.Smooth }) 266e41f4b71Sopenharmony_ci // Apply a pan animation. 267e41f4b71Sopenharmony_ci .translate({ x: this.cardOffset }) 268e41f4b71Sopenharmony_ci .animation({ curve: curves.springMotion() }) 269e41f4b71Sopenharmony_ci .zIndex((this.getProgress(index) >= 0.4 && this.getProgress(index) <= 0.6) ? 2 : 1) 270e41f4b71Sopenharmony_ci }, (item:TaskData) => item.toString()) 271e41f4b71Sopenharmony_ci } 272e41f4b71Sopenharmony_ci .width((this.cardWidth + this.cardSpace) * (taskDataArr.length + 1)) 273e41f4b71Sopenharmony_ci .height('100%') 274e41f4b71Sopenharmony_ci } 275e41f4b71Sopenharmony_ci .gesture( 276e41f4b71Sopenharmony_ci GestureGroup(GestureMode.Parallel, 277e41f4b71Sopenharmony_ci PanGesture({ direction: PanDirection.Horizontal, distance: 5 }) 278e41f4b71Sopenharmony_ci .onActionStart((event: GestureEvent|undefined) => { 279e41f4b71Sopenharmony_ci if(event){ 280e41f4b71Sopenharmony_ci this.startTime = event.timestamp; 281e41f4b71Sopenharmony_ci } 282e41f4b71Sopenharmony_ci }) 283e41f4b71Sopenharmony_ci .onActionUpdate((event: GestureEvent|undefined) => { 284e41f4b71Sopenharmony_ci if(event){ 285e41f4b71Sopenharmony_ci this.cardOffset = this.lastCardOffset + event.offsetX; 286e41f4b71Sopenharmony_ci } 287e41f4b71Sopenharmony_ci }) 288e41f4b71Sopenharmony_ci .onActionEnd((event: GestureEvent|undefined) => { 289e41f4b71Sopenharmony_ci if(event){ 290e41f4b71Sopenharmony_ci let time = 0 291e41f4b71Sopenharmony_ci if(this.startTime){ 292e41f4b71Sopenharmony_ci time = event.timestamp - this.startTime; 293e41f4b71Sopenharmony_ci } 294e41f4b71Sopenharmony_ci let speed = event.offsetX / (time / 1000000000); 295e41f4b71Sopenharmony_ci let moveX = Math.pow(speed, 2) / 7000 * (speed > 0 ? 1 : -1); 296e41f4b71Sopenharmony_ci 297e41f4b71Sopenharmony_ci this.cardOffset += moveX; 298e41f4b71Sopenharmony_ci // When panning left to a position beyond the rightmost position 299e41f4b71Sopenharmony_ci let cardOffsetMax = -(taskDataArr.length - 1) * (this.displayWidth / 2); 300e41f4b71Sopenharmony_ci if (this.cardOffset < cardOffsetMax) { 301e41f4b71Sopenharmony_ci this.cardOffset = cardOffsetMax; 302e41f4b71Sopenharmony_ci } 303e41f4b71Sopenharmony_ci // When panning right to a position beyond the rightmost position 304e41f4b71Sopenharmony_ci if (this.cardOffset > this.displayWidth / 4) { 305e41f4b71Sopenharmony_ci this.cardOffset = this.displayWidth / 4; 306e41f4b71Sopenharmony_ci } 307e41f4b71Sopenharmony_ci 308e41f4b71Sopenharmony_ci // Processing when the pan distance is less than the minimum distance 309e41f4b71Sopenharmony_ci let remainMargin = this.cardOffset % (this.displayWidth / 2); 310e41f4b71Sopenharmony_ci if (remainMargin < 0) { 311e41f4b71Sopenharmony_ci remainMargin = this.cardOffset % (this.displayWidth / 2) + this.displayWidth / 2; 312e41f4b71Sopenharmony_ci } 313e41f4b71Sopenharmony_ci if (remainMargin <= this.displayWidth / 4) { 314e41f4b71Sopenharmony_ci this.cardOffset += this.displayWidth / 4 - remainMargin; 315e41f4b71Sopenharmony_ci } else { 316e41f4b71Sopenharmony_ci this.cardOffset -= this.displayWidth / 4 - (this.displayWidth / 2 - remainMargin); 317e41f4b71Sopenharmony_ci } 318e41f4b71Sopenharmony_ci 319e41f4b71Sopenharmony_ci // Record the pan offset. 320e41f4b71Sopenharmony_ci this.lastCardOffset = this.cardOffset; 321e41f4b71Sopenharmony_ci } 322e41f4b71Sopenharmony_ci }) 323e41f4b71Sopenharmony_ci ), GestureMask.IgnoreInternal) 324e41f4b71Sopenharmony_ci .scrollable(ScrollDirection.Horizontal) 325e41f4b71Sopenharmony_ci .scrollBar(BarState.Off) 326e41f4b71Sopenharmony_ci 327e41f4b71Sopenharmony_ci // Move to the beginning and end positions. 328e41f4b71Sopenharmony_ci Button('Move to first/last') 329e41f4b71Sopenharmony_ci .backgroundColor(0x888888) 330e41f4b71Sopenharmony_ci .margin({ bottom: 30 }) 331e41f4b71Sopenharmony_ci .onClick(() => { 332e41f4b71Sopenharmony_ci this.clickIndex = !this.clickIndex; 333e41f4b71Sopenharmony_ci 334e41f4b71Sopenharmony_ci if (this.clickIndex) { 335e41f4b71Sopenharmony_ci this.cardOffset = this.displayWidth / 4; 336e41f4b71Sopenharmony_ci } else { 337e41f4b71Sopenharmony_ci this.cardOffset = this.displayWidth / 4 - (taskDataArr.length - 1) * this.displayWidth / 2; 338e41f4b71Sopenharmony_ci } 339e41f4b71Sopenharmony_ci this.lastCardOffset = this.cardOffset; 340e41f4b71Sopenharmony_ci }) 341e41f4b71Sopenharmony_ci } 342e41f4b71Sopenharmony_ci .width('100%') 343e41f4b71Sopenharmony_ci .height('100%') 344e41f4b71Sopenharmony_ci } 345e41f4b71Sopenharmony_ci} 346e41f4b71Sopenharmony_ci``` 347e41f4b71Sopenharmony_ci 348e41f4b71Sopenharmony_ci 349