feat: 为特色图选择器增加预览功能与自适应高度支持
This commit is contained in:
1 parent
9e33fabdbe
commit
edcf251945
1 file changed
+62
-4
@@ -1,19 +1,32 @@
|
||||
<script lang="ts">
|
||||
import { addToast } from '$lib/stores/toast.svelte';
|
||||
import { Fancybox } from '@fancyapps/ui/dist/index.js';
|
||||
import '@fancyapps/ui/dist/fancybox/fancybox.css';
|
||||
import { onMount } from 'svelte';
|
||||
import Tabs from './Tabs.svelte';
|
||||
|
||||
let {
|
||||
cover = $bindable(''),
|
||||
title = '特色图',
|
||||
inputName = 'cover',
|
||||
aspectRatio = '16/9'
|
||||
aspectRatio = '16/9',
|
||||
adaptiveHeight = false,
|
||||
previewable = false
|
||||
} = $props<{
|
||||
cover?: string | null;
|
||||
title?: string;
|
||||
inputName?: string;
|
||||
aspectRatio?: string;
|
||||
adaptiveHeight?: boolean;
|
||||
previewable?: boolean;
|
||||
}>();
|
||||
|
||||
let pickerElement = $state<HTMLDivElement>();
|
||||
let previewHeightRatio = $derived((() => {
|
||||
const [width, height] = aspectRatio.split('/').map(Number);
|
||||
return width > 0 && height > 0 ? height / width : 9 / 16;
|
||||
})());
|
||||
|
||||
let activeTab = $state('url');
|
||||
let isUploading = $state(false);
|
||||
|
||||
@@ -22,6 +35,16 @@
|
||||
let hasMore = $state(true);
|
||||
let isLoadingLibrary = $state(false);
|
||||
|
||||
onMount(() => {
|
||||
if (!previewable || !pickerElement) return;
|
||||
|
||||
const selector = '[data-fancybox="featured-image-preview"]';
|
||||
const container = pickerElement;
|
||||
Fancybox.bind(container, selector, {});
|
||||
|
||||
return () => Fancybox.unbind(container, selector);
|
||||
});
|
||||
|
||||
async function loadLibrary(reset = false) {
|
||||
if (reset) {
|
||||
page = 1;
|
||||
@@ -89,14 +112,31 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="sidebar-box">
|
||||
<div class="sidebar-box" bind:this={pickerElement}>
|
||||
{#if title}
|
||||
<h3>{title}</h3>
|
||||
{/if}
|
||||
|
||||
{#if cover}
|
||||
<div class="cover-preview">
|
||||
<img src={cover} alt="图片预览" style:aspect-ratio={aspectRatio} />
|
||||
<div
|
||||
class="cover-preview"
|
||||
class:adaptive-height={adaptiveHeight}
|
||||
style={`--preview-aspect-ratio: ${aspectRatio}; --preview-height-ratio: ${previewHeightRatio}`}
|
||||
>
|
||||
{#if previewable}
|
||||
<a
|
||||
class="cover-preview-link"
|
||||
href={cover}
|
||||
data-fancybox="featured-image-preview"
|
||||
data-caption={title || '特色图'}
|
||||
aria-label="查看特色图大图"
|
||||
title="点击查看大图"
|
||||
>
|
||||
<img src={cover} alt="图片预览" />
|
||||
</a>
|
||||
{:else}
|
||||
<img src={cover} alt="图片预览" />
|
||||
{/if}
|
||||
<button type="button" class="btn-clear" onclick={() => cover = ''}>移除</button>
|
||||
</div>
|
||||
{/if}
|
||||
@@ -166,6 +206,16 @@
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.cover-preview.adaptive-height {
|
||||
container-type: inline-size;
|
||||
}
|
||||
|
||||
.cover-preview-link {
|
||||
display: block;
|
||||
background: #f5f5f5;
|
||||
cursor: zoom-in;
|
||||
}
|
||||
|
||||
.cover-preview img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
@@ -174,6 +224,14 @@
|
||||
max-height: 280px;
|
||||
}
|
||||
|
||||
.cover-preview:not(.adaptive-height) img {
|
||||
aspect-ratio: var(--preview-aspect-ratio);
|
||||
}
|
||||
|
||||
.cover-preview.adaptive-height img {
|
||||
max-height: min(280px, calc(100cqw * var(--preview-height-ratio)));
|
||||
}
|
||||
|
||||
.btn-clear {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
|
||||
Reference in new issue
Block a user