Skip to content

Commit b6aa6e2

Browse files
Add files via upload
1 parent afb95ad commit b6aa6e2

File tree

1 file changed

+156
-0
lines changed

1 file changed

+156
-0
lines changed

canvasExample.js

+156
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
import React, { useState, useEffect,useRef } from "react";
2+
import debounce from 'lodash.debounce';
3+
4+
5+
const CanvasExample = props => {
6+
7+
const {toggle, addressInfo, backgroundImage, ...rest} = props;
8+
const canvasRef = useRef(null);
9+
const [coordinates,setCoordinates] = useState([]);
10+
const [polyComplete,setPolyComplete] = useState(false);
11+
const hitboxSize =4;
12+
const black ="rgb(0,0,0)";
13+
const lightGreen = "rgba(0,255,0,0.2)";
14+
15+
16+
useEffect(()=>{
17+
debounce(() =>{
18+
clearScreen();
19+
},50);
20+
21+
},[canvasRef.current])
22+
23+
24+
const clearScreen = () =>{
25+
let ctx = canvasRef.current.getContext("2d");
26+
ctx.clearRect(0, 0, canvasRef.current.width, canvasRef.current.height);
27+
}
28+
29+
30+
useEffect( () => {
31+
//draw dots if there is 1 or more coordinates
32+
if(coordinates.length>=1){
33+
reDrawDots();
34+
}
35+
//draw lines if there are 2 or more coordinates
36+
if(coordinates.length>=2){
37+
reDrawLines();
38+
}
39+
},[coordinates])
40+
41+
42+
const reDrawLines = () => {
43+
let ctx = canvasRef.current.getContext("2d");
44+
ctx.beginPath();
45+
let first = true;
46+
for(let i =0; i<coordinates.length; i++) {
47+
let coord= coordinates[i];
48+
if(first){
49+
ctx.moveTo(coord.x,coord.y);
50+
first=false;
51+
}
52+
else{
53+
ctx.lineTo(coord.x,coord.y);
54+
}
55+
}
56+
if(polyComplete){
57+
ctx.closePath();
58+
ctx.fillStyle = lightGreen;
59+
ctx.fill();
60+
}
61+
ctx.stroke();
62+
}
63+
64+
const reDrawDots = () => {
65+
let ctx = canvasRef.current.getContext("2d");
66+
for(let i =0; i<coordinates.length; i++) {
67+
let coord= coordinates[i];
68+
ctx.beginPath();
69+
ctx.arc(coord.x,coord.y,hitboxSize,0, 2*Math.PI);
70+
ctx.fillStyle = black;
71+
ctx.fill();
72+
}
73+
}
74+
75+
76+
const canvasClick = e => {
77+
if(!polyComplete) {
78+
let first = coordinates[0];
79+
let rect = canvasRef.current.getBoundingClientRect();
80+
//client x any y are just window coords we need the coords relative to inside the canvas
81+
82+
let current = {x: Math.round(e.clientX - rect.left), y: Math.round(e.clientY - rect.top)};
83+
let deepcopy = Array.from(coordinates);
84+
85+
//check to see if we are close enough to complete the polygon
86+
if(first){
87+
let distX= Math.abs(current.x - first.x);
88+
let distY= Math.abs(current.y - first.y);
89+
if(distX <= hitboxSize
90+
&& distY <= hitboxSize
91+
&& deepcopy.length>2) {
92+
//if we are close enough, do not add the last coordinate,
93+
// just complete the polygon
94+
setPolyComplete(true);
95+
} else{
96+
//add the coordinate, draw the line, draw the dot
97+
deepcopy.push(current);
98+
}
99+
}
100+
else{
101+
//add the coordinate, draw the dot
102+
deepcopy.push(current);
103+
}
104+
setCoordinates(deepcopy);
105+
}
106+
}
107+
108+
109+
const resetCoords = () => {
110+
clearScreen();
111+
setCoordinates([]);
112+
setPolyComplete(false);
113+
}
114+
115+
const undo = () => {
116+
clearScreen();
117+
setCoordinates(coordinates.slice(0,-1));
118+
setPolyComplete(false);
119+
}
120+
121+
const finish = async () => {
122+
123+
if(coordinates!=[]){
124+
const coords= coordinates.map(c =>c.x +" " +c.y).toString();
125+
//your api call here to save the coords
126+
}
127+
}
128+
129+
130+
return (
131+
<div>
132+
{backgroundImage &&
133+
<canvas
134+
ref = {canvasRef}
135+
onClick = {(e) => canvasClick(e) }
136+
width={1000}
137+
height={700}
138+
style ={{borderWidth:"1px",borderColor:"black",borderStyle:"solid"
139+
,background: 'url('+backgroundImage+')' }}
140+
>
141+
142+
</canvas>
143+
}
144+
145+
<div style={{display:'flex',flex:1,flexDirection:'row',width:'100%',paddingTop:'1rem'}}>
146+
<div style={{ display:'flex', flex:1, flexDirection:'row', width:'100%'}}>
147+
<button title="Undo" onClick={() =>undo()}/>
148+
<button title="Reset" onClick={() =>resetCoords()}/>
149+
<button title="Complete" onClick={() =>finish()}/>
150+
</div>
151+
</div>
152+
</div>
153+
);
154+
155+
}
156+
export default CanvasExample;

0 commit comments

Comments
 (0)