Files
flatrender/src/components/image-editor/canvas/ImageBaseLayer.tsx
T

75 lines
1.8 KiB
TypeScript

"use client";
import { useEffect, useState } from "react";
import { Image } from "react-konva";
import type Konva from "konva";
import useImage from "use-image";
import {
applyAdjustmentsToNode,
buildKonvaFilterList,
} from "@/lib/image-editor-konva";
import type { ImageAdjustments, ImageLayer } from "@/lib/image-editor-types";
interface ImageBaseLayerProps {
layer: ImageLayer;
adjustments: ImageAdjustments;
interactive?: boolean;
onSelect: () => void;
registerNode: (id: string, node: Konva.Node | null) => void;
}
export function ImageBaseLayer({
layer,
adjustments,
interactive = true,
onSelect,
registerNode,
}: ImageBaseLayerProps) {
const [konvaNode, setKonvaNode] = useState<Konva.Image | null>(null);
const src =
typeof layer.props.src === "string" ? layer.props.src : undefined;
const [image] = useImage(src ?? "", "anonymous");
const filters = buildKonvaFilterList(adjustments);
useEffect(() => {
if (!konvaNode || !image) return;
applyAdjustmentsToNode(konvaNode, adjustments, filters);
}, [konvaNode, image, adjustments, filters]);
if (!image) return null;
return (
<Image
ref={(node) => {
registerNode(layer.id, node);
setKonvaNode(node);
}}
image={image}
x={layer.x}
y={layer.y}
width={layer.width}
height={layer.height}
rotation={layer.rotation}
opacity={layer.opacity}
listening={interactive}
onMouseDown={
interactive
? (event) => {
event.cancelBubble = true;
onSelect();
}
: undefined
}
onTap={
interactive
? (event) => {
event.cancelBubble = true;
onSelect();
}
: undefined
}
/>
);
}