Reputation: 6305
I have the following code file App.js
, using this code I am able to draw square/rectangle shape using mouse events.
see working here : https://www.awesomescreenshot.com/video/18588785?key=8a5877587128b9d65b77999becd3f2e3
App.js File code:
import store from './store/store'
import { Provider } from 'react-redux';
import DrawAnnotations from "./components/DrawAnnotations";
function App() {
return (
<div>
<Provider store={store}>
<DrawAnnotations />
</Provider>
</div>
);
}
export default App;
DrawAnnotations.js File Code
import React, { useState } from "react";
import { useSelector, useDispatch } from 'react-redux';
import {
setMouseDownReading,
setMouseUpReading,
measureLength,
setMouseDownAnnotations,
setMouseMoveAnnotations,
setMouseUpAnnotations,
setAnnotationsToDraw
} from "../store/dataReadingSlice";
import {
Stage,
Layer,
Rect,
Group,
Label,
Text,
Line,
} from "react-konva";
const DrawAnnotations = (props) => {
const dispatch = useDispatch();
const dataReading = useSelector((state) => state.dataReading);
const [annotations, setAnnotations] = useState([]);
const [newAnnotation, setNewAnnotation] = useState([]);
const handleMouseDown = event => {
if (newAnnotation.length === 0) {
const { x, y } = event.target.getStage().getPointerPosition();
let mouseDownCoords = {
x: x, y: y
}
dispatch(setMouseDownReading(mouseDownCoords))
dispatch(setMouseDownAnnotations({ x, y, width: 0, height: 0, key: "0" }))
setNewAnnotation([{ x, y, width: 0, height: 0, key: "0" }]);
}
};
const handleMouseUp = event => {
if (newAnnotation.length === 1) {
const sx = newAnnotation[0].x;
const sy = newAnnotation[0].y;
const { x, y } = event.target.getStage().getPointerPosition();
let mouseUpCoords = {
x: x, y: y
}
dispatch(setMouseUpReading(mouseUpCoords))
const annotationToAdd = {
x: sx,
y: sy,
width: x - sx,
height: y - sy,
key: annotations.length + 1,
strokeWidth: 10,
stroke: '#F75200',
dashwidth: [0, 0]
};
dispatch(setMouseUpAnnotations(annotationToAdd))
annotations.push(annotationToAdd);
dispatch(measureLength())
setNewAnnotation([]);
setAnnotations(annotations);
//dispatch(setAnnotationsToDraw(annotationsToDraw))
}
};
const handleMouseMove = event => {
if (newAnnotation.length === 1) {
const sx = newAnnotation[0].x;
const sy = newAnnotation[0].y;
const { x, y } = event.target.getStage().getPointerPosition();
dispatch(setMouseMoveAnnotations(
{
x: sx,
y: sy,
width: x - sx,
height: y - sy,
key: "0"
}
))
setNewAnnotation([
{
x: sx,
y: sy,
width: x - sx,
height: y - sy,
key: "0"
}
]);
}
};
const handler = (e) => {
e.stopPropagation();
e.preventDefault();
}
const annotationsToDraw = [...annotations, ...newAnnotation];
return (
<Stage
onMouseDown={handleMouseDown}
onMouseUp={handleMouseUp}
onMouseMove={handleMouseMove}
width={1200}
height={1000}
>
{dataReading.rectangles.length > 0 &&
dataReading.rectangles.map((rectangle, rectIndex) => {
return (
<Layer key={rectIndex}>
{
rectangle.annotationsData.map((value, index) => {
//annotationsToDraw.map((value, index) => {
return (
<Group key={index}>
{/* Line for X */}
{value.width > 20 &&
<>
<Line
points={[0, 0, rectangle.measureXYLength.x, 0]}
stroke='blue'
strokeWidth={5}
lineJoin='round'
x={value.x}
y={value.y - 25}
/>
<Label
x={(value.x + value.width) / 2}
y={value.y - 50}
>
<Text
text={rectangle.measureXYLength.x + " px"}
padding={10}
height={30}
width={150}
verticalAlign="middle"
/>
</Label>
</>
}
{/* Rectangle */}
<Rect
x={value.x}
y={value.y}
width={value.width}
height={value.height}
fill="#C5E6ED"
stroke={value.stroke ? value.stroke : 'blue'}
strokeWidth={value.strokeWidth}
dash={value.dashwidth ? value.dashwidth : [5, 5]}
shadowBlur={10}
/>
{/* Line for Y */}
{value.height > 20 &&
<>
<Line
points={[-20, 0, -20, rectangle.measureXYLength.y]}
stroke='red'
strokeWidth={5}
lineJoin='round'
x={value.x}
y={value.y}
/>
<Label
x={value.x - 75}
y={(value.y + value.height ) / 2}
>
<Text
text={rectangle.measureXYLength.y + " px"}
height={30}
width={100}
verticalAlign="middle"
/>
</Label>
</>
}
</Group>
);
})
}
</Layer>
)
})}
</Stage>
);
};
export default DrawAnnotations;
dataReadingSlice.js file code
const { createSlice } = require('@reduxjs/toolkit')
const dataReadingSlice = createSlice({
name: 'dataReading',
initialState: {
stateCount: {
index: 0,
},
rectangles:[{
mouseDownReading: {},
mouseUpReading: {},
measureXYLength:{x: 0,y: 0},
annotationsData: []
}
],
mouseDownReading: {},
mouseUpReading: {},
measureXYLength:{x: 0,y: 0},
annotations: [],
annotationsToDraw: []
},
reducers: {
setMouseDownReading(state, action) {
state.mouseDownReading = action.payload
},
setMouseUpReading(state, action) {
state.mouseUpReading = action.payload
},
setMouseDownAnnotations(state, action) {
state.annotations.push(action.payload)
},
setMouseMoveAnnotations(state, action) {
state.annotations.push(action.payload)
},
setMouseUpAnnotations(state, action) {
state.annotations = []
state.annotations.push(action.payload)
},
measureLength(state, action) {
let indexCount = state.stateCount.index
state.rectangles[indexCount] = {
mouseDownReading: state.mouseDownReading,
mouseUpReading : state.mouseUpReading,
measureXYLength:{
x: parseFloat(state.mouseUpReading.x) - parseFloat(state.mouseDownReading.x),
y: parseFloat(state.mouseUpReading.y) - parseFloat(state.mouseDownReading.y)
},
annotationsData: state.annotations
}
state.stateCount.index = state.stateCount.index + 1
},
setAnnotationsToDraw(state, action) {
//console.log("draw method called")
//console.log(action.payload)
//state.annotationsToDraw = action.payload
}
}
})
export const {
setMouseDownReading,
setMouseUpReading,
measureLength,
setMouseDownAnnotations,
setMouseMoveAnnotations,
setMouseUpAnnotations,
setAnnotationsToDraw
} = dataReadingSlice.actions
export default dataReadingSlice.reducer
I have to make the shape as follows:
How could I display length and width of each side on the center of side? how to set their positioning as per required?
Upvotes: 1
Views: 602