- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
在鸿蒙OS的广阔天地中,开发者们有机会创造出令人惊叹的用户体验。最近,我着手设计一款具有独特滑动效果的Swiper组件,它在滑动时能够迅速进入视野,同时巧妙地将旧的cell隐藏到视线之外。本文将分享如何利用鸿蒙的Swiper组件,实现这一引人入胜的动态效果.
Swiper的设计理念是简洁而富有动感。每个cell在滑动时不仅会逐渐缩小至原始大小的70%,还会被前一个cell覆盖,创造出一种流畅且连续的视觉效果。这种效果的实现,依赖于精确的动画控制和布局调整.
实现这一效果,我们需要对Swiper组件进行深度定制。这包括对cell的尺寸、位置和层级进行动态调整,以及利用贝塞尔曲线来实现平滑的动画效果.
Swiper组件提供了丰富的API,允许我们对其行为进行精细控制。以下是一些关键的配置项和它们的作用:
itemSpace
: 控制cell之间的间距。indicator
: 是否显示指示器。displayCount
: 设置同时展示的cell数量。onAreaChange
: 当Swiper区域大小变化时的回调。customContentTransition
: 自定义内容转换动画。Swiper组件基础配置代码:
Swiper()
.itemSpace(12)
.indicator(false)
.displayCount(this.DISPLAY_COUNT)
.padding({left:10, right:10})
.onAreaChange((oldValue, newValue) => {
// 处理区域变化逻辑
})
.customContentTransition({
transition: (proxy) => {
// 自定义转换逻辑
}
});
每个Item需要根据其在Swiper中的位置进行尺寸、位置和层级的调整。这涉及到初始化相关变量,并在aboutToAppear生命周期方法中进行设置.
初始化宽高,初始化组件数据:
@State cw: number = 0;
@State ch: number = 0;
aboutToAppear(): void {
initSwipe(...)
}
initSwipe(num:number){
this.translateList = []
for (let i = 0; i < num; i++) {
this.scaleList.push(0.8)
this.translateList.push(0.0)
this.zIndexList.push(0)
}
}
private MIN_SCALE: number = 0.70
private DISPLAY_COUNT: number = 4
private DISPLAY_WIDTH: number = 200
@State scaleList: number[] = []
@State translateList: number[] = []
@State zIndexList: number[] = []
Item尺寸和位置设置代码:
LifeStyleItem({lifeStyleResponse: item})
.scale({ x: this.scaleList[index], y: this.scaleList[index] })
.translate({ x: this.translateList[index] })
.zIndex(this.zIndexList[index]);
在 customContentTransition的transition 属性中设置属性:
//scaleList 需要进行线性变化
//translateList 位移需要进行 数据偏移处理和贝塞尔曲线处理
//zIndexList 需要进行位置层级设置
this.scaleList[proxy.index] = 线性函数
this.translateList[proxy.index] = - proxy.position * proxy.mainAxisLength + 贝塞尔曲线函数
this.zIndexList[proxy.index] = proxy.position
为了实现平滑的动画效果,我们定义了三次贝塞尔曲线函数和线性函数。这些函数将用于计算cell在滑动过程中的尺寸、位置和层级变化.
三次贝塞尔曲线函数:
function cubicBezier8(t, a1, b1, a2, b2) {
// 计算三次贝塞尔曲线的值
const k1 = 3 * a1;
const k2 = 3 * (a2 - b1) - k1;
const k3 = 1 - k1 - k2;
return k3 * Math.pow(t, 3) + k2 * Math.pow(t, 2) + k1 * t;
}
线性函数:
function chazhi(startPosition, endPosition, startValue, endValue, position) {
// 计算线性插值的结果
const range = endPosition - startPosition;
const positionDifference = position - startPosition;
const fraction = positionDifference / range;
const valueRange = endValue - startValue;
const result = startValue + (valueRange * fraction);
return result;
}
我们编写了计算函数来确定cell在Swiper中的最终表现。这包括根据位置计算尺寸、位置和层级.
计算尺寸和位置的函数:
function calculateValue(width: number, position: number): number {
const minValue = 0;
const normalizedPosition = position / 4;
// 计算贝塞尔曲线的缓动值
const easedPosition = cubicBezier(normalizedPosition, 0.3, 0.1, 1, 0.05);
// 根据缓动值计算最终的变化值
const value = minValue + (width - minValue) * easedPosition;
return value;
}
function calculateValueScale(position) {
if (position >= 2.5) {
// 当position大于2时,值固定为0.8
return 0.8;
} else if (position < 2.5) {
const startPosition = 2.5;
const endPosition = -1;
// 定义返回值的起始值和结束值
const startValue = 0.8;
const endValue = 0.7;
return chazhi(startPosition,endPosition,startValue,endValue,position)
}
return 0.7;
}
将上述所有代码片段整合到一个组件中,确保Swiper和每个Item都能够根据用户的滑动操作动态调整。 代码如下:
function calculateValue(width: number, position: number): number {
const minValue = 0;
const normalizedPosition = position / 4;
const easedPosition = cubicBezier8(normalizedPosition, 0.3, 0.1, 1, 0.05);
const value = minValue + (width - minValue) * easedPosition;
return value;
}
function cubicBezier(t: number, a1: number, b1: number, a2: number, b2: number): number {
const k1 = 3 * a1;
const k2 = 3 * (a2 - b1) - k1;
const k3 = 1 - k1 - k2;
return k3 * Math.pow(t, 3) + k2 * Math.pow(t, 2) + k1 * t;
}
function calculateValueScale(position: number): number {
if (position >= 2.5) {
return 0.8;
} else if (position < 2.5) {
const startPosition = 2.5;
const endPosition = -1;
const startValue = 0.8;
const endValue = 0.7;
return chazhi(startPosition,endPosition,startValue,endValue,position)
}
return 0.7;
}
function chazhi(startPosition:number,endPosition:number,startValue:number,endValue:number,position:number):number{
const range = endPosition - startPosition;
const positionDifference = position - startPosition;
const fraction = positionDifference / range;
const valueRange = endValue - startValue;
const result = startValue + (valueRange * fraction);
return result;
}
@Component
struct Banner {
@State cw: number = 0;
@State ch: number = 0;
aboutToAppear(): void {
initSwipe()
}
initSwipe(num:number){
this.translateList = []
for (let i = 0; i < num; i++) {
this.scaleList.push(0.8)
this.translateList.push(0.0)
this.zIndexList.push(0)
}
}
private MIN_SCALE: number = 0.70
private DISPLAY_COUNT: number = 4
private DISPLAY_WIDTH: number = 200
@State scaleList: number[] = []
@State translateList: number[] = []
@State zIndexList: number[] = []
build(){
Swiper() {
ForEach(this.lifeStyleList, (item: LifeStyleResponse|null,index) => {
LifeStyleItem({lifeStyleResponse:item})
.scale({ x: this.scaleList[index], y: this.scaleList[index] })
.translate({ x: this.translateList[index] })
.zIndex(this.zIndexList[index])
}
)
}
.itemSpace(12)
.indicator(false)
.displayCount(this.DISPLAY_COUNT)
.padding({left:10,right:10})
.onAreaChange((oldValue,newValue)=>{
this.cw = new Number(newValue.width).valueOf()
this.ch = new Number(newValue.height).valueOf()
})
.customContentTransition({
transition :(proxy: SwiperContentTransitionProxy)=>{
this.scaleList[proxy.index] = calculateValueScale(proxy.position)
this.translateList[proxy.index] = - proxy.position * proxy.mainAxisLength + calculateValue8(this.cw,proxy.position)
this.zIndexList[proxy.index] = proxy.position
}
})
}
通过本文的深入解析,我们不仅实现了一个具有个性化动态效果的Swiper组件,还学习了如何利用鸿蒙OS的强大API来定制动画和布局。希望这篇文章能够激发更多开发者的创造力,共同探索鸿蒙OS的无限可能.
最后此篇关于鸿蒙OS高级技巧:打造个性化动态Swiper效果的文章就讲到这里了,如果你想了解更多关于鸿蒙OS高级技巧:打造个性化动态Swiper效果的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我可以使用 javascript 和其他所有东西,但在重新发明轮子之前,我想知道是否已经有一个类似的 jquery 插件,因为我想使用那个框架而不是 mootools。 我没有钱的问题,特别是 5 欧
我正在 React 应用程序中处理动画。我需要动画在悬停 后开始工作。我尝试了 :hover:after css 但不起作用。将鼠标悬停在图像上后动画可以工作,但我需要在悬停后开始。将鼠标悬停在图像上
我正在使用 jQuery 在按钮单击时实现 slider 效果。我的代码是: $(document).ready(function() { $("#mybutton").click(functio
我需要一个div标签在屏幕右侧滑出,如何使用jQuery获得这种效果?我一直在看这里:http://api.jquery.com/category/effects/sliding/而且这似乎不是我要找
我正在使用此代码实现页面 curl 效果......它在模拟器和设备中工作正常......但它不是(setType:@“pageCurl”)苹果记录的api,这导致它被iPhone拒绝App Stor
我见过各种关于 WPF 效果的引用,但它们似乎是针对位图的,而不是针对文本的。是否可以将除模糊或投影以外的效果应用于XAML中的TextBlock对象? 我想要做的示例可能是轮廓笔划,或斜角/浮雕效果
我见过各种关于 WPF 效果的引用,但它们似乎是针对位图的,而不是针对文本的。是否可以将除模糊或投影以外的效果应用于XAML中的TextBlock对象? 我想要做的示例可能是轮廓笔划,或斜角/浮雕效果
我正在尝试模拟这种效果:http://meyerweb.com/eric/css/edge/complexspiral/demo.html在我的博客上:http://segment6.blogspot
我尝试将样式应用到 Accordion Pane ,但遇到了问题。 这行不通。 accordion.setEffect(new DropShadow(BlurType.ONE_PASS_BOX, Co
关于 Datatables website 的教程足够清楚了: 在我告诉 Datatables 我正在谈论哪一列后,我只需将切换按钮放入: column.visible( ! column.visib
我正在寻找 scratchOut 效果,随便叫它什么。 这是从前景中删除图像的效果,因此背景图像变得可见。 我曾尝试使用 jquery 插件重新创建此效果,但它并不像我希望的那样流畅。 有没有人有这种
本文实例讲述了android实现文字和图片混排(文字环绕图片)效果。分享给大家供大家参考,具体如下: 在平时我们做项目中,或许有要对一张图片或者某一个东西进行文字和图片说明,这时候要求排版美观,所
本文实例讲述了Javafx简单实现【我的电脑资源管理器】效果。分享给大家供大家参考。具体如下: 1. java代码: ?
我是 ngrx 的新手,正在尝试让我的 ngrx 商店的 @Effect 函数正常工作。下面的代码显示了如果我没有使用 ngrx 商店,服务是如何工作的。我首先调用 http.get 来获取列表,然后
基本上我搜索了很多,解决方案建议应用一些 PNG 掩码或不提供所需的解决方案。 我发现了什么。 ffmpeg -i main.mkv -i facecloseup.mkv -filter_compl
有关使用从商店中选择的状态的效果的 Ngrx 文档状态(没有双关语意) Note: For performance reasons, use a flattening operator like co
我有一个数据网格控件,我在其中使用名为 FastShadow 的自定义效果,它就像一个光晕。 我希望效果在其边界之外发光,这样很好,但是当我在顶部绘制另一个形状时,我不希望这个形状受到影响。在本例中,
除了子 div.exception 中的所有内容,我想将 div.main 中的所有文本设为灰色。 div.exception 应该看起来好像类 main 从未添加到父 div。 这可能吗?如果是这样
我有一个 PDF 文件,我想重现此包页面中的页面 curl 效果: https://pub.flutter-io.cn/packages/page_turn 我试过用这个 page_turn插件,它需
我想测试一个效果如下: 如果调度了 LoadEntriesSucces 操作,则效果开始 等待 5 秒 5 秒后发送 http 请求 当响应到达时,将分派(dispatch)新的操作(取决于响应是成功
我是一名优秀的程序员,十分优秀!