vue实现一张竖着的图片动画帧组件
组件代码
<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount } from 'vue'
const props = withDefaults(defineProps<{
url: string,
totalFrames: number,
animationDuration: number
}>(), {
url: () => (''),
animationDuration: () => (1)
})
let requestAnimationFrameId: number;
let currentFrame: number = 1;
const imgRef = ref<HTMLImageElement>();
let last: number = Date.now();
const translateY = ref(0);
const animation = () => {
requestAnimationFrameId = requestAnimationFrame(animation);
const now = Date.now();
const delta = now - last;
const interval = props.animationDuration * 1000 / props.totalFrames;
if (delta > interval) {
last = now - (delta % interval);
if (imgRef.value) {
const h = imgRef.value.clientHeight;
translateY.value = -(h / props.totalFrames) * currentFrame
}
currentFrame++;
if (currentFrame === props.totalFrames) {
currentFrame = 0;
}
}
};
onMounted(() => requestAnimationFrameId = requestAnimationFrame(animation));
onBeforeUnmount(() => cancelAnimationFrame(requestAnimationFrameId))
</script>
<template>
<div class="image">
<img ref="imgRef" :src="url" :style="{ 'transform': `translate(0, ${translateY}px)` }" />
</div>
</template>
<style scoped lang="scss">
.image {
width: 50px;
height: 50px;
display: inline-block;
overflow: hidden;
img {
object-fit: cover;
height: auto;
max-width: 100%;
}
}
</style>
使用
<FrameImage style="width:86px;height:86px" :url="{地址}" :totalFrames="10" :animationDuration="1.5"/>
<FrameImage style="width:80px;height:80px" :url="{地址}" :totalFrames="25" :animationDuration="2"/>