优化添加背景页面右边栏清除背景后的状态

This commit is contained in:
jingrow 2026-01-21 22:23:27 +08:00
parent 887f4efcb1
commit e544ec301e

View File

@ -27,7 +27,7 @@ favorite-colors-grid<template>
v-for="(shade, index) in colorShades"
:key="index"
class="shade-item"
:class="{ 'active': shade === backgroundColor }"
:class="{ 'active': backgroundColor && shade === backgroundColor }"
:style="{ backgroundColor: shade }"
@click="selectShade(shade)"
:title="shade"
@ -208,7 +208,7 @@ favorite-colors-grid<template>
v-model="backgroundColor"
type="text"
class="sidebar-hex-input"
placeholder="#FFFFFF"
placeholder=""
@input="onHexInputChange"
@blur="onHexInputBlur"
/>
@ -294,7 +294,15 @@ favorite-colors-grid<template>
<n-tab-pane name="color" :tab="t('Color')">
<div class="color-picker-section">
<div class="color-picker-container">
<!-- Show checkerboard when background is cleared -->
<div
v-if="!backgroundColor"
class="sidebar-color-picker-empty"
@click="backgroundColor = '#FFFFFF'"
>
</div>
<input
v-else
v-model="backgroundColor"
type="color"
class="sidebar-color-picker"
@ -305,7 +313,7 @@ favorite-colors-grid<template>
v-model="backgroundColor"
type="text"
class="sidebar-hex-input"
placeholder="#FFFFFF"
placeholder=""
@input="onHexInputChange"
@blur="onHexInputBlur"
/>
@ -313,7 +321,7 @@ favorite-colors-grid<template>
class="add-favorite-btn"
@click="addToFavorites"
:title="t('Add to favorites')"
:disabled="favoriteColors.length >= MAX_FAVORITE_COLORS"
:disabled="!backgroundColor || favoriteColors.length >= MAX_FAVORITE_COLORS"
>
<i class="fa fa-star"></i>
</button>
@ -403,7 +411,7 @@ favorite-colors-grid<template>
<n-spin :show="pexelsLoading">
<div v-if="pexelsImages.length > 0" class="background-images-grid">
<div
v-for="image in pexelsImages"
v-for="image in displayedPexelsImages"
:key="image.id"
class="background-image-item"
@click="applyBackgroundImage(image.src.medium)"
@ -411,7 +419,16 @@ favorite-colors-grid<template>
<img :src="image.src.tiny" :alt="image.alt" />
</div>
</div>
<n-empty v-else :description="t('No images found')" size="small" />
<div v-if="showLoadMoreButton" class="load-more-container">
<button
type="button"
class="load-more-btn"
@click="loadMorePexelsImages"
>
{{ t('Show More') }}
</button>
</div>
<n-empty v-else-if="pexelsImages.length === 0" :description="t('No images found')" size="small" />
</n-spin>
</div>
</n-tab-pane>
@ -429,7 +446,15 @@ favorite-colors-grid<template>
<div class="color-picker-section">
<h4 class="section-title">{{ t('Background Color') }}</h4>
<div class="color-picker-container">
<!-- Show checkerboard when background is cleared -->
<div
v-if="!backgroundColor"
class="sidebar-color-picker-empty"
@click="backgroundColor = '#FFFFFF'"
>
</div>
<input
v-else
v-model="backgroundColor"
type="color"
class="sidebar-color-picker"
@ -440,7 +465,7 @@ favorite-colors-grid<template>
v-model="backgroundColor"
type="text"
class="sidebar-hex-input"
placeholder="#FFFFFF"
placeholder=""
@input="onHexInputChange"
@blur="onHexInputBlur"
/>
@ -448,7 +473,7 @@ favorite-colors-grid<template>
class="add-favorite-btn"
@click="addToFavorites"
:title="t('Add to favorites')"
:disabled="favoriteColors.length >= MAX_FAVORITE_COLORS"
:disabled="!backgroundColor || favoriteColors.length >= MAX_FAVORITE_COLORS"
>
<i class="fa fa-star"></i>
</button>
@ -552,7 +577,7 @@ favorite-colors-grid<template>
<button
type="button"
class="load-more-btn"
@click="showAllPexelsImages = true"
@click="loadMorePexelsImages"
>
{{ t('Show More') }}
</button>
@ -693,14 +718,23 @@ const fetchPexelsImages = async () => {
params: {
query: pexelsQuery.value,
page: pexelsPage.value,
per_page: 20,
per_page: PEXELS_PER_PAGE,
orientation: 'landscape'
},
headers: {
Authorization: PEXELS_API_KEY
}
})
pexelsImages.value = response.data.photos || []
const newPhotos = response.data.photos || []
// Append new photos to existing list
if (pexelsPage.value === 1) {
pexelsImages.value = newPhotos
} else {
pexelsImages.value = [...pexelsImages.value, ...newPhotos]
}
PEXELS_TOTAL_FETCHED.value = pexelsImages.value.length
} catch (error: any) {
console.error('Failed to fetch Pexels images:', error)
// Don't show error message if API key is not configured
@ -1044,25 +1078,35 @@ const pexelsLoading = ref(false)
const pexelsPage = ref(1)
const pexelsQuery = ref('nature background')
const PEXELS_API_KEY = __PEXELS_API_KEY__ || ''
const showAllPexelsImages = ref(false)
const PEXELS_INITIAL_DISPLAY = 12
const pexelsDisplayCount = ref(12)
const PEXELS_PER_PAGE = 12
const PEXELS_TOTAL_FETCHED = ref(0)
// Custom background images
const customBackgrounds = ref<string[]>([])
// Computed: Display limited or all Pexels images
// Computed: Display limited Pexels images
const displayedPexelsImages = computed(() => {
if (showAllPexelsImages.value || pexelsImages.value.length <= PEXELS_INITIAL_DISPLAY) {
return pexelsImages.value
}
return pexelsImages.value.slice(0, PEXELS_INITIAL_DISPLAY)
return pexelsImages.value.slice(0, pexelsDisplayCount.value)
})
// Show "Load More" button condition
const showLoadMoreButton = computed(() => {
return !showAllPexelsImages.value && pexelsImages.value.length > PEXELS_INITIAL_DISPLAY
return pexelsImages.value.length > pexelsDisplayCount.value
})
// Load more Pexels images
const loadMorePexelsImages = async () => {
// Increase display count by 12
pexelsDisplayCount.value += PEXELS_PER_PAGE
// If we need to fetch more images from API
if (pexelsDisplayCount.value > pexelsImages.value.length) {
pexelsPage.value++
await fetchPexelsImages()
}
}
// Load custom backgrounds from localStorage
const loadCustomBackgrounds = () => {
try {
@ -1788,7 +1832,7 @@ const clearBackground = async () => {
// Create new fabric canvas WITHOUT background
fabricCanvas = new Canvas(canvasRef.value, {
selection: false,
backgroundColor: 'transparent'
backgroundColor: null
})
// Load the original uploaded image (already has transparency)
@ -1817,8 +1861,8 @@ const clearBackground = async () => {
scaleY: 1
})
// Ensure no background color
fabricCanvas.backgroundColor = ''
// Ensure no background color (null for transparent)
fabricCanvas.backgroundColor = null
fabricCanvas.add(img)
fabricCanvas.centerObject(img)
@ -1837,8 +1881,8 @@ const clearBackground = async () => {
resultImage.value = dataUrl
await cacheResultImage(dataUrl)
// Reset background color to default
backgroundColor.value = '#FFFFFF'
// Clear hex input by setting empty string (placeholder will show)
backgroundColor.value = ''
// Update or create history item
if (currentHistoryIndex.value === -1) {
@ -2673,7 +2717,8 @@ const removeHistoryItem = (index: number) => {
.n-tabs-pane-wrapper {
flex: 1;
overflow: hidden;
overflow-y: auto;
overflow-x: hidden;
}
}
}
@ -2913,6 +2958,32 @@ const removeHistoryItem = (index: number) => {
}
}
.sidebar-color-picker-empty {
width: 100%;
height: 60px;
border: 2px solid #e5e7eb;
border-radius: 8px;
cursor: pointer;
position: relative;
display: flex;
align-items: center;
justify-content: center;
/* Checkerboard pattern for transparent background */
background-image:
linear-gradient(45deg, #f1f5f9 25%, transparent 25%),
linear-gradient(-45deg, #f1f5f9 25%, transparent 25%),
linear-gradient(45deg, transparent 75%, #f1f5f9 75%),
linear-gradient(-45deg, transparent 75%, #f1f5f9 75%);
background-size: 20px 20px;
background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
background-color: #ffffff;
transition: all 0.2s ease;
&:hover {
border-color: #1fc76f;
}
}
.sidebar-hex-input {
flex: 1;
border: 1px solid #e5e7eb;
@ -3074,7 +3145,7 @@ const removeHistoryItem = (index: number) => {
border: 2px solid #e5e7eb;
transition: all 0.15s ease;
position: relative;
overflow: hidden;
overflow: visible;
background: #f3f4f6;
img {
@ -3096,8 +3167,8 @@ const removeHistoryItem = (index: number) => {
.remove-bg-btn {
position: absolute;
top: 4px;
right: 4px;
top: -8px;
right: -8px;
width: 20px;
height: 20px;
border-radius: 999px;
@ -3108,7 +3179,7 @@ const removeHistoryItem = (index: number) => {
align-items: center;
justify-content: center;
opacity: 0;
transform: scale(0.8);
transform: scale(0.9);
transition: all 0.2s ease;
cursor: pointer;
font-size: 0;