user_handbook/docs/.vuepress/components/longPicSplitV2.vue

102 lines
1.9 KiB
Vue
Raw Normal View History

2026-03-30 10:23:03 +08:00
<script setup>
import { ref, onMounted, computed } from 'vue'
const props = defineProps({
src: {
type: String,
required: true
},
alt: {
type: String,
default: '长图'
},
sliceHeight: {
type: Number,
default: 600
}
})
const imgLoaded = ref(false)
const naturalWidth = ref(0)
const naturalHeight = ref(0)
const containerWidth = ref(0)
const handleLoad = (e) => {
imgLoaded.value = true
naturalWidth.value = e.target.naturalWidth
naturalHeight.value = e.target.naturalHeight
}
const handleContainerResize = (el) => {
containerWidth.value = el.getBoundingClientRect().width
}
const slices = computed(() => {
if (!imgLoaded.value) return []
const count = Math.ceil(naturalHeight.value / props.sliceHeight)
const arr = []
for (let i = 0; i < count; i++) {
arr.push({
top: i * props.sliceHeight,
height: Math.min(props.sliceHeight, naturalHeight.value - i * props.sliceHeight)
})
}
return arr
})
</script>
<template>
<div
class="long-pic-img-split"
@resize="handleContainerResize($event.target)"
>
<!-- 用于获取尺寸 -->
<img
:src="src"
:alt="alt"
@load="handleLoad"
class="img-hidden"
>
<!-- 正常分段显示宽度100%不会被放大 -->
<img
v-for="(item, idx) in slices"
:key="idx"
:src="src"
:alt="`${alt}-${idx + 1}`"
class="split-img"
:style="{
height: `${item.height}px`,
objectPosition: `center ${-item.top}px`,
}"
/>
</div>
</template>
<style scoped>
.long-pic-img-split {
width: 100%;
max-width: 100%;
overflow: hidden;
margin: 10px 0;
}
.img-hidden {
position: absolute;
width: 100%;
opacity: 0;
pointer-events: none;
}
.split-img {
display: block;
width: 100% !important;
max-width: 100% !important;
object-fit: cover;
object-position: top center;
box-sizing: border-box;
margin: 0;
padding: 0;
}
</style>