1 Star 0 Fork 1

ohos/ArkUIComponentSample

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
InfiniteScroll.ets 4.07 KB
一键复制 编辑 原始数据 按行查看 历史
yeyinglong 提交于 2024-02-18 14:59 +08:00 . infiniteScroll randon height
import animator, { AnimatorResult } from '@ohos.animator';
@Observed
class ScrollData {
constructor(data:number) {
this.data = data
}
offset: number = 0;
height: number = 800;
data: number;
}
@Component
struct ScrollItem {
@ObjectLink item:ScrollData
build() {
Stack() {
Text(this.item.data.toString()).fontSize(100)
}
.backgroundColor(Color.Orange)
.borderWidth(2)
.height(this.item.height)
.width("100%")
.offset({y:this.item.offset})
}
}
@Component
@Entry
export struct InfiniteScroll {
@State arr: Array<ScrollData> = []
private panYOffset:number = 0
private selfHeight: number = 0
private scrollYAnimator: AnimatorResult | undefined = undefined
createScrollAnimator(start:number, velocity:number):AnimatorResult {
let friction = 0.7
let FRICTION_SCALE = -4.2
let response = Math.abs(2 * Math.PI / (-4.2 * friction))
let tmpStiffness = (2 * Math.PI / response);
let stiffness = tmpStiffness * tmpStiffness;
let damping = 4 * Math.PI / response;
let end = start + velocity / (friction * -FRICTION_SCALE)
let v = velocity / (end - start)
return animator.create({
duration: 2000,
easing: "interpolating-spring(" + v + ",1," + stiffness + "," + damping + ")",
delay: 0,
fill: "forwards",
direction: "normal",
iterations: 1,
begin: start,
end: end
})
}
onScrollOffset(offset: number) {
this.arr.forEach((value:ScrollData)=>{
value.offset += offset;
})
if (this.arr[0].offset > -this.selfHeight / 2) {
let data = new ScrollData(this.arr[0].data -1)
data.height = Math.round(Math.random() * 800 + 400)
data.offset = this.arr[0].offset - data.height
this.arr.unshift(data)
} else if (this.arr[0].offset + this.arr[0].height < -this.selfHeight / 2) {
this.arr.shift()
}
let last = this.arr[this.arr.length - 1];
if (last.offset + last.height < this.selfHeight * 3 / 2) {
let data = new ScrollData(last.data + 1)
data.height = Math.round(Math.random() * 800 + 400)
data.offset = last.offset + last.height;
this.arr.push(data)
} else if (last.offset > this.selfHeight * 3 / 2) {
this.arr.pop()
}
}
build() {
Stack() {
ForEach(this.arr, (item:ScrollData) => {
ScrollItem({item:item})
}, (item:ScrollData) => item.data.toString())
}
.alignContent(Alignment.Top)
.clip(true)
.height("100%")
.width("100%")
.backgroundColor(Color.Green)
.onTouch((event: TouchEvent)=>{
if (event.type == TouchType.Down) {
this.scrollYAnimator?.pause()
}
})
.gesture(
PanGesture()
.onActionStart((event?: GestureEvent) => {
this.panYOffset = 0
this.scrollYAnimator?.pause()
})
.onActionUpdate((event?: GestureEvent) => {
if (event) {
let dt = event.offsetY - this.panYOffset
this.onScrollOffset(dt)
this.panYOffset = event.offsetY
}
})
.onActionEnd((event: GestureEvent) => {
if (Math.abs(event.velocityY) > 10) {
this.panYOffset = 0
this.scrollYAnimator = this.createScrollAnimator(0, event.velocityY)
this.scrollYAnimator.onframe = (value: number) => {
let dt = value - this.panYOffset
this.onScrollOffset(dt)
this.panYOffset = value
}
this.scrollYAnimator.play()
}
}),
)
.onAreaChange((oldValue: Area, newValue: Area) => {
this.selfHeight = newValue.height as number
let offset = this.arr[1].offset - this.arr[0].height;
this.arr.forEach((value:ScrollData)=>{
value.offset = offset;
offset += value.height
})
})
}
aboutToAppear() {
for(let i = -1; i < 2; i++) {
let data = new ScrollData(i)
data.height = Math.round(Math.random() * 800 + 400)
this.arr.push(data)
}
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
TypeScript
1
https://gitee.com/yeyinglong/ark-uicomponent-sample.git
git@gitee.com:yeyinglong/ark-uicomponent-sample.git
yeyinglong
ark-uicomponent-sample
ArkUIComponentSample
master

搜索帮助