优化添加背景页面

This commit is contained in:
jingrow 2026-01-21 14:50:01 +08:00
parent 803fd46e1e
commit aca21ce487

View File

@ -308,20 +308,42 @@ let fabricCanvas: Canvas | null = null
const adjustCanvasSize = () => { const adjustCanvasSize = () => {
const canvas = canvasRef.value const canvas = canvasRef.value
if (!canvas) return if (!canvas || !fabricCanvas) return
const previewSection = canvas.closest('.preview-section') as HTMLElement const container = canvas.parentElement
if (!container) return
const previewSection = container.closest('.preview-section') as HTMLElement
if (!previewSection) return if (!previewSection) return
const previewRect = previewSection.getBoundingClientRect() const previewRect = previewSection.getBoundingClientRect()
const padding = 24 const padding = 48
const maxAvailableWidth = Math.max(0, previewRect.width - padding) const maxAvailableWidth = Math.max(0, previewRect.width - padding)
const maxAvailableHeight = Math.max(0, previewRect.height - 200) // Account for controls const maxAvailableHeight = Math.max(0, previewRect.height - padding)
if (maxAvailableWidth <= 0 || maxAvailableHeight <= 0) return if (maxAvailableWidth <= 0 || maxAvailableHeight <= 0) return
canvas.style.maxWidth = `${maxAvailableWidth}px` // Get canvas natural dimensions
canvas.style.maxHeight = `${maxAvailableHeight}px` const canvasWidth = fabricCanvas.width || 1
const canvasHeight = fabricCanvas.height || 1
// Calculate scale to fit within available space
const scale = Math.min(
maxAvailableWidth / canvasWidth,
maxAvailableHeight / canvasHeight,
1
)
// Apply display dimensions to container
const displayWidth = canvasWidth * scale
const displayHeight = canvasHeight * scale
container.style.width = `${displayWidth}px`
container.style.height = `${displayHeight}px`
// Scale canvas visually using CSS transform
canvas.style.transform = `scale(${scale})`
canvas.style.transformOrigin = 'top left'
} }
watch(uploadedImageUrl, adjustCanvasSize) watch(uploadedImageUrl, adjustCanvasSize)
@ -754,45 +776,30 @@ const initializeCanvas = async () => {
return return
} }
const previewSection = canvasRef.value?.closest('.preview-section') as HTMLElement // Get image natural dimensions (already compressed to max 1024x1024)
if (!previewSection) {
processing.value = false
return
}
const previewRect = previewSection.getBoundingClientRect()
const padding = 100
const maxAvailableWidth = Math.max(400, previewRect.width - padding)
const maxAvailableHeight = Math.max(400, previewRect.height - 300)
const imgWidth = img.width || 1 const imgWidth = img.width || 1
const imgHeight = img.height || 1 const imgHeight = img.height || 1
const scale = Math.min( // Set canvas to actual image dimensions (no scaling)
maxAvailableWidth / imgWidth, // This ensures download maintains the same size as upload
maxAvailableHeight / imgHeight, fabricCanvas.setDimensions({ width: imgWidth, height: imgHeight })
1
)
img.scale(scale)
const canvasWidth = img.getScaledWidth()
const canvasHeight = img.getScaledHeight()
// Use setDimensions for fabric v7
fabricCanvas.setDimensions({ width: canvasWidth, height: canvasHeight })
img.set({ img.set({
left: 0, left: 0,
top: 0, top: 0,
selectable: false, selectable: false,
evented: false evented: false,
scaleX: 1,
scaleY: 1
}) })
fabricCanvas.add(img) fabricCanvas.add(img)
fabricCanvas.centerObject(img) fabricCanvas.centerObject(img)
fabricCanvas.renderAll() fabricCanvas.renderAll()
// Adjust visual display size to fit container
adjustCanvasSize()
// Auto-apply default background color // Auto-apply default background color
await nextTick() await nextTick()
applyBackgroundSilent() applyBackgroundSilent()
@ -975,39 +982,20 @@ const initializeCanvasWithBackground = async (bgColor: string) => {
return return
} }
const previewSection = canvasRef.value?.closest('.preview-section') as HTMLElement // Get image natural dimensions (already compressed to max 1024x1024)
if (!previewSection) {
processing.value = false
return
}
const previewRect = previewSection.getBoundingClientRect()
const padding = 100
const maxAvailableWidth = Math.max(400, previewRect.width - padding)
const maxAvailableHeight = Math.max(400, previewRect.height - 300)
const imgWidth = img.width || 1 const imgWidth = img.width || 1
const imgHeight = img.height || 1 const imgHeight = img.height || 1
const scale = Math.min( // Set canvas to actual image dimensions (no scaling)
maxAvailableWidth / imgWidth, fabricCanvas.setDimensions({ width: imgWidth, height: imgHeight })
maxAvailableHeight / imgHeight,
1
)
img.scale(scale)
const canvasWidth = img.getScaledWidth()
const canvasHeight = img.getScaledHeight()
// Use setDimensions for fabric v7
fabricCanvas.setDimensions({ width: canvasWidth, height: canvasHeight })
img.set({ img.set({
left: 0, left: 0,
top: 0, top: 0,
selectable: false, selectable: false,
evented: false evented: false,
scaleX: 1,
scaleY: 1
}) })
// Apply saved background color if provided // Apply saved background color if provided
@ -1019,6 +1007,9 @@ const initializeCanvasWithBackground = async (bgColor: string) => {
fabricCanvas.centerObject(img) fabricCanvas.centerObject(img)
fabricCanvas.renderAll() fabricCanvas.renderAll()
// Adjust visual display size to fit container
adjustCanvasSize()
processing.value = false processing.value = false
} catch (error) { } catch (error) {
console.error('Canvas initialization error:', error) console.error('Canvas initialization error:', error)
@ -1571,29 +1562,27 @@ const removeHistoryItem = (index: number) => {
width: 100%; width: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center;
justify-content: center;
overflow: hidden; overflow: hidden;
min-height: 0; min-height: 0;
padding: 0; padding: 24px;
background: #fafbfc; background: #fafbfc;
} }
.canvas-container { .canvas-container {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
position: relative; position: relative;
overflow: auto; display: inline-block;
min-height: 400px; margin: auto;
padding: 20px;
} }
.preview-canvas { .preview-canvas {
max-width: 100%; display: block;
max-height: 100%;
border: 1px solid #e5e7eb; border: 1px solid #e5e7eb;
border-radius: 8px; border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
} }
/* Right Sidebar - Naive UI Style */ /* Right Sidebar - Naive UI Style */