主题
无缝向上滚动组件
seamless-scroll.vue
jsx
<template>
<view class="scroll-container" :style="{height: height + 'px'}">
<view class="scroll-content" :style="{transform: 'translateY(-' + translateY + 'px)'}" ref="contentRef">
<slot></slot>
</view>
</view>
</template>
<script setup>
import {
ref,
onMounted,
onUnmounted,
} from 'vue';
const props = defineProps({
height: {
type: Number,
default: 400,
},
speed: {
type: Number,
default: 100,
}
});
const translateY = ref(0); // Y轴位移
let contentRef = ref(null);
let contentHeight = 0;
let previousTime = null;
onMounted(() => {
contentHeight = contentRef.value.$el.scrollHeight;
startScroll();
});
onUnmounted(() => {
cancelAnimationFrame(rafId);
});
let rafId;
function startScroll() {
function animateScroll(timestamp) {
if (!previousTime) {
previousTime = timestamp;
}
const elapsedTime = timestamp - previousTime;
if (elapsedTime > 1000 / props.speed) {
translateY.value += 1;
if (translateY.value >= contentHeight - props.height) {
translateY.value = 0;
}
previousTime = timestamp;
}
rafId = requestAnimationFrame(animateScroll);
}
rafId = requestAnimationFrame(animateScroll);
}
</script>
<style scoped>
.scroll-container {
overflow: hidden;
}
</style>
jsx
<template>
<view class="scroll-container" :style="{height: height + 'px'}">
<view class="scroll-content" :style="{transform: 'translateY(-' + translateY + 'px)'}" ref="contentRef">
<slot></slot>
</view>
</view>
</template>
<script setup>
import {
ref,
onMounted,
nextTick
} from 'vue';
const props = defineProps({
height: {
type: Number,
default: 200,
},
speed: {
type: Number,
default: 150,
}
})
// 容器高度
const translateY = ref(0); // Y轴位移
const items = ref([]); // 列表项
let contentRef = ref(null);
let contentHeight = 0;
onMounted(async () => {
await nextTick(); // 等待组件渲染完成
contentHeight = contentRef.value.$el.scrollHeight;
startScroll();
});
function startScroll() {
setInterval(() => {
translateY.value += 1;
if (translateY.value >= contentHeight - props.height) {
translateY.value = 0;
}
}, 1000 / props.speed);
}
</script>
<style scoped>
.scroll-container {
overflow: hidden;
}
.scroll-content {
animation: scrollAnimation infinite linear;
}
@keyframes scrollAnimation {
from {
transform: translateY(0);
}
to {
transform: translateY(-100%);
}
}
</style>
使用
jsx
<seamless-scroll :height="200" :speed="10">
<view v-for="(item, index) in items" :key="index" class="scroll-item h-100px">{{ item }}</view>
</seamless-scroll>