Files
raumPlaner/src/Tile.jsx

85 lines
3.3 KiB
JavaScript

import React, { useRef } from 'react';
import { Rect, Group, Transformer } from 'react-konva';
export function Tile({ initialX, initialY, scale, meterWidth = 1.6, meterHeight = 1.6, color = "rgba(16, 185, 129, 0.6)", stroke = "#10b981", isSelected, onSelect, type, rotation = 0, onChange }) {
const shapeRef = useRef();
const trRef = useRef();
const pixelWidth = meterWidth * scale;
const pixelHeight = meterHeight * scale;
// Sync up transformer when selected
React.useEffect(() => {
if (isSelected && trRef.current && shapeRef.current) {
trRef.current.nodes([shapeRef.current]);
trRef.current.getLayer().batchDraw();
}
}, [isSelected]);
const isLight = type === 'light';
return (
<Group>
<Rect
x={initialX}
y={initialY}
rotation={rotation}
width={pixelWidth}
height={pixelHeight}
fill={isLight ? null : color}
fillRadialGradientStartPoint={isLight ? { x: pixelWidth / 2, y: pixelHeight / 2 } : null}
fillRadialGradientStartRadius={isLight ? 0 : null}
fillRadialGradientEndPoint={isLight ? { x: pixelWidth / 2, y: pixelHeight / 2 } : null}
fillRadialGradientEndRadius={isLight ? Math.min(pixelWidth, pixelHeight) / 2 : null}
fillRadialGradientColorStops={isLight ? [0, 'rgba(253, 224, 71, 0.8)', 0.6, 'rgba(253, 224, 71, 0.5)', 1, 'rgba(253, 224, 71, 0)'] : null}
stroke={isLight ? null : stroke}
strokeWidth={isLight ? 0 : 2}
draggable
// Origin at center so rotation is around the center
offsetX={pixelWidth / 2}
offsetY={pixelHeight / 2}
ref={shapeRef}
onClick={onSelect}
onTap={onSelect}
shadowColor="rgba(0,0,0,0.5)"
shadowBlur={isSelected ? 10 : 5}
shadowOffset={{ x: 2, y: 2 }}
onDragStart={(e) => {
onSelect();
// visually pop out
e.target.moveToTop();
}}
onDragEnd={(e) => {
onChange && onChange({
x: e.target.x(),
y: e.target.y()
});
}}
onTransformEnd={() => {
const node = shapeRef.current;
node.scaleX(1);
node.scaleY(1);
onChange && onChange({
x: node.x(),
y: node.y(),
rotation: node.rotation()
});
}}
/>
{isSelected && (
<Transformer
ref={trRef}
resizeEnabled={false} // Only allow rotation
rotateEnabled={true}
centeredScaling={true}
rotationSnaps={[0, 45, 90, 135, 180, 225, 270, 315]}
anchorSize={8}
borderStroke="#facc15"
anchorStroke="#facc15"
anchorFill="#fff"
/>
)}
</Group>
);
}