text customization visible now
This commit is contained in:
parent
c34c1f475f
commit
ac5b6a943f
4 changed files with 7 additions and 117 deletions
|
|
@ -217,6 +217,7 @@ const CanvasSetting = () => {
|
||||||
|
|
||||||
<Separator className="mt-4" />
|
<Separator className="mt-4" />
|
||||||
|
|
||||||
|
{/* opacity */}
|
||||||
<div className='flex flex-col gap-2 rnd-escape'>
|
<div className='flex flex-col gap-2 rnd-escape'>
|
||||||
<Label>
|
<Label>
|
||||||
Adjust Opacity:
|
Adjust Opacity:
|
||||||
|
|
@ -236,18 +237,18 @@ const CanvasSetting = () => {
|
||||||
|
|
||||||
<Separator className="mt-4" />
|
<Separator className="mt-4" />
|
||||||
|
|
||||||
|
{/* canvas size customization (width/height) */}
|
||||||
<div className='flex gap-2 my-2'>
|
<div className='flex gap-2 my-2'>
|
||||||
<div className='flex flex-col gap-2'>
|
<div className='flex flex-col gap-2'>
|
||||||
<Label>
|
<Label>
|
||||||
Width:
|
Width:
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
|
min={300}
|
||||||
type="number"
|
type="number"
|
||||||
value={canvasSettings.width}
|
value={canvasSettings.width}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
if (canvasSettings?.width > parseInt(e.target.value)) {
|
handleChange('width', parseInt(e.target.value, 10));
|
||||||
handleChange('width', parseInt(e.target.value, 10));
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -257,12 +258,11 @@ const CanvasSetting = () => {
|
||||||
Height:
|
Height:
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
|
min={300}
|
||||||
type="number"
|
type="number"
|
||||||
value={canvasSettings.height}
|
value={canvasSettings.height}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
if (canvasSettings?.height > parseInt(e.target.value)) {
|
handleChange('height', parseInt(e.target.value, 10));
|
||||||
handleChange('height', parseInt(e.target.value, 10));
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,71 +0,0 @@
|
||||||
import { useContext } from 'react';
|
|
||||||
import * as fabric from 'fabric'; // v6
|
|
||||||
import ActiveObjectContext from '@/components/Context/activeObject/ObjectContext';
|
|
||||||
import CanvasContext from '@/components/Context/canvasContext/CanvasContext';
|
|
||||||
import { Input } from '@/components/ui/input';
|
|
||||||
|
|
||||||
const AddImageText = () => {
|
|
||||||
const { activeObject } = useContext(ActiveObjectContext);
|
|
||||||
const { canvas } = useContext(CanvasContext);
|
|
||||||
|
|
||||||
// Handle user image upload
|
|
||||||
const handleImageUpload = (event) => {
|
|
||||||
const file = event.target.files[0];
|
|
||||||
if (file) {
|
|
||||||
const reader = new FileReader();
|
|
||||||
|
|
||||||
reader.onload = (e) => {
|
|
||||||
const imgElement = new Image();
|
|
||||||
imgElement.src = e.target.result;
|
|
||||||
|
|
||||||
imgElement.onload = () => {
|
|
||||||
// Check if the active object is an instance of 'i-text'
|
|
||||||
if (activeObject && activeObject.type === 'i-text') {
|
|
||||||
// Create a Fabric BaseImage object from the uploaded image
|
|
||||||
const image = new fabric.BaseImage(imgElement, {
|
|
||||||
left: 0, // Set the left position as needed
|
|
||||||
top: 0, // Set the top position as needed
|
|
||||||
width: activeObject.width, // Scale the image width to match text
|
|
||||||
height: activeObject.height, // Scale the image height to match text
|
|
||||||
});
|
|
||||||
|
|
||||||
// Set the text object as the clipping path for the image
|
|
||||||
image.clipPath = activeObject;
|
|
||||||
|
|
||||||
// Set the fill of the text to be transparent to only show the clipped path
|
|
||||||
activeObject.set({ fill: 'rgba(255, 255, 255, 0)' });
|
|
||||||
|
|
||||||
// Add the image to the canvas
|
|
||||||
canvas.add(image);
|
|
||||||
|
|
||||||
// Render the canvas
|
|
||||||
canvas.requestAll();
|
|
||||||
} else {
|
|
||||||
console.warn('No active text object found or active object is not of type i-text.');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
imgElement.onerror = () => {
|
|
||||||
console.error('Failed to load the image.');
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
reader.readAsDataURL(file); // Convert image file to base64
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<div>
|
|
||||||
<Input
|
|
||||||
type="file"
|
|
||||||
accept="image/*"
|
|
||||||
onChange={handleImageUpload}
|
|
||||||
style={{ marginBottom: '10px' }}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AddImageText;
|
|
||||||
|
|
@ -30,8 +30,6 @@ const CustomizeShape = () => {
|
||||||
return <p className='text-sm font-semibold'>No active object found</p>;
|
return <p className='text-sm font-semibold'>No active object found</p>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log(activeObject?.type);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='p-1'>
|
<div className='p-1'>
|
||||||
|
|
||||||
|
|
@ -77,7 +75,7 @@ const CustomizeShape = () => {
|
||||||
<Separator className="my-2" />
|
<Separator className="my-2" />
|
||||||
|
|
||||||
{/* Text Customization */}
|
{/* Text Customization */}
|
||||||
{activeObjectType === 'text' && <TextCustomization />}
|
{activeObjectType === 'i-text' && <TextCustomization />}
|
||||||
<Separator className="my-2" />
|
<Separator className="my-2" />
|
||||||
|
|
||||||
{/* Add image into shape */}
|
{/* Add image into shape */}
|
||||||
|
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
const exportScaledCanvasImage = (scale = 2, clipRect = null) => {
|
|
||||||
if (canvas) {
|
|
||||||
// If a clipPath is provided, apply it to the canvas
|
|
||||||
if (clipRect) {
|
|
||||||
canvas.set("clipPath", clipRect);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Export the image with the scale
|
|
||||||
const imageBase64 = canvas.toDataURL({
|
|
||||||
format: 'png', // or 'jpeg'
|
|
||||||
quality: 1, // (0 to 1) for JPEG compression, ignored for PNG
|
|
||||||
multiplier: scale, // Scale the canvas size
|
|
||||||
});
|
|
||||||
|
|
||||||
// Download the scaled image
|
|
||||||
const link = document.createElement('a');
|
|
||||||
link.href = imageBase64;
|
|
||||||
link.download = `canvas-image-${scale}x.png`;
|
|
||||||
link.click();
|
|
||||||
|
|
||||||
// After downloading, clear the clipping (optional)
|
|
||||||
if (clipRect) {
|
|
||||||
canvas.setClipPath(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Example: Crop area and then export
|
|
||||||
const clipRect = new fabric.Rect({
|
|
||||||
left: canvas?.getWidth() / 2,
|
|
||||||
top: canvas?.getHeight() / 2,
|
|
||||||
originX: 'center', // Use center origin
|
|
||||||
originY: 'center',
|
|
||||||
width: 200, // Size of the clip area
|
|
||||||
height: 200, // Size of the clip area
|
|
||||||
absolutePositioned: true, // Ensure clipping path stays in place
|
|
||||||
});
|
|
||||||
Loading…
Add table
Reference in a new issue