HarmonyOS Next系列之实现一个左右露出中间大两边小带缩放动画的轮播图(十二)

系列文章目录

HarmonyOS Next 系列之省市区弹窗选择器实现(一)
HarmonyOS Next 系列之验证码输入组件实现(二)
HarmonyOS Next 系列之底部标签栏TabBar实现(三)
HarmonyOS Next 系列之HTTP请求封装和Token持久化存储(四)
HarmonyOS Next 系列之从手机选择图片或拍照上传功能实现(五)
HarmonyOS Next 系列之可移动悬浮按钮实现(六)
HarmonyOS Next 系列之沉浸式状态实现的多种方式(七)
HarmonyOS Next系列之Echarts图表组件(折线图、柱状图、饼图等)实现(八)
HarmonyOS Next系列之地图组件(Map Kit)使用(九)
HarmonyOS Next系列之半圆环进度条实现(十)
HarmonyOS Next 系列之列表下拉刷新和触底加载更多数据实现(十一)
HarmonyOS Next系列之实现一个左右露出中间大两边小带缩放动画的轮播图(十二)


文章目录

  • 系列文章目录
  • 前言
  • 一、实现原理
  • 二、Swiper组件使用回顾
    • 1、入参
    • 2、常用属性
      • index
      • autoPlay
      • interval
      • loop
      • itemSpace
      • prevMargin
      • nextMargin
      • DotIndicator
    • 3.常用事件
      • onChange
    • 4、事件customContentTransition
      • SwiperContentAnimatedTransition内置属性:
      • SwiperContentTransitionProxy内置属性
    • 完整代码:


前言

HarmonyOS Next(基于API12)实现一个左右露出中间大两边小带缩放动画的轮播图。

请添加图片描述


一、实现原理

难点解析:通过轮播图自定义动画属性customContentTransition,在滑动切换页面过程中根据回调参数获取页面相对选中页的起始位置移动比例,动态设置图片缩放比例。

二、Swiper组件使用回顾

1、入参

唯一入参(controller?: SwiperController)轮播图控制器,通过控制器可以控制翻页

private swiperController: SwiperController = new SwiperController()
......
.....
//控制翻到下一页
 this.swiperController.showNext()

//控制翻到上一页
 this.swiperController.showPrevious()
 ......
 ......
 build{
   Swiper(this.swiperController) {
      ......
      ......
  }
}

2、常用属性

index

设置当前在容器中显示的子组件的索引值。支持$$双向绑定变量

autoPlay

设置子组件是否自动播放。默认false

interval

设置使用自动播放时播放的时间间隔,默认3000ms

loop

设置是否开启循环,也即播放最后一张完后会自动回到第一张。,默认true

itemSpace

设置子组件与子组件之间间隙,默认0,单位vp

prevMargin

设置前边距,用于露出前一项的一小部分,默认0,单位vp

nextMargin

设置后边距,用于露出后一项的一小部分,默认0,单位vp

DotIndicator

圆点指示器属性,继承自Indicator,constructor()构造器
eg:

Swiper(){}
 .indicator( // 设置圆点导航点样式
        new DotIndicator()
          .itemWidth(15)//圆点宽
          .itemHeight(15)//圆点高
          .selectedItemWidth(15)//选中圆点宽
          .selectedItemHeight(15)//选中圆点高
          .color(Color.Gray)//圆点颜色
          .selectedColor(Color.Blue)//选中圆点颜色
          )

3.常用事件

onChange

onChange(event: (index: number) => void)
当前显示的子组件索引变化时触发该事件,返回值为当前显示的子组件的索引值


通过上面属性很容易实现一个左右露出的轮播图
示例代码如下:

