85 lines
3.3 KiB
JavaScript
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>
|
|
);
|
|
}
|