Genesis
This commit is contained in:
83
src/Tile.jsx
Normal file
83
src/Tile.jsx
Normal file
@@ -0,0 +1,83 @@
|
||||
import React, { useRef, useState } from 'react';
|
||||
import { Rect, Group, Transformer } from 'react-konva';
|
||||
|
||||
export function Tile({ id, 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={(e) => {
|
||||
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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user