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

203 lines
8 KiB
JavaScript

import { useContext, useEffect } from 'react'
import { Label } from './ui/label';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from './ui/select';
import { Input } from './ui/input';
import ColorContext from './Context/colorContext/ColorContext';
import CanvasContext from './Context/canvasContext/CanvasContext';
import { fabric } from 'fabric';
const ColorComponent = () => {
const { canvas } = useContext(CanvasContext);
const {
backgroundType,
setBackgroundType,
solidColor,
gradientColors,
setSolidColor,
setGradientColors,
gradientDirection,
setGradientDirection,
setDirectionCoords,
directionCoords,
} = useContext(ColorContext);
const applySolidColor = (color) => {
setSolidColor(color);
};
const applyGradient = () => {
const width = canvas?.width || 0;
const height = canvas?.height || 0;
// Define coordinates for linear gradient
const linearCoords = {
"top-to-bottom": { x1: 0, y1: 0, x2: 0, y2: height },
"bottom-to-top": { x1: 0, y1: height, x2: 0, y2: 0 },
"left-to-right": { x1: 0, y1: 0, x2: width, y2: 0 },
"right-to-left": { x1: width, y1: 0, x2: 0, y2: 0 },
};
const directionCoords = linearCoords[gradientDirection];
if (directionCoords) {
setDirectionCoords(directionCoords);
} else {
console.error(`Invalid gradient direction: ${gradientDirection}`);
}
};
useEffect(() => {
if (gradientDirection && backgroundType === "gradient") {
applyGradient();
}
}, [gradientDirection, backgroundType]);
useEffect(() => {
const object = canvas?.getActiveObject();
if (!object) {
if (canvas && solidColor && backgroundType === "color") {
canvas.backgroundColor = solidColor;
canvas.renderAll();
}
if (canvas && directionCoords && gradientColors && backgroundType === "gradient") {
const gradient = new fabric.Gradient({
type: "linear",
gradientUnits: "pixels",
coords: directionCoords,
colorStops: [
{ offset: 0, color: gradientColors.color1 },
{ offset: 1, color: gradientColors.color2 },
],
});
canvas.backgroundColor = gradient;
canvas.renderAll();
}
if (canvas && gradientColors && backgroundType === "radial") {
const gradient = new fabric.Gradient({
type: "radial",
gradientUnits: "pixels",
coords: {
x1: canvas.width / 2,
y1: canvas.height / 2,
r1: 0,
x2: canvas.width / 2,
y2: canvas.height / 2,
r2: Math.min(canvas.width, canvas.height) / 2,
},
colorStops: [
{ offset: 0, color: gradientColors.color1 },
{ offset: 1, color: gradientColors.color2 },
],
});
canvas.backgroundColor = gradient;
canvas.renderAll();
}
}
}, [gradientColors, directionCoords, solidColor, canvas, backgroundType]);
return (
<div className='flex flex-wrap my-2 gap-2'>
<div className='flex gap-2 flex-wrap mb-auto'>
<Label>Background Type:</Label>
<Select value={backgroundType} onValueChange={setBackgroundType}>
<SelectTrigger>
<SelectValue placeholder="Select background type" />
</SelectTrigger>
<SelectContent>
<SelectItem value="color">Solid Color</SelectItem>
<SelectItem value="gradient">Linear Gradient</SelectItem>
<SelectItem value="radial">Radial Gradient</SelectItem>
</SelectContent>
</Select>
</div>
{backgroundType === "color" ? (
<div className='flex flex-col gap-2'>
<Label>Solid Color:</Label>
<Input
type="color"
value={solidColor}
onChange={(e) => applySolidColor(e.target.value)}
/>
</div>
) : backgroundType === "gradient" ? (
<div className='grid grid-cols-1 gap-2'>
<div className='flex flex-wrap gap-2'>
<Label>Direction:</Label>
<Select
value={gradientDirection}
onValueChange={(value) => {
setGradientDirection(value);
}}
>
<SelectTrigger>
<SelectValue placeholder="Select direction" />
</SelectTrigger>
<SelectContent>
<SelectItem value="top-to-bottom">Top to Bottom</SelectItem>
<SelectItem value="bottom-to-top">Bottom to Top</SelectItem>
<SelectItem value="left-to-right">Left to Right</SelectItem>
<SelectItem value="right-to-left">Right to Left</SelectItem>
</SelectContent>
</Select>
</div>
<div className='flex gap-2 flex-wrap'>
<Label>Color 1:</Label>
<Input
type="color"
value={gradientColors.color1}
onChange={(e) =>
setGradientColors((prev) => ({
...prev,
color1: e.target.value,
}))}
/>
</div>
<div className='flex flex-wrap gap-2'>
<Label>Color 2:</Label>
<Input
type="color"
value={gradientColors.color2}
onChange={(e) =>
setGradientColors((prev) => ({
...prev,
color2: e.target.value,
}))}
/>
</div>
</div>
) : (
<div className='flex flex-wrap gap-2'>
<div className='flex gap-2 flex-wrap'>
<Label>Color 1:</Label>
<Input
type="color"
value={gradientColors.color1}
onChange={(e) =>
setGradientColors((prev) => ({
...prev,
color1: e.target.value,
}))}
/>
</div>
<div className='flex flex-wrap gap-2'>
<Label>Color 2:</Label>
<Input
type="color"
value={gradientColors.color2}
onChange={(e) =>
setGradientColors((prev) => ({
...prev,
color2: e.target.value,
}))}
/>
</div>
</div>
)}
</div>
);
};
export default ColorComponent;