添加背景页面增加收藏背景色功能
This commit is contained in:
parent
951813a539
commit
27b7d65e45
@ -1113,6 +1113,12 @@
|
||||
"Add custom background color to images. Free online tool to add background to transparent images. Supports JPG, PNG, WebP formats.": "为图片添加自定义背景颜色。免费在线工具,可为透明背景图片添加背景。支持 JPG、PNG、WebP 格式。",
|
||||
"add background, background color, image background, transparent background, online background tool, image processing, background editor, free tool": "添加背景、背景颜色、图片背景、透明背景、在线背景工具、图片处理、背景编辑器、免费工具",
|
||||
"Background Color": "背景颜色",
|
||||
"Add to favorites": "添加到收藏",
|
||||
"Remove from favorites": "从收藏中移除",
|
||||
"Favorite Colors": "收藏颜色",
|
||||
"Color already in favorites": "颜色已在收藏中",
|
||||
"Maximum 12 favorite colors allowed. Please remove one first.": "最多允许12个收藏颜色,请先移除一个",
|
||||
"Color added to favorites": "颜色已添加到收藏",
|
||||
"Color Tones": "色调",
|
||||
"Common Colors": "常用颜色",
|
||||
"Apply Background": "应用背景",
|
||||
|
||||
@ -161,7 +161,17 @@
|
||||
<div v-if="uploadedImage" class="right-sidebar">
|
||||
<div class="sidebar-content">
|
||||
<div class="color-picker-section">
|
||||
<h4 class="section-title">{{ t('Background Color') }}</h4>
|
||||
<div class="section-header">
|
||||
<h4 class="section-title">{{ t('Background Color') }}</h4>
|
||||
<button
|
||||
class="add-favorite-btn"
|
||||
@click="addToFavorites"
|
||||
:title="t('Add to favorites')"
|
||||
:disabled="favoriteColors.length >= MAX_FAVORITE_COLORS"
|
||||
>
|
||||
<i class="fa fa-star"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="color-picker-container">
|
||||
<input
|
||||
v-model="backgroundColor"
|
||||
@ -180,6 +190,29 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="favoriteColors.length > 0" class="favorite-colors-section">
|
||||
<h4 class="section-title">{{ t('Favorite Colors') }}</h4>
|
||||
<div class="favorite-colors-grid">
|
||||
<div
|
||||
v-for="(color, index) in favoriteColors"
|
||||
:key="index"
|
||||
class="favorite-color-item"
|
||||
:class="{ 'active': color === backgroundColor }"
|
||||
:style="{ backgroundColor: color }"
|
||||
@click="selectCommonColor(color)"
|
||||
:title="color"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="remove-favorite-btn"
|
||||
@click.stop="removeFavoriteColor(color)"
|
||||
:title="t('Remove from favorites')"
|
||||
:aria-label="t('Remove from favorites')"
|
||||
></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="common-colors-section">
|
||||
<h4 class="section-title">{{ t('Common Colors') }}</h4>
|
||||
<div class="common-colors-grid">
|
||||
@ -251,6 +284,65 @@ const colorShades = computed(() => {
|
||||
return generateColorShades(backgroundColor.value)
|
||||
})
|
||||
|
||||
// Favorite colors - persisted in localStorage
|
||||
const favoriteColors = ref<string[]>([])
|
||||
const MAX_FAVORITE_COLORS = 12
|
||||
|
||||
// Load favorite colors from localStorage
|
||||
const loadFavoriteColors = () => {
|
||||
try {
|
||||
const saved = localStorage.getItem('add_background_favorite_colors')
|
||||
if (saved) {
|
||||
const parsed = JSON.parse(saved)
|
||||
if (Array.isArray(parsed)) {
|
||||
favoriteColors.value = parsed.slice(0, MAX_FAVORITE_COLORS)
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to load favorite colors:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// Save favorite colors to localStorage
|
||||
const saveFavoriteColors = () => {
|
||||
try {
|
||||
localStorage.setItem('add_background_favorite_colors', JSON.stringify(favoriteColors.value))
|
||||
} catch (error) {
|
||||
console.error('Failed to save favorite colors:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// Add current color to favorites
|
||||
const addToFavorites = () => {
|
||||
const color = backgroundColor.value.toUpperCase()
|
||||
|
||||
// Check if color already exists
|
||||
if (favoriteColors.value.includes(color)) {
|
||||
message.info(t('Color already in favorites'))
|
||||
return
|
||||
}
|
||||
|
||||
// Check if favorites is full
|
||||
if (favoriteColors.value.length >= MAX_FAVORITE_COLORS) {
|
||||
message.warning(t('Maximum 12 favorite colors allowed. Please remove one first.'))
|
||||
return
|
||||
}
|
||||
|
||||
// Add to beginning of array
|
||||
favoriteColors.value.unshift(color)
|
||||
saveFavoriteColors()
|
||||
message.success(t('Color added to favorites'))
|
||||
}
|
||||
|
||||
// Remove color from favorites
|
||||
const removeFavoriteColor = (color: string) => {
|
||||
const index = favoriteColors.value.indexOf(color)
|
||||
if (index > -1) {
|
||||
favoriteColors.value.splice(index, 1)
|
||||
saveFavoriteColors()
|
||||
}
|
||||
}
|
||||
|
||||
// 12 common background colors - light to dark
|
||||
const commonColors = ref([
|
||||
'#FFFFFF', // White
|
||||
@ -547,6 +639,7 @@ const handleUrlSubmit = async () => {
|
||||
onMounted(() => {
|
||||
window.addEventListener('resize', handleResize)
|
||||
window.addEventListener('paste', handlePaste)
|
||||
loadFavoriteColors()
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
@ -1737,19 +1830,65 @@ const removeHistoryItem = (index: number) => {
|
||||
}
|
||||
|
||||
.color-picker-section,
|
||||
.favorite-colors-section,
|
||||
.common-colors-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 1px solid #e5e7eb;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #1f2937;
|
||||
margin: 0;
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 1px solid #e5e7eb;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.add-favorite-btn {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 6px;
|
||||
background: white;
|
||||
color: #fbbf24;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.2s ease;
|
||||
padding: 0;
|
||||
flex-shrink: 0;
|
||||
|
||||
i {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
border-color: #fbbf24;
|
||||
background: #fffbeb;
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
&:active:not(:disabled) {
|
||||
transform: scale(0.95);
|
||||
background: #fef3c7;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.4;
|
||||
cursor: not-allowed;
|
||||
color: #cbd5e1;
|
||||
}
|
||||
}
|
||||
|
||||
.color-picker-container {
|
||||
@ -1800,12 +1939,18 @@ const removeHistoryItem = (index: number) => {
|
||||
}
|
||||
}
|
||||
|
||||
.favorite-colors-grid,
|
||||
.common-colors-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.favorite-colors-grid {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.favorite-color-item,
|
||||
.common-color-item {
|
||||
aspect-ratio: 1;
|
||||
border-radius: 8px;
|
||||
@ -1841,6 +1986,58 @@ const removeHistoryItem = (index: number) => {
|
||||
}
|
||||
}
|
||||
|
||||
.favorite-color-item {
|
||||
.remove-favorite-btn {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
right: 2px;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border-radius: 999px;
|
||||
border: none;
|
||||
background: rgba(15, 23, 42, 0.75);
|
||||
color: white;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
opacity: 0;
|
||||
transform: scale(0.8);
|
||||
transition: all 0.2s ease;
|
||||
cursor: pointer;
|
||||
font-size: 0;
|
||||
line-height: 1;
|
||||
z-index: 2;
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 10px;
|
||||
height: 2px;
|
||||
background: white;
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
&::before {
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
&::after {
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: rgba(239, 68, 68, 0.9);
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
&:hover .remove-favorite-btn {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
.canvas-processing-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
@ -2146,6 +2343,7 @@ const removeHistoryItem = (index: number) => {
|
||||
box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.favorite-colors-grid,
|
||||
.common-colors-grid {
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
}
|
||||
@ -2191,6 +2389,7 @@ const removeHistoryItem = (index: number) => {
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
.favorite-colors-grid,
|
||||
.common-colors-grid {
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user