HarmonyOS 滑动缩放demo

HarmonyOS
3天前
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
FengTianYa
class MyDataSource implements IDataSource {
  private list: string[] = []

  constructor(list: string[]) {
    this.list = list
  }

  totalCount(): number {
    return this.list.length
  }

  getData(index: number): string {
    return this.list[index]
  }

  registerDataChangeListener(listener: DataChangeListener): void {
  }

  unregisterDataChangeListener() {
  }
}

const MAX_SCALE = 1 // 最大缩放
const MIN_SCALE = 0.75 // 最小缩放
// 可通过以下两个参数变化观察效果,然后优化
const PAGE_DURATION = 200 // 子控件动画时长
const SWIPER_DURATION = 300 // swiper组件切换动画时长
const DRAGGING_MAX_DISTANCE = 1000 // 拖动时用来计算缩放,影响拖动缩放速度,可根据屏幕尺寸来定

@Component
export struct SwiperPageOne {
  private swiperController: SwiperController = new SwiperController()
  private data: MyDataSource = new MyDataSource([])
  @State currentIndex: number = 0
  @State scaleArray: number[] = []; //缩放值
  startSwiperOffset: number = 0 //开始滑动距离
  private DISPLAY_COUNT: number = 1
  @State NextIndex: number = 0
  @State PreIndex: number = 0
  @State ImageArr: string[] = [
  ]
  @State swiperHeight: number = 200

  aboutToAppear(): void {
    let list: string[] = []
    for (let i = 0; i <= 5; i++) {
      list.push(this.ImageArr[i]);
      this.scaleArray.push(i == 0 ? MAX_SCALE : MIN_SCALE)
    }
    console.info('tag--' + JSON.stringify(this.scaleArray))
    this.data = new MyDataSource(list)
  }

  build() {
    Column() {
      Swiper(this.swiperController) {
        LazyForEach(this.data, (item: string, index: number) => {
          Column() {
            Image(item)
              .width('100%')
              .height('100%')
          }
          .padding({bottom:30})// 指示点区域
          .alignSelf(ItemAlign.Center)
          .width("100%")
          .height('100%')
          .scale({ x: this.scaleArray[index], y: this.scaleArray[index] })
          .animation({
            duration: PAGE_DURATION,
            curve: Curve.Linear
          })
        }, (item: string, index: number) => item)
      }
      .displayMode(SwiperDisplayMode.STRETCH)
      .displayCount(this.DISPLAY_COUNT)
      .width('100%')
      .height(this.swiperHeight)
      .index(this.currentIndex) //状态变量
      .cachedCount(2)
      .indicator(true)
      .autoPlay(false)
      .loop(false) //关闭循环
      .duration(SWIPER_DURATION)
      .itemSpace(0)
      .nextMargin(50)
      .prevMargin(50)
      .curve(Curve.Linear)

      .onChange((index) => {
        console.info('tagchangeIndex--' + index)
        this.currentIndex = index
        //设置当前index缩放值为最大值
        this.scaleArray[this.currentIndex] = MAX_SCALE;
        if (this.currentIndex == 0) {
          // 当前index=0时,设置上一张图片的缩放值
          this.scaleArray[this.scaleArray.length - 1] = MIN_SCALE
        } else if (this.currentIndex == this.scaleArray.length - 1) {
          // 当index为最后一张图片时,设置下一张图片的缩放值
          this.scaleArray[this.currentIndex -1] = MIN_SCALE
        } else {
          // 设置上一张图片的缩放值
          this.scaleArray[this.currentIndex + 1] = MIN_SCALE
        }
      })
      .customContentTransition({
        // 页面移除视窗时超时1000ms下渲染树
        timeout: 1000,
        // 对视窗内所有页面逐帧回调transition,在回调中修改opacity、scale、translate、zIndex等属性值,实现自定义动画
        transition: (proxy: SwiperContentTransitionProxy) => {
          if (this.startSwiperOffset == 0) {
            this.startSwiperOffset = proxy.position * proxy.mainAxisLength;
            console.info('tag-startSwiperOffset::' + this.startSwiperOffset)
          }
          console.info('tag-proxy-selectedIndex::' + proxy.selectedIndex + '--index::' + proxy.index +
            '--position::' + proxy.position + '--mainAxisLength::' + proxy.mainAxisLength)

          let offset: number = proxy.position * proxy.mainAxisLength //移动距离
          let currentScale: number = this.scaleArray[proxy.index] //当前index缩放值

          let nextIndex = (proxy.index == this.scaleArray.length - 2 ? 0 : proxy.index + 1) //计算下一个index
          let preIndex = (proxy.index == 0 ? this.scaleArray.length - 2 : proxy.index - 1) //计算上一个index

          let nextScale: number = this.scaleArray[nextIndex] //下一个index缩放值
          let preScale: number = this.scaleArray[preIndex] //上一个index缩放值
          // console.info('tag1 nextIndex::'+nextIndex+'---preIndex::'+preIndex + '-index::'+proxy.index)
          // console.info('tag1 nextScale::'+nextScale+'---preScale::'+preScale + '-currentScale::'+currentScale)
          // 滑动距离
          let distance = Math.abs(offset)
          currentScale = MAX_SCALE - Math.min(distance / DRAGGING_MAX_DISTANCE, MAX_SCALE - MIN_SCALE) //当前缩放值
          if (this.startSwiperOffset > offset) {
            nextScale = MIN_SCALE + Math.min(distance / DRAGGING_MAX_DISTANCE, MAX_SCALE - MIN_SCALE)
            preScale = MIN_SCALE
          } else {
            preScale = MIN_SCALE + Math.min(distance / DRAGGING_MAX_DISTANCE, MAX_SCALE - MIN_SCALE)
            nextScale = MIN_SCALE
          }
          this.scaleArray[this.currentIndex] = currentScale //当前index缩放值
          this.scaleArray[nextIndex] = nextScale //下一个index缩放值
          this.scaleArray[preIndex] = preScale //上一个index缩放值
        }
      })
    }

  }
}



import { SwiperPageOne } from '../pages/swiperPageOne'

@Entry
@Component
struct Index {
  build() {
    Column() {
      SwiperPageOne({ImageArr:[
        'xxxx',
        'xxxx',
        'xxxx',
        'xxxx',
        'xxxx',
        'xxxx',
      ],swiperHeight:350})
        .height(350)
    }
    .alignItems(HorizontalAlign.Center)
    .justifyContent(FlexAlign.Center)
    .height('100%')
    .width('100%')
  }
}
分享
微博
QQ
微信
回复
3天前
相关问题
HarmonyOS 希望提供滑动控件Demo
16浏览 • 1回复 待解决
HarmonyOS 首页金刚栏滑动demo
35浏览 • 1回复 待解决
HarmonyOS 缩放动画问题
62浏览 • 1回复 待解决
HarmonyOS如何实现动态缩放动画
572浏览 • 1回复 待解决
HarmonyOS Web组件内容缩放问题
433浏览 • 1回复 待解决
WebView支持页面缩放吗?
962浏览 • 1回复 待解决
解决Canvas画布缩放时闪烁
1528浏览 • 1回复 待解决
Web组件如何开启手势缩放
1687浏览 • 1回复 待解决
自适应缩放布局如何实现
503浏览 • 1回复 待解决
HarmonyOS h5页面缩放问题
595浏览 • 0回复 待解决
鸿蒙Drawing API的缩放怎么使用
820浏览 • 1回复 待解决
HarmonyOS 商城demo
15浏览 • 1回复 待解决