Fix: Add custom photo as editable design element instead of background

When a custom photo is provided (from photo request), automatically add it
as an editable image element on the design canvas instead of replacing
the product background. This allows the admin to:
- Move and position the photo on the product
- Resize and rotate the photo
- Add text and other design elements on top
- Edit it just like any other design element
This commit is contained in:
Andymick
2026-07-18 21:13:23 +01:00
parent 77c0fc6d0d
commit df6aeb1dfe
+18 -8
View File
@@ -598,6 +598,24 @@ export default function DesignCanvas({
} }
}, [product.id]); }, [product.id]);
// Add custom photo as an editable image element when provided
useEffect(() => {
if (customPhoto && elementsFront.length === 0) {
const imageId = uuid();
const newImage: DesignElement = {
id: imageId,
type: 'image',
src: customPhoto,
x: DISPLAY / 4,
y: DISPLAY / 4,
width: DISPLAY / 2,
height: DISPLAY / 2,
rotation: 0,
};
setElementsFront([newImage]);
}
}, [customPhoto]);
useLayoutEffect(() => { useLayoutEffect(() => {
const el = canvasContainerRef.current; const el = canvasContainerRef.current;
if (!el) return; if (!el) return;
@@ -1114,11 +1132,6 @@ export default function DesignCanvas({
}; };
function renderPhoto(v: 'front' | 'back') { function renderPhoto(v: 'front' | 'back') {
// If a custom photo was provided (e.g., from a photo request), use it
if (customPhoto && v === 'front') {
return <img src={customPhoto} alt="Custom photo" className="h-full w-full object-cover" />;
}
const colorPhoto = v === 'front' ? product.colorPhotos[color] : product.colorPhotosBack[color]; const colorPhoto = v === 'front' ? product.colorPhotos[color] : product.colorPhotosBack[color];
if (colorPhoto) { if (colorPhoto) {
return <img src={colorPhoto} alt={`${product.name} in ${color}`} className="h-full w-full object-cover" />; return <img src={colorPhoto} alt={`${product.name} in ${color}`} className="h-full w-full object-cover" />;
@@ -1147,9 +1160,6 @@ export default function DesignCanvas({
// Same resolution logic as renderPhoto, but returns raw data instead of JSX — // Same resolution logic as renderPhoto, but returns raw data instead of JSX —
// used when compositing the placement-reference image for the order record. // used when compositing the placement-reference image for the order record.
function getPhotoInfo(v: 'front' | 'back'): { url: string; tint: boolean } | null { function getPhotoInfo(v: 'front' | 'back'): { url: string; tint: boolean } | null {
// If a custom photo was provided (e.g., from a photo request), use it
if (customPhoto && v === 'front') return { url: customPhoto, tint: false };
const colorPhoto = v === 'front' ? product.colorPhotos[color] : product.colorPhotosBack[color]; const colorPhoto = v === 'front' ? product.colorPhotos[color] : product.colorPhotosBack[color];
if (colorPhoto) return { url: colorPhoto, tint: false }; if (colorPhoto) return { url: colorPhoto, tint: false };