@Entry
@Component
struct Index {
  @State currentIndex: number = 0//当前显示索引
  controller: SwiperController = new SwiperController()//控制器
  //图片
  imageList: string[] = ['https://img0.baidu.com/it/u=891057047,2511666354&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=667',
    'https://img2.baidu.com/it/u=2162972920,3759823780&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=664',
    'https://img1.baidu.com/it/u=1377826580,1094847210&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=750',
    'https://img2.baidu.com/it/u=3233674257,3277114296&fm=253&fmt=auto&app=120&f=JPEG?w=667&h=500',
    'https://img0.baidu.com/it/u=3948329438,2482580265&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=1082'
  ]



  build() {
    Column() {
      Swiper(this.controller) {
        ForEach(this.imageList, (item: string, index: number) => {
          Image(item).draggable(false).height(200).borderRadius(10)
        }, (index: number) => index.toString())
      }
      .width('100%')
      .autoPlay(true)//自动播放
      .itemSpace(20)//每张图片之间间距
      .prevMargin(30)//前一张图片露出宽度
      .nextMargin(30)//后一张图片露出宽度
      .indicator(new DotIndicator().color(Color.Gray).selectedColor(Color.White)) //指示器样式
      .onChange((index:number) => {
        //切换图片监听
        this.currentIndex = index
      })

    }
    .width('100%')
    .height('100%')
    .padding({top:10})
  }
}


运行效果:
请添加图片描述


4、事件customContentTransition

customContentTransition(transition: SwiperContentAnimatedTransition)
自定义Swiper页面切换动画,也是本次实现切换缩放动画轮播图的关键事件,
在轮播滑动切换过程中,在视窗内(可视区域)所有页面逐帧触发回调

SwiperContentAnimatedTransition内置属性:

名称说明
timeoutSwiper自定义切换动画超时时间,默认0,单位ms
transition自定义切换动画具体内容,类型Callback < SwiperContentTransitionProxy>

SwiperContentTransitionProxy内置属性

名称说明
selectedIndex当前选中索引
index轮播图索引
positionindex页面相对于(selectedIndex对应页面的起始位置)的移动比例。
mainAxisLengthindex对应页面在主轴方向上的长度

说明:触发事件的条件是出现可视区域内的图片都会逐张触发,例如从索引为0图片切换到索引为1过程,0和1两张图片都会出现在可视区域内,所以2张图片都会触发该事件,该事件会随着移动比例变化而多次触发直到图片移出可视区域。
position:表示当前页面相对选中页面(selectedIndex对应页面)的移动比例,啥意思呢,通过打印数据来理解:

示例:

Swiper(this.controller) {
        ForEach(this.imageList, (item: string, index: number) => {
          Image(item).draggable(false).height(200).borderRadius(10)
        }, (index: number) => index.toString())
      }
      .width('100%')
      .autoPlay(false)//自动播放
      .indicator(new DotIndicator().color(Color.Gray).selectedColor(Color.White)) //指示器样式
      .onChange((index:number) => {
        //切换图片监听
        this.currentIndex = index
      })
      .customContentTransition({
        timeout:1000,
        //自定义动画
        transition:(proxy: SwiperContentTransitionProxy)=>{
         if(proxy.index===0){
         //打印第一张的position值变化情况
           console.log(proxy.position.toString(),'position')
         }
        }
      })

测试:
(1)从第一张切换到第二张过程(向左滑)观察第一张图片postition值变化:
请添加图片描述

在这里插入图片描述
可以看到这个过程 position值趋近0到-1变化,
在开始滑动那一刻,selectedIndex为0也即第一张自己,自己和自己初始位置移动比例为0,所以position开始值为0。
滑动完成那一刻,selectedIndex为1也即第二张图片,自己和下一张图片(selectedIndex为1图片)距离为图片本身宽度,这个比例为1,因为是往左滑动所以比例为负数也即-1。index在selectedIndedx左边为负数,右边为正数

(2)从第二张切换到第一张过程(向右滑)第一张图片postition值变化:
请添加图片描述

在这里插入图片描述
可以看到这个过程index为0(第一张图片)的 position值趋近-1到0变化,(也就是上一步逆过程)。

观察第二张情况:

