fix: 2533 鼠标悬停时显示图片名称、放大、下载按钮

pull/1/head
lizijiee 2 years ago
parent 26aa61a804
commit 1489248287

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 512 512"><path d="M304 192v32c0 6.6-5.4 12-12 12h-56v56c0 6.6-5.4 12-12 12h-32c-6.6 0-12-5.4-12-12v-56h-56c-6.6 0-12-5.4-12-12v-32c0-6.6 5.4-12 12-12h56v-56c0-6.6 5.4-12 12-12h32c6.6 0 12 5.4 12 12v56h56c6.6 0 12 5.4 12 12zm201 284.7L476.7 505c-9.4 9.4-24.6 9.4-33.9 0L343 405.3c-4.5-4.5-7-10.6-7-17V372c-35.3 27.6-79.7 44-128 44C93.1 416 0 322.9 0 208S93.1 0 208 0s208 93.1 208 208c0 48.3-16.4 92.7-44 128h16.3c6.4 0 12.5 2.5 17 7l99.7 99.7c9.3 9.4 9.3 24.6 0 34zM344 208c0-75.2-60.8-136-136-136S72 132.8 72 208s60.8 136 136 136s136-60.8 136-136z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 678 B

@ -1,13 +1,4 @@
<script lang="ts" setup> <script lang="ts" setup>
import { useInfiniteScroll } from '@vueuse/core'
import imagesloaded from 'imagesloaded'
import { debounce } from 'lodash-es'
import Masonry from 'masonry-layout'
import { useMessage } from 'naive-ui'
import { computed, nextTick, onMounted, onUnmounted, onUpdated, reactive, ref, unref, watch } from 'vue'
import GeneratePackageModal from './modal/GeneratePackageModal.vue'
import PackageSettingsModal from './modal/PackageSettingsModal.vue'
import LoginSuccessModal from './modal/LoginSuccessModal.vue'
import { getPictureList, oneClickCheck } from '@/api/home/main' import { getPictureList, oneClickCheck } from '@/api/home/main'
import avatar from '@/assets/images/avatar.jpg' import avatar from '@/assets/images/avatar.jpg'
import { timeOptions, viewOptions } from '@/config/home' import { timeOptions, viewOptions } from '@/config/home'
@ -17,6 +8,15 @@ import { getViewportOffset } from '@/utils/domUtils'
import { hideDownload } from '@/utils/image' import { hideDownload } from '@/utils/image'
import emitter from '@/utils/mitt' import emitter from '@/utils/mitt'
import { getImgUrl } from '@/utils/urlUtils' import { getImgUrl } from '@/utils/urlUtils'
import { useInfiniteScroll } from '@vueuse/core'
import imagesloaded from 'imagesloaded'
import { debounce } from 'lodash-es'
import Masonry from 'masonry-layout'
import { useMessage } from 'naive-ui'
import { computed, nextTick, onMounted, onUnmounted, onUpdated, reactive, ref, unref, watch } from 'vue'
import GeneratePackageModal from './modal/GeneratePackageModal.vue'
import LoginSuccessModal from './modal/LoginSuccessModal.vue'
import PackageSettingsModal from './modal/PackageSettingsModal.vue'
const deviceHeight = ref(600) const deviceHeight = ref(600)
let _masonry: null | Masonry = null let _masonry: null | Masonry = null
@ -141,6 +141,7 @@ async function featchList() {
ocrPictureclass: item.ocrPictureclass, ocrPictureclass: item.ocrPictureclass,
uphead: item.uphead, uphead: item.uphead,
similar: item.similarityscore || 0, similar: item.similarityscore || 0,
imgName: item.imgname
} }
}) })
@ -264,6 +265,52 @@ function sortHandler() {
sortBy.value = sortBy.value === 'asc' ? 'desc' : 'asc' sortBy.value = sortBy.value === 'asc' ? 'desc' : 'asc'
refreshHandler() refreshHandler()
} }
async function downloadImage(item) {
if (!item.thumburl) {
message.error('请输入有效的图片链接地址')
return;
}
try {
// 使 fetch GET
const response = await fetch(item.thumburl, {
method: 'GET',
mode: 'cors', //
cache: 'default',
});
//
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
// Blob
const blob = await response.blob();
// a
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = item.imgName; //
link.style.display = 'none'; //
// DOM
document.body.appendChild(link);
//
link.click();
//
URL.revokeObjectURL(link.href);
document.body.removeChild(link);
} catch (error) {
console.error('下载图片时发生错误:', error);
}
}
function previewHandler(index: number,event: MouseEvent) {
event.stopImmediatePropagation();
event.stopPropagation();
if (imageRef.value?.[index] && (imageRef.value[index] as any).src)
(imageRef.value?.[index] as any).mergedOnClick();
}
</script> </script>
<template> <template>
@ -307,17 +354,27 @@ function sortHandler() {
class="wrapper-content-item-img" :class="{ 'wrapper-content-item-img-fit': viewMode !== 'masonry' }" class="wrapper-content-item-img" :class="{ 'wrapper-content-item-img-fit': viewMode !== 'masonry' }"
:src="item.imgUrl" :src="item.imgUrl"
> --> > -->
<n-image <n-image class="img" :img-props="{ onClick: hideDownload }"
class="img" :img-props="{ onClick: hideDownload }" :class="{ 'img-fit': viewMode === 'horizontalVersion', 'img-full': viewMode === '3:4' || viewMode === 'verticalVersion' }"
:class="{ 'img-fit': viewMode === 'horizontalVersion', 'img-full': viewMode === '3:4'|| viewMode === 'verticalVersion' }" :preview-src="item.imgUrl" :src="item.thumburl" :preview-src="item.imgUrl" :src="item.thumburl" ref="imageRef" />
/>
<div class="percent"> <div class="percent">
<SvgIcon size="42" name="tag" /> <SvgIcon size="42" name="tag" />
<div class="val"> <div class="val">
{{ `${item.similar}%` }} {{ `${item.similar}%` }}
</div> </div>
</div> </div>
<div class="glass">
<SvgIcon size="16" name="download" style="margin-top: -6px;cursor: pointer;"
@click="downloadImage(item)" />
</div>
<div class="info"> <div class="info">
<div class="footer">
<div class="img-name">{{ item.imgName }}</div>
<div class="icon-wrap" @click="previewHandler(index, $event)">
<SvgIcon size="13" name="magnifying-2" style="cursor: pointer;margin-left: 3px;color:#898481" />
</div>
</div>
<div class="left"> <div class="left">
<n-avatar :src="getAvatar(item.uphead)" class="avatar" round /> <n-avatar :src="getAvatar(item.uphead)" class="avatar" round />
<span>{{ item.upname }}</span> <span>{{ item.upname }}</span>
@ -399,9 +456,11 @@ function sortHandler() {
width: 100%; width: 100%;
overflow: hidden; overflow: hidden;
} }
.img-full { .img-full {
width: 100%; width: 100%;
overflow: hidden; overflow: hidden;
::v-deep(img) { ::v-deep(img) {
width: 100%; width: 100%;
height: 100%; height: 100%;
@ -413,6 +472,7 @@ function sortHandler() {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
margin-top: 4px; margin-top: 4px;
position: relative;
.left { .left {
display: flex; display: flex;
@ -448,6 +508,64 @@ function sortHandler() {
margin-bottom: 10px; margin-bottom: 10px;
overflow: hidden; overflow: hidden;
position: relative; position: relative;
transition: 0.5s;
.glass {
position: absolute;
display: none !important;
background-color: #FFF;
border-radius: 6px;
padding: 3px;
top: 10px;
right: 10px;
width: 22px;
height: 22px;
}
.footer {
display: none;
width: 100%;
height: 40px;
position: absolute;
top: -45px;
justify-content: space-between;
align-items: center;
padding: 0 10px;
background: rgba(0, 0, 0, .35);
border-radius: 7px;
.img-name {
width: 70%;
color: #FFF;
/* 设置文本溢出时的样式为省略号 */
text-overflow: ellipsis;
/* 隐藏超出容器的文本 */
overflow: hidden;
/* 确保文本不换行 */
white-space: nowrap;
}
.icon-wrap {
width: 22px;
height: 22px;
background-color: #FFF;
border-radius: 6px;
}
}
&:hover {
.percent {
display: none;
}
.glass {
display: block !important;
}
.info .footer {
display: flex;
}
}
} }
.percent { .percent {

Loading…
Cancel
Save