145 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			145 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"
 | 
						|
      ) 上传图片 {{ status }}
 | 
						|
      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="status === 'success'",
 | 
						|
    :class="{ 'opacity-100': status === 'success', 'opacity-10': status !== 'success' }"
 | 
						|
  )
 | 
						|
    .absolute.transition-all.duration-700.ease-in-out.left-0.top-2000.bg-gray-100(
 | 
						|
      v-for="item in data" :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="`/api/gallery/${item.id}@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, status, 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>
 |