优化添加背景页面切换背景图的逻辑,修复抖动问题

This commit is contained in:
jingrow 2026-01-22 13:28:06 +08:00
parent f7075b27a1
commit 8d67c28f61

View File

@ -829,19 +829,14 @@ const applyBackgroundImage = async (imageUrl: string) => {
if (!fabricCanvas || !uploadedImage.value || !uploadedImageUrl.value) return
try {
processing.value = true
// Don't set processing.value = true to avoid overlay flicker
// Save the original foreground image reference before clearing
const currentObjects = fabricCanvas.getObjects()
const foregroundImg = currentObjects.length > 0 ? currentObjects[0] : null
// Load background image
// Load background image first (canvas not changed yet, user sees nothing)
const bgImg = await FabricImage.fromURL(imageUrl, {
crossOrigin: 'anonymous'
})
if (!bgImg || !fabricCanvas) {
processing.value = false
return
}
@ -866,42 +861,28 @@ const applyBackgroundImage = async (imageUrl: string) => {
evented: false
})
// Clear canvas
fabricCanvas.clear()
// Get current objects
const currentObjects = fabricCanvas.getObjects()
// Add background image first (at the bottom)
// Disable auto-rendering to prevent flicker
fabricCanvas.renderOnAddRemove = false
// Remove old background images (keep only the last object - foreground)
// This keeps the foreground visible at all times
if (currentObjects.length > 1) {
const objectsToRemove = currentObjects.slice(0, -1)
objectsToRemove.forEach(obj => fabricCanvas.remove(obj))
}
// Add new background image at the bottom
fabricCanvas.add(bgImg)
fabricCanvas.sendObjectToBack(bgImg)
// Re-load and add the foreground image (original uploaded image)
if (foregroundImg) {
// Clone the foreground image to avoid issues
const newForegroundImg = await FabricImage.fromURL(uploadedImageUrl.value, {
crossOrigin: 'anonymous'
})
if (newForegroundImg) {
newForegroundImg.set({
left: canvasWidth / 2,
top: canvasHeight / 2,
originX: 'center',
originY: 'center',
selectable: false,
evented: false
})
fabricCanvas.add(newForegroundImg)
}
}
// Ensure correct layer order: background at bottom, foreground on top
const allObjects = fabricCanvas.getObjects()
if (allObjects.length === 2) {
// Move background (first object) to back
fabricCanvas.sendObjectToBack(allObjects[0])
// Move foreground (second object) to front
fabricCanvas.bringObjectToFront(allObjects[1])
}
// Clear background color since we're using background image
fabricCanvas.backgroundColor = null
// Re-enable auto-rendering and render once
fabricCanvas.renderOnAddRemove = true
fabricCanvas.renderAll()
// Export result
@ -930,8 +911,6 @@ const applyBackgroundImage = async (imageUrl: string) => {
historyList.value[currentHistoryIndex.value].resultImage = dataUrl
}
processing.value = false
// Auto-close mobile color picker on mobile
if (window.innerWidth <= 768) {
closeMobileColorPicker()
@ -939,7 +918,6 @@ const applyBackgroundImage = async (imageUrl: string) => {
} catch (error: any) {
console.error('Apply background image error:', error)
message.error(t('Failed to apply background image'))
processing.value = false
}
}