canvas-backend/src/components/CanvasCapture.jsx
2024-12-25 18:13:00 +06:00

139 lines
6.1 KiB
JavaScript

import { useContext, useState } from 'react';
import CanvasContext from './Context/canvasContext/CanvasContext';
import OpenContext from './Context/openContext/OpenContext';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Label } from '@/components/ui/label';
import { Button } from '@/components/ui/button';
import { Card, CardHeader, CardTitle } from './ui/card';
import { Rnd } from 'react-rnd';
import { X } from 'lucide-react';
import { Separator } from './ui/separator';
const resolutions = [
{ value: '720p', label: 'HD (1280x720)', width: 1280, height: 720 },
{ value: '1080p', label: 'Full HD (1920x1080)', width: 1920, height: 1080 },
{ value: '1440p', label: 'QHD (2560x1440)', width: 2560, height: 1440 },
{ value: '4k', label: '4K (3840x2160)', width: 3840, height: 2160 },
{ value: 'story', label: 'Story (1080x1920)', width: 1080, height: 1920 }, // Added for Stories
{ value: '5k', label: '5K (5120x2880)', width: 5120, height: 2880 },
{ value: 'ultrawide', label: 'Ultrawide (3440x1440)', width: 3440, height: 1440 },
{ value: 'cinematic', label: 'Cinematic (2560x1080)', width: 2560, height: 1080 },
];
const imageTypes = [
{ value: 'png', label: 'PNG' },
{ value: 'jpeg', label: 'JPEG' },
{ value: 'webp', label: 'WebP' },
];
const CanvasCapture = () => {
const [resolution, setResolution] = useState(resolutions[0].value);
const [imageType, setImageType] = useState(imageTypes[0].value);
const { canvas } = useContext(CanvasContext);
const { captureOpen, setCaptureOpen } = useContext(OpenContext);
const captureImage = async () => {
if (!canvas) return;
const selectedResolution = resolutions.find(res => res.value === resolution);
const { width, height } = selectedResolution;
// Create a temporary canvas for resizing
const tempCanvas = document.createElement('canvas');
const tempCtx = tempCanvas.getContext('2d');
// Set desired resolution
tempCanvas.width = width;
tempCanvas.height = height;
// Render the fabric.js canvas onto the temporary canvas
const dataUrl = canvas.toDataURL({
format: imageType,
quality: 1,
multiplier: width / canvas.width, // Adjust the scale based on width
});
const img = new Image();
img.src = dataUrl;
img.onload = () => {
tempCtx.drawImage(img, 0, 0, width, height);
// Generate resized image data URL
const resizedDataUrl = tempCanvas.toDataURL(`image/${imageType}`, 1);
// Download the resized image
const link = document.createElement('a');
link.href = resizedDataUrl;
link.download = `PlanPostAi-capture-${resolution}.${imageType}`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
};
};
return (
<>
{captureOpen && (
<Rnd
className='z-[1000]'
default={{ x: 0, y: 20 }}
minWidth={250}
maxWidth={300}
minHeight={150}
bounds='parent'
>
<Card className='space-y-2 p-2'>
<CardHeader className='p-0'>
<div className='flex items-center justify-between'>
<Button variant={'ghost'} onClick={() => setCaptureOpen(false)}>
<X className='cursor-pointer' />
</Button>
<CardTitle className='text-lg mr-1'>Capture Panel</CardTitle>
</div>
</CardHeader>
<Separator />
<div className='grid grid-cols-1 sm:grid-cols-2 gap-4'>
<div className='space-y-2'>
<Label htmlFor='resolution'>Resolution</Label>
<Select onValueChange={setResolution} defaultValue={resolution}>
<SelectTrigger id='resolution'>
<SelectValue placeholder='Select resolution' />
</SelectTrigger>
<SelectContent>
{resolutions.map(res => (
<SelectItem key={res.value} value={res.value}>
{res.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div className='space-y-2'>
<Label htmlFor='imageType'>Image Type</Label>
<Select onValueChange={setImageType} defaultValue={imageType}>
<SelectTrigger id='imageType'>
<SelectValue placeholder='Select image type' />
</SelectTrigger>
<SelectContent>
{imageTypes.map(type => (
<SelectItem key={type.value} value={type.value}>
{type.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
</div>
<Button onClick={captureImage} className='w-full'>
Capture Canvas
</Button>
</Card>
</Rnd>
)}
</>
);
};
export default CanvasCapture;