80 lines
2.4 KiB
TypeScript
80 lines
2.4 KiB
TypeScript
|
|
import { useEffect, useRef } from 'react';
|
||
|
|
import { useFilterStore } from '@/store/filter-store';
|
||
|
|
import { useLayerStore } from '@/store/layer-store';
|
||
|
|
import { applyFilter } from '@/lib/filter-utils';
|
||
|
|
import { cloneCanvas } from '@/lib/canvas-utils';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Hook for previewing filters on the active layer
|
||
|
|
*/
|
||
|
|
export function useFilterPreview() {
|
||
|
|
const { activeFilter, params, isPreviewMode } = useFilterStore();
|
||
|
|
const { activeLayerId, layers } = useLayerStore();
|
||
|
|
const originalCanvasRef = useRef<HTMLCanvasElement | null>(null);
|
||
|
|
|
||
|
|
const activeLayer = layers.find((l) => l.id === activeLayerId);
|
||
|
|
|
||
|
|
// Store original canvas when preview starts
|
||
|
|
useEffect(() => {
|
||
|
|
if (isPreviewMode && activeLayer?.canvas && !originalCanvasRef.current) {
|
||
|
|
originalCanvasRef.current = cloneCanvas(activeLayer.canvas);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!isPreviewMode && originalCanvasRef.current) {
|
||
|
|
// Restore original when preview is disabled
|
||
|
|
if (activeLayer?.canvas) {
|
||
|
|
const ctx = activeLayer.canvas.getContext('2d');
|
||
|
|
if (ctx) {
|
||
|
|
ctx.clearRect(0, 0, activeLayer.canvas.width, activeLayer.canvas.height);
|
||
|
|
ctx.drawImage(originalCanvasRef.current, 0, 0);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
originalCanvasRef.current = null;
|
||
|
|
}
|
||
|
|
}, [isPreviewMode, activeLayer]);
|
||
|
|
|
||
|
|
// Apply filter preview
|
||
|
|
useEffect(() => {
|
||
|
|
if (!isPreviewMode || !activeFilter || !activeLayer?.canvas) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
const canvas = activeLayer.canvas;
|
||
|
|
const ctx = canvas.getContext('2d');
|
||
|
|
if (!ctx) return;
|
||
|
|
|
||
|
|
// Restore original
|
||
|
|
if (originalCanvasRef.current) {
|
||
|
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||
|
|
ctx.drawImage(originalCanvasRef.current, 0, 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Apply filter
|
||
|
|
try {
|
||
|
|
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
||
|
|
const filteredData = applyFilter(imageData, activeFilter, params);
|
||
|
|
ctx.putImageData(filteredData, 0, 0);
|
||
|
|
} catch (error) {
|
||
|
|
console.error('Error applying filter preview:', error);
|
||
|
|
}
|
||
|
|
}, [isPreviewMode, activeFilter, params, activeLayer]);
|
||
|
|
|
||
|
|
// Cleanup on unmount
|
||
|
|
useEffect(() => {
|
||
|
|
return () => {
|
||
|
|
if (originalCanvasRef.current && activeLayer?.canvas) {
|
||
|
|
const ctx = activeLayer.canvas.getContext('2d');
|
||
|
|
if (ctx) {
|
||
|
|
ctx.clearRect(0, 0, activeLayer.canvas.width, activeLayer.canvas.height);
|
||
|
|
ctx.drawImage(originalCanvasRef.current, 0, 0);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
};
|
||
|
|
}, []);
|
||
|
|
|
||
|
|
return {
|
||
|
|
isPreviewMode,
|
||
|
|
activeFilter,
|
||
|
|
};
|
||
|
|
}
|