151 lines
4.4 KiB
JavaScript
151 lines
4.4 KiB
JavaScript
import ActiveObjectContext from "@/components/Context/activeObject/ObjectContext";
|
|
import CanvasContext from "@/components/Context/canvasContext/CanvasContext";
|
|
import { Button } from "@/components/ui/button";
|
|
import { Card } from "@/components/ui/card";
|
|
import { Input } from "@/components/ui/input";
|
|
import { Label } from "@/components/ui/label";
|
|
import { Slider } from "@/components/ui/slider";
|
|
import { useContext, useEffect, useState } from "react";
|
|
import CollapsibleComponent from "./CollapsibleComponent";
|
|
|
|
const ShadowCustomization = () => {
|
|
// get values from context
|
|
const { activeObject } = useContext(ActiveObjectContext);
|
|
const { canvas } = useContext(CanvasContext);
|
|
|
|
// state to handle shadow inputs
|
|
const [shadowColor, setShadowColor] = useState("");
|
|
const [offsetX, setOffsetX] = useState(5);
|
|
const [offsetY, setOffsetY] = useState(5);
|
|
const [blur, setBlur] = useState(0.5);
|
|
const [opacity, setOpacity] = useState(0.5);
|
|
|
|
useEffect(() => {
|
|
if (activeObject) {
|
|
setShadowColor(activeObject?.shadow?.color || "#db1d62");
|
|
setOffsetX(activeObject?.shadow?.offsetX || 5);
|
|
setOffsetY(activeObject?.shadow?.offsetY || 5);
|
|
setBlur(activeObject?.shadow?.blur || 0.5);
|
|
setOpacity(activeObject?.shadow?.opacity || 0.5);
|
|
}
|
|
}, [activeObject]);
|
|
|
|
const handleApplyShadow = () => {
|
|
if (activeObject && canvas) {
|
|
const shadow = {
|
|
color: shadowColor,
|
|
blur: blur,
|
|
offsetX: offsetX,
|
|
offsetY: offsetY,
|
|
opacity: opacity,
|
|
};
|
|
activeObject.set("shadow", shadow);
|
|
// Ensure object updates and renders
|
|
activeObject.dirty = true; // Mark the object as dirty for re-render
|
|
canvas.renderAll(); // Trigger canvas re-render
|
|
}
|
|
};
|
|
|
|
const handleDisableShadow = () => {
|
|
if (activeObject && canvas) {
|
|
activeObject.set("shadow", null);
|
|
canvas.renderAll();
|
|
}
|
|
};
|
|
|
|
const content = () => {
|
|
return (
|
|
<div>
|
|
<div className="space-y-2">
|
|
<div>
|
|
<Label htmlFor="shadowColor">Shadow Color</Label>
|
|
<div className="flex items-center space-x-2">
|
|
<Input
|
|
id="shadowColor"
|
|
type="color"
|
|
value={shadowColor}
|
|
onChange={(e) => setShadowColor(e.target.value)}
|
|
className="w-16 h-10"
|
|
/>
|
|
<span>{shadowColor}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<Label>Offset X: {offsetX}px</Label>
|
|
<Slider
|
|
value={[offsetX]}
|
|
onValueChange={(value) => setOffsetX(value[0])}
|
|
max={50}
|
|
min={-50}
|
|
step={1}
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<Label>Offset Y: {offsetY}px</Label>
|
|
<Slider
|
|
value={[offsetY]}
|
|
onValueChange={(value) => setOffsetY(value[0])}
|
|
max={50}
|
|
min={-50}
|
|
step={1}
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<Label>Blur: {blur}px</Label>
|
|
<Slider
|
|
value={[blur]}
|
|
onValueChange={(value) => setBlur(value[0])}
|
|
max={50}
|
|
min={0}
|
|
step={1}
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<Label>Opacity: {opacity}</Label>
|
|
<Slider
|
|
value={[opacity]}
|
|
onValueChange={(value) => setOpacity(value[0])}
|
|
max={1}
|
|
min={0}
|
|
step={0.1}
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div
|
|
className="w-32 h-32 bg-white rounded-md flex items-center justify-center mx-auto border-2 my-4"
|
|
style={{
|
|
boxShadow: `${offsetX}px ${offsetY}px ${blur}px ${shadowColor}${Math.round(
|
|
opacity * 255
|
|
)
|
|
.toString(16)
|
|
.padStart(2, "0")}`,
|
|
}}
|
|
>
|
|
<span className="text-4xl">A</span>
|
|
</div>
|
|
|
|
<div className="grid gap-2">
|
|
<Button onClick={handleApplyShadow}>Apply Shadow</Button>
|
|
<Button variant="outline" onClick={handleDisableShadow}>
|
|
Disable Shadow
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
return (
|
|
<Card className="shadow-none border-0">
|
|
<CollapsibleComponent text={"Shadow Control"}>
|
|
{content()}
|
|
</CollapsibleComponent>
|
|
</Card>
|
|
);
|
|
};
|
|
|
|
export default ShadowCustomization;
|