(1)从第一张切换到第二张过程(向左滑)观察第二张图片postition值变化:
在这里插入图片描述
趋近从1到0变化过程

(2)从第二张切换到第一张过程(向右滑)第一张图片postition值变化:
在这里插入图片描述
趋近从0到1变化过程


总结:图片在最中间position=0,往两边趋近-1和1,左负右正,取绝对值就是形成1-0-1顺序。

我们想要实现的轮播图效果缩放比例刚好相反,中间图片缩放比例1,两边比较小假设0.8,形成图片缩放顺序0.8-1-0.8

很容易得出移动过程中图片缩放比例计算公式为: 1-0.2*Math.abs( position)

完整代码:

@Entry
@Component
struct Index {
  //图表实例
  @State currentIndex: number = 0
  controller: SwiperController = new SwiperController()
  imageList: string[] = [
    'https://img0.baidu.com/it/u=891057047,2511666354&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=667',
    'https://img2.baidu.com/it/u=2162972920,3759823780&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=664',
    'https://img1.baidu.com/it/u=1377826580,1094847210&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=750',
    'https://img2.baidu.com/it/u=3233674257,3277114296&fm=253&fmt=auto&app=120&f=JPEG?w=667&h=500',
    'https://img0.baidu.com/it/u=3948329438,2482580265&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=1082'
  ]
  @State scaleList: number[] = [] //所有图片缩放比
  @State imgMargin: number = 30 //左右图片露出宽度
  @State itemSpace: number = 25 //每张图表间距
  private scaleRatio = 0.75 //缩放系数,其他图片比例和最中间选中图片比例

  aboutToAppear(): void {
    this.scaleList = this.imageList.map((item: string, index: number) => {
      //初始化时候第二张和最后一张设置缩小,loop为true时候最后一张会在初始化的最左边显示
      return index === 1 || index === this.imageList.length - 1 ? this.scaleRatio : 1
    })
  }

  build() {
    Column() {
      Swiper(this.controller) {
        ForEach(this.imageList, (item: string, index: number) => {
          Image(item).draggable(false).height(300).scale({
            y: this.scaleList[index],
          }).borderRadius(10)
        }, (index: number) => index.toString())
      }
      .width('100%')
      .autoPlay(true)
      .index(this.currentIndex)
      .itemSpace(this.itemSpace)
      .prevMargin(this.imgMargin)
      .nextMargin(this.imgMargin)
      .indicator(new DotIndicator().color(Color.Gray).selectedColor(Color.White))
      .customContentTransition({//自定义动画
        timeout: 1000,
        transition: (proxy: SwiperContentTransitionProxy) => {
          let scale= 1 - Math.min(Math.max(Math.abs(proxy.position), 0), 1) * (1 - this.scaleRatio)
          this.scaleList[proxy.index] = scale

        }
      })
      .onChange((i) => this.currentIndex = i)

    }
    .width('100%')
    .height('100%')
    .padding({ top: 10 })
  }
}

运行效果:
请添加图片描述

说明:定义一个数组参数scaleList保存每张图片缩放比例,滑动过程通过动态计算更新对应图片缩放比例,首次渲染,两边缩小的图片分别对应第二张和最后一张,初始渲染需设置好2张缩放后的比例。为了itemSpace设置的精准性,这边只设置了图片y方向(高度)的缩放,在缩放比例不是很大情况下看不出图片变形。当然也可以根据实际需要设置x方向也缩放,设置完两张图片间隙会比 itemSpace大些因为图片宽度被缩放,往图片中心变小,间隙就变大。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/875224.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一种多策略改进小龙虾智能优化算法MSCOA 改进策略:种群混沌映射初始化+透镜成像反向学习+黄金正弦变异策略

一种多策略改进小龙虾智能优化算法MSCOA 改进策略&#xff1a;种群初始化精英反向透镜成像反向学习黄金正弦变异策略 文章目录 一、小龙虾COA基本原理二、改进策略2.1种群初始化 映射2.2 透镜成像反向学习2.3 黄金正弦变异策略 三、实验结果四、核心代码五、代码获取六、总结 一…

