diff --git a/components/tools/ManipulationPanel.tsx b/components/tools/ManipulationPanel.tsx index 8cee83e..6ae7344 100644 --- a/components/tools/ManipulationPanel.tsx +++ b/components/tools/ManipulationPanel.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useState, useEffect, useRef, useCallback } from 'react'; +import { useState } from 'react'; import { Slider } from '@/components/ui/slider'; import { Button } from '@/components/ui/button'; import { @@ -19,11 +19,11 @@ interface ManipulationPanelProps { } export function ManipulationPanel({ color, onColorChange }: ManipulationPanelProps) { - const [lightenAmount, setLightenAmount] = useState(0); - const [darkenAmount, setDarkenAmount] = useState(0); - const [saturateAmount, setSaturateAmount] = useState(0); - const [desaturateAmount, setDesaturateAmount] = useState(0); - const [rotateAmount, setRotateAmount] = useState(0); + const [lightenAmount, setLightenAmount] = useState(0.2); + const [darkenAmount, setDarkenAmount] = useState(0.2); + const [saturateAmount, setSaturateAmount] = useState(0.2); + const [desaturateAmount, setDesaturateAmount] = useState(0.2); + const [rotateAmount, setRotateAmount] = useState(30); const lightenMutation = useLighten(); const darkenMutation = useDarken(); @@ -32,101 +32,80 @@ export function ManipulationPanel({ color, onColorChange }: ManipulationPanelPro const rotateMutation = useRotate(); const complementMutation = useComplement(); - // Track if we're applying our own changes to prevent feedback loop - const isApplyingRef = useRef(false); - const baseColorRef = useRef(color); - - // Update base color only when not applying our own changes - useEffect(() => { - if (!isApplyingRef.current) { - baseColorRef.current = color; - // Reset sliders when color changes externally - setLightenAmount(0); - setDarkenAmount(0); - setSaturateAmount(0); - setDesaturateAmount(0); - setRotateAmount(0); + const handleLighten = async () => { + try { + const result = await lightenMutation.mutateAsync({ + colors: [color], + amount: lightenAmount, + }); + if (result.colors[0]) { + onColorChange(result.colors[0].output); + toast.success(`Lightened by ${(lightenAmount * 100).toFixed(0)}%`); + } + } catch (error) { + toast.error('Failed to lighten color'); } - }, [color]); + }; - // Debounced effect to apply manipulations - useEffect(() => { - const timer = setTimeout(async () => { - // Skip if all sliders are at neutral position - if (lightenAmount === 0 && darkenAmount === 0 && saturateAmount === 0 && - desaturateAmount === 0 && rotateAmount === 0) { - return; + const handleDarken = async () => { + try { + const result = await darkenMutation.mutateAsync({ + colors: [color], + amount: darkenAmount, + }); + if (result.colors[0]) { + onColorChange(result.colors[0].output); + toast.success(`Darkened by ${(darkenAmount * 100).toFixed(0)}%`); } + } catch (error) { + toast.error('Failed to darken color'); + } + }; - isApplyingRef.current = true; - let currentColor = baseColorRef.current; - - try { - // Apply lighten - if (lightenAmount > 0) { - const result = await lightenMutation.mutateAsync({ - colors: [currentColor], - amount: lightenAmount, - }); - if (result.colors[0]) { - currentColor = result.colors[0].output; - } - } - - // Apply darken - if (darkenAmount > 0) { - const result = await darkenMutation.mutateAsync({ - colors: [currentColor], - amount: darkenAmount, - }); - if (result.colors[0]) { - currentColor = result.colors[0].output; - } - } - - // Apply saturate - if (saturateAmount > 0) { - const result = await saturateMutation.mutateAsync({ - colors: [currentColor], - amount: saturateAmount, - }); - if (result.colors[0]) { - currentColor = result.colors[0].output; - } - } - - // Apply desaturate - if (desaturateAmount > 0) { - const result = await desaturateMutation.mutateAsync({ - colors: [currentColor], - amount: desaturateAmount, - }); - if (result.colors[0]) { - currentColor = result.colors[0].output; - } - } - - // Apply rotate - if (rotateAmount !== 0) { - const result = await rotateMutation.mutateAsync({ - colors: [currentColor], - amount: rotateAmount, - }); - if (result.colors[0]) { - currentColor = result.colors[0].output; - } - } - - onColorChange(currentColor); - } catch (error) { - // Silent error during manipulation - } finally { - isApplyingRef.current = false; + const handleSaturate = async () => { + try { + const result = await saturateMutation.mutateAsync({ + colors: [color], + amount: saturateAmount, + }); + if (result.colors[0]) { + onColorChange(result.colors[0].output); + toast.success(`Saturated by ${(saturateAmount * 100).toFixed(0)}%`); } - }, 300); + } catch (error) { + toast.error('Failed to saturate color'); + } + }; - return () => clearTimeout(timer); - }, [lightenAmount, darkenAmount, saturateAmount, desaturateAmount, rotateAmount]); + const handleDesaturate = async () => { + try { + const result = await desaturateMutation.mutateAsync({ + colors: [color], + amount: desaturateAmount, + }); + if (result.colors[0]) { + onColorChange(result.colors[0].output); + toast.success(`Desaturated by ${(desaturateAmount * 100).toFixed(0)}%`); + } + } catch (error) { + toast.error('Failed to desaturate color'); + } + }; + + const handleRotate = async () => { + try { + const result = await rotateMutation.mutateAsync({ + colors: [color], + amount: rotateAmount, + }); + if (result.colors[0]) { + onColorChange(result.colors[0].output); + toast.success(`Rotated hue by ${rotateAmount}°`); + } + } catch (error) { + toast.error('Failed to rotate hue'); + } + }; const handleComplement = async () => { try { @@ -151,7 +130,7 @@ export function ManipulationPanel({ color, onColorChange }: ManipulationPanelPro return (