添加背景页面工具栏增加清除背景图标

This commit is contained in:
jingrow 2026-01-21 21:37:42 +08:00
parent 4c17007f33
commit 9ca7b644cf
2 changed files with 116 additions and 0 deletions

View File

@ -1218,6 +1218,8 @@
"Upload": "上传",
"Background Settings": "背景设置",
"Close": "关闭",
"Clear Background": "清除背景",
"Failed to clear background": "清除背景失败",
"Sign up successful, but auto login failed. Please login manually": "注册成功,但自动登录失败,请手动登录",
"WeChat": "微信",
"Weibo": "微博",

View File

@ -43,6 +43,14 @@ favorite-colors-grid<template>
>
<i class="fa fa-download"></i>
</button>
<button
v-if="resultImage"
class="toolbar-btn"
@click="clearBackground"
:title="t('Clear Background')"
>
<i class="fa fa-eraser"></i>
</button>
<button
class="toolbar-btn"
@click="resetUpload"
@ -1740,6 +1748,99 @@ const resetUpload = () => {
}
}
// Clear background (restore to transparent)
const clearBackground = async () => {
if (!fabricCanvas || !uploadedImage.value || !uploadedImageUrl.value) return
try {
processing.value = true
// Clean up old canvas
if (fabricCanvas) {
fabricCanvas.dispose()
fabricCanvas = null
}
// Create new fabric canvas WITHOUT background
fabricCanvas = new Canvas(canvasRef.value, {
selection: false,
backgroundColor: 'transparent'
})
// Load the original uploaded image (already has transparency)
const img = await FabricImage.fromURL(uploadedImageUrl.value, {
crossOrigin: 'anonymous'
})
if (!img || !fabricCanvas) {
processing.value = false
return
}
// Get image natural dimensions
const imgWidth = img.width || 1
const imgHeight = img.height || 1
// Set canvas to actual image dimensions
fabricCanvas.setDimensions({ width: imgWidth, height: imgHeight })
img.set({
left: 0,
top: 0,
selectable: false,
evented: false,
scaleX: 1,
scaleY: 1
})
// Ensure no background color
fabricCanvas.backgroundColor = ''
fabricCanvas.add(img)
fabricCanvas.centerObject(img)
fabricCanvas.renderAll()
// Adjust visual display size to fit container
adjustCanvasSize()
// Export result with transparent background
const dataUrl = fabricCanvas.toDataURL({
format: 'png',
quality: 0.95,
multiplier: 1
})
resultImage.value = dataUrl
await cacheResultImage(dataUrl)
// Reset background color to default
backgroundColor.value = '#FFFFFF'
// Update or create history item
if (currentHistoryIndex.value === -1) {
const historyItem: HistoryItem = {
id: `history-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
originalImageUrl: uploadedImageUrl.value,
originalImageFile: uploadedImage.value,
resultImage: dataUrl,
backgroundColor: '',
timestamp: Date.now()
}
historyList.value.unshift(historyItem)
currentHistoryIndex.value = 0
} else if (currentHistoryIndex.value >= 0) {
historyList.value[currentHistoryIndex.value].resultImage = dataUrl
historyList.value[currentHistoryIndex.value].backgroundColor = ''
}
processing.value = false
} catch (error: any) {
console.error('Clear background error:', error)
message.error(t('Failed to clear background'))
processing.value = false
}
}
// Convert RGB to light pastel color using OKLCH (adaptive approach)
const rgbToLightPastel = (r: number, g: number, b: number): string => {
// Convert RGB to hex first
@ -2494,6 +2595,17 @@ const removeHistoryItem = (index: number) => {
position: relative;
display: inline-block;
margin: auto;
/* Checkerboard pattern for transparent background */
background-image:
linear-gradient(45deg, #e5e7eb 25%, transparent 25%),
linear-gradient(-45deg, #e5e7eb 25%, transparent 25%),
linear-gradient(45deg, transparent 75%, #e5e7eb 75%),
linear-gradient(-45deg, transparent 75%, #e5e7eb 75%);
background-size: 20px 20px;
background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
background-color: #ffffff;
padding: 0;
border-radius: 8px;
}
.preview-canvas {
@ -2503,6 +2615,8 @@ const removeHistoryItem = (index: number) => {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
/* Ensure canvas itself has no background */
background: transparent;
}
/* Right Sidebar */