代码拉取完成,页面将自动刷新
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)
}
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。