小型企业如何利用人工智能的生产力

尽管生产力低下是一个长期存在的问题&#xff0c;但最近严峻的经济逆风加剧了这一问题&#xff0c;企业清算数量同比增长了 19&#xff05;。 Xero 的报告《小企业生产力&#xff1a;趋势、影响和战略》反映了这些宏观经济变化&#xff0c;显示 2023 年新西兰小企业生产力与 …

SiC,GaN驱动优选驱动方案SiLM5350系列SiLM5350MDDCM-DG 带米勒钳位Clamp保护功能 单通道隔离栅极驱动器

SiLM5350MDDCM-DG是一款适用于IGBT、MOSFET的单通道 隔离门极驱动器&#xff0c;具有10A拉电流和10A灌电流驱动能 力。提供内部钳位功能&#xff0c;可单独控制 上升时间和下降时间。 在 SOP8 封 装 中 具 有 3000VRMS 隔 离 耐 压 &#xff08; 符 合 UL1577&#xff09;。 与…

抖音微信超火国庆节国旗头像生成源码

源码介绍&#xff1a; 抖音微信超火国庆节国旗头像生成源码&#xff0c;静态页前端生成速度超快&#xff01;源码直接上传到服务器即可使用。 1、打开地址后点击上传->选一张你喜欢的头像->然后点右边箭头符合选款式->最后点保存头像->按照提示 2、保存到手机即…

c/c++面试100道

1.一道笔试题解析_哔哩哔哩_bilibili P20&#xff1a;#define offsetof(TYPE, MEMBER) ((size_t)&((TYPE*)0)->MEMBER) 1、 offsetof 宏是 C 语言中用于计算结构体成员相对于结构体起始地址的偏移量的宏定义。这个宏的定义如下&#xff1a; #define offsetof(TYPE, …

macOS上谷歌浏览器的十大隐藏功能

谷歌浏览器&#xff08;Google Chrome&#xff09;在macOS上拥有一系列强大而隐蔽的特性&#xff0c;这些功能能显著提高您的浏览体验。从多设备同步到提升安全性和效率&#xff0c;这些被低估的功能等待着被发掘。我们将逐步探索这些功能&#xff0c;帮助您最大化利用谷歌浏览…

09-排序1 排序(C)

这一节&#xff0c;测试各类排序算法的运行速度&#xff08;没有基数排序&#xff08;桶&#xff09; 其实在实际学习中&#xff0c;还是有意义的 给定 n 个&#xff08;长整型范围内的&#xff09;整数&#xff0c;要求输出从小到大排序后的结果。 本题旨在测试各种不同的排序…

【代码随想录训练营第42期 Day57打卡 - 图论Part7 - Prim算法

一、Prim算法 Prim算法是一种贪心算法&#xff0c;用于求解加权无向图的最小生成树问题。其中&#xff0c;最小生成树是指一个边的子集&#xff0c;它连接图中的所有顶点&#xff0c;且边的总权重最小&#xff0c;并且没有形成环。 对于Prim算法的简单了解&#xff0c;这里推…

基于小程序的教学辅助微信小程序设计+ssm(lw+演示+源码+运行)

教学辅助微信小程序 摘 要 随着移动应用技术的发展&#xff0c;越来越多的学生借助于移动手机、电脑完成生活中的事务&#xff0c;许多的传统行业也更加重视与互联网的结合&#xff0c;由于学生学习的压力越来越大&#xff0c;教学辅助是一个非常不错的教育平台&#xff0c;对…

9.12-kubeadm方式安装k8s+基础命令的使用

一、安装环境 编号主机名称ip地址1k8s-master192.168.2.662k8s-node01192.168.2.773k8s-node02192.168.2.88 二、前期准备 1.设置免密登录 [rootk8s-master ~]# ssh-keygen[rootk8s-master ~]# ssh-copy-id root192.168.2.77[rootk8s-master ~]# ssh-copy-id root192.168.2.…

