146 lines
5.1 KiB
Vue
146 lines
5.1 KiB
Vue
<template lang="pug">
|
|
.flex.flex-col
|
|
// 上传图像按钮悬浮在右上角
|
|
.fixed.top-1.flex.flex-row.items-center.justify-center.h-16.px-4.bg-gray-100(
|
|
class="rounded-full left-3/4"
|
|
v-if="account.online"
|
|
)
|
|
.flex.flex-row.items-center.justify-center.gap-1
|
|
label.text-gray-500.text-sm.font-bold.px-2.py-1.bg-gray-200.rounded-md.cursor-pointer(
|
|
for="file"
|
|
) 上传图片
|
|
input#file.hidden(type="file", accept="image/*", multiple="multiple", @change="upload")
|
|
.flex-1.flex.flex-col.justify-center.items-center.text-center
|
|
.text-gray-500.text-sm.font-bold.px-2.py-1.bg-gray-200.rounded-md.cursor-pointer(
|
|
@click="refresh"
|
|
) 刷新
|
|
.relative.mt-24.transition-opacity.duration-700.ease-in-out(
|
|
ref="PUB",
|
|
v-if="!pending",
|
|
:class="{ 'opacity-100': !pending, 'opacity-10': pending }"
|
|
)
|
|
.absolute.transition-all.duration-700.ease-in-out.left-0.top-2000.bg-gray-100(
|
|
v-for="item in data.list" :key="item.image",
|
|
:data-w="item.width",
|
|
:data-h="item.height",
|
|
class="hover:bg-gray-200"
|
|
)
|
|
NuxtLink(:to="`/gallery/${item.id}`")
|
|
//img.w-full(:src="`${item.image}?w=${WIDTH}`" loading="lazy")
|
|
img.w-full(:src="item.image+'@w480.webp'" loading="lazy")
|
|
.absolute.top-0.left-0.right-0.text-white.overflow-hidden.break-words.pb-4(
|
|
style="background: linear-gradient(to top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.25))"
|
|
)
|
|
p.p-2 {{ item.width }} x {{ item.height }}
|
|
// 删除按钮
|
|
.absolute.top-0.right-0.flex.flex-row.items-center.justify-center.px-2.bg-gray-100(
|
|
class="rounded-full cursor-pointer opacity-0 transition-all ease-in-out duration-300 hover:opacity-100"
|
|
@click.stop="remove(item.id)"
|
|
v-if="account.online"
|
|
) 删除
|
|
RouterView
|
|
</template>
|
|
|
|
<script setup>
|
|
const { data, pending, refresh } = useFetch("/api/gallery?page=1&pageSize=40")
|
|
const PUB = ref(null)
|
|
const WIDTH = ref(320)
|
|
const account = useState('account')
|
|
|
|
const upload = async event => {
|
|
let body = new FormData()
|
|
for (let file of event.target.files) body.append("image", file)
|
|
await $fetch(`/api/gallery`, { method: "POST", body }).then(rest => {
|
|
data.value.list.unshift(...rest.list)
|
|
})
|
|
}
|
|
|
|
const remove = async id => {
|
|
await $fetch(`/api/gallery/${id}`, { method: "DELETE" }).then(rest => {
|
|
const index = data.value.list.findIndex(item => item.id === id)
|
|
if (index !== -1) data.value.list.splice(index, 1)
|
|
})
|
|
}
|
|
|
|
const 屏幕宽高重置 = () => {
|
|
let 容器宽度 = document.body.clientWidth
|
|
let 高分屏 = window.devicePixelRatio === 1 && 容器宽度 > 1280
|
|
let 列宽 = 高分屏 ? 480 : 320
|
|
let 间距 = 高分屏 ? 16 : 8
|
|
let 列数 = parseInt(容器宽度 / (列宽 + 间距)) || 1
|
|
let 边距 = (容器宽度 - 列数 * 列宽 - (列数 - 1) * 间距) / 2
|
|
let 各列高度 = new Array(列数).fill(0)
|
|
Array.from(PUB.value?.children ?? []).forEach((item, index) => {
|
|
let 最低 = Math.min(...各列高度)
|
|
let 列号 = 各列高度.indexOf(最低)
|
|
let 位置 = (列宽 + 间距) * 列号 + 边距
|
|
let 元素宽 = parseInt(item.getAttribute("data-w"))
|
|
let 元素高 = parseInt(item.getAttribute("data-h"))
|
|
let 缩放比 = 元素宽 / 列宽
|
|
let 缩放高 = parseInt(元素高 / 缩放比)
|
|
item.style.top = 最低 + "px"
|
|
item.style.left = 位置 + "px"
|
|
item.style.width = 列宽 + "px"
|
|
item.style.height = 缩放高 + "px"
|
|
item.style.transitionDelay = `${index * 40}ms`
|
|
各列高度[列号] += 缩放高 + 间距
|
|
})
|
|
if (PUB.value) PUB.value.style.height = Math.max(...各列高度) + "px"
|
|
WIDTH.value = 列宽
|
|
};
|
|
|
|
const disabled = ref(false); // 上锁
|
|
const inadvance = ref(400); // 距离
|
|
const page = ref(3); // 页码
|
|
|
|
//const nextPage = () => {
|
|
// fetch(`/api/text?page=${page.value}`).then((res) => {
|
|
// page.value = page.value + 1;
|
|
// disabled.value = false;
|
|
// if (res.status === 200) {
|
|
// res.json().then((rest) => {
|
|
// console.log(rest);
|
|
// rest.list.forEach((item) => {
|
|
// if (!item.width || !item.height) {
|
|
// console.log("没有宽高");
|
|
// let img = new Image();
|
|
// img.src = item.image;
|
|
// img.onload = () => {
|
|
// console.log("width:" + img.width + ",height:" + img.height);
|
|
// item.width = img.width;
|
|
// item.height = img.height;
|
|
// };
|
|
// }
|
|
// });
|
|
// data.value.list = data.value.list.concat(rest.list);
|
|
// });
|
|
// }
|
|
// });
|
|
//};
|
|
|
|
const handleScroll = () => {
|
|
if (disabled.value) return;
|
|
const { scrollHeight, scrollTop, clientHeight } = document.documentElement;
|
|
if (scrollHeight - scrollTop - clientHeight <= inadvance.value) {
|
|
console.log("scroll to bottom");
|
|
disabled.value = true; // 加载期间上锁
|
|
inadvance.value = 1280; // 加高判定值使卡顿感减弱
|
|
//nextPage();
|
|
}
|
|
}
|
|
|
|
onBeforeUnmount(() => {
|
|
document.removeEventListener("scroll", handleScroll)
|
|
})
|
|
|
|
onMounted(() => {
|
|
屏幕宽高重置()
|
|
window.onresize = 屏幕宽高重置
|
|
document.addEventListener("scroll", handleScroll)
|
|
})
|
|
|
|
onUpdated(() => {
|
|
屏幕宽高重置()
|
|
})
|
|
</script>
|