139 lines
6.1 KiB
JavaScript
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;
|