指令——计算机的语言(part 2)

目录 1.1 翻译并执行程序 1.1.1 编译器 1.1.2 汇编器 1.1.3 链接器 1.1.4 加载器 1.1.5 动态链接库 接上一篇文章: 指令——计算机的语言(part 1) 1.1 翻译并执行程序 程序翻译层次图如下: 首先高级语言比如说C&#xff0c;会被编译器编译成汇编语言&#xff0c;然后汇…

Python面试宝典第48题:找丑数

题目 我们把只包含质因子2、3和5的数称作丑数&#xff08;Ugly Number&#xff09;。比如&#xff1a;6、8都是丑数&#xff0c;但14不是&#xff0c;因为它包含质因子7。习惯上&#xff0c;我们把1当做是第一个丑数。求按从小到大的顺序的第n个丑数。 示例 1&#xff1a; 输入…

另类动态规划

前言&#xff1a;一开始我根本想不到这个题目是一个动态规划的题目&#xff0c;而且我一开始的初始状态还写错了 我还忘记了写算法题的基本步骤&#xff0c;先看数据范围&#xff0c;再考虑能不能用动态规划写 题目地址 #include <bits/stdc.h> using namespace std; #de…

3C电子胶黏剂在手机制造方面有哪些关键的应用

3C电子胶黏剂在手机制造方面有哪些关键的应用 3C电子胶黏剂在手机制造中扮演着至关重要的角色&#xff0c;其应用广泛且细致&#xff0c;覆盖了手机内部组件的多个层面&#xff0c;确保了设备的可靠性和性能。以下是电子胶在手机制造中的关键应用&#xff1a; 手机主板用胶&…

浏览器百科:网页存储篇-IndexedDB介绍(十)

1.引言 在现代网页开发中&#xff0c;数据存储需求日益增多和复杂&#xff0c;传统的客户端存储技术如localStorage和sessionStorage已难以满足大型数据的存储和管理需求。为了解决这一问题&#xff0c;HTML5 引入了 IndexedDB&#xff0c;在本篇《浏览器百科&#xff1a;网页…

网络学习-eNSP配置路由器

#PC1网关&#xff1a;192.168.1.254 #PC3网关&#xff1a;192.168.3.254 #PC4网关&#xff1a;192.168.4.254# 注&#xff1a;路由器接口必须配置不同网段IP地址 <Huawei>system-view Enter system view, return user view with CtrlZ. #给路由器两个接口配置IP地址 [Hua…

IBM中国研发中心撤出:挑战与机遇并存

IBM中国研发中心撤出&#xff1a;挑战与机遇并存 引言 近日&#xff0c;IBM宣布撤出在中国的两大研发中心的消息&#xff0c;引起了广泛关注。这一举动不仅对IBM自身的全球布局产生了影响&#xff0c;也在一定程度上反映了跨国公司在中国市场策略的调整。本文将探讨这一事件背…

keras和tensorflow可用的一组版本

目录 keras版本&#xff1a;3.5.0tensorflow&#xff1a;2.17.0之前的错误导包现在的正确导包 keras版本&#xff1a;3.5.0 tensorflow&#xff1a;2.17.0 之前的错误导包 其实也不是说错误&#xff0c;就是因为文件位置不对&#xff0c;所以VSCode总是有黄色波浪线&#xff0…

只出现一次的数II

只出现一次的数&#xff1a;力扣&#xff08;LeetCode&#xff09;-----只出现一次的数 题目描述 给你一个整数数组 nums &#xff0c;除某个元素仅出现 一次 外&#xff0c;其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。 示例 1&#xff1a; 输入&am…

C# WinForm:禁用Panel容器滚动条自动移动位置的功能

1.在WinForm项目中新建一个类&#xff1a; 2.类里面的内容&#xff0c;重写Panel的这个方法 3.编译后这个控件就出现在工具箱了 4.然后用这个新Panel控件就好了 5.完事大吉。