203 lines
8 KiB
JavaScript
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;
|