import React, { useState } from "react"; export default function App(){ const [points,setPoints]=useState([]); const [scale,setScale]=useState(0.01); const [result,setResult]=useState(""); const [mode,setMode]=useState("line"); const click=(e)=>{ const rect=e.target.getBoundingClientRect(); const x=e.clientX-rect.left; const y=e.clientY-rect.top; setPoints([...points,[x,y]]); }; const reset=()=>{ setPoints([]); setResult(""); }; const measureLine=()=>{ if(points.length<2)return; const [p1,p2]=points; const px=Math.sqrt((p2[0]-p1[0])**2+(p2[1]-p1[1])**2); setResult((px*scale).toFixed(2)+" ft"); }; const measureArea=()=>{ let area=0; for(let i=0;i

Contractor OS

{points.map((p,i)=>(
))}
setScale(e.target.value)} />
{mode==="line" && } {mode==="area" && }

{result}

) } import React, { useState, useRef } from "react"; export default function App() { const [points, setPoints] = useState([]); const [scale, setScale] = useState(0.01); const [result, setResult] = useState(""); const [mode, setMode] = useState("line"); const [uploadedImage, setUploadedImage] = useState(null); const [imageSize, setImageSize] = useState({ width: 0, height: 0 }); const [scaleMode, setScaleMode] = useState("custom"); // "custom", "architectural", "calibrate" const [archScale, setArchScale] = useState({ drawing: 0.25, real: 1 }); // 1/4" = 1' const [dpi, setDpi] = useState(96); // screen DPI const canvasRef = useRef(null); // Common architectural scales const commonScales = [ { label: '1/8" = 1\'', drawing: 0.125, real: 1 }, { label: '1/4" = 1\'', drawing: 0.25, real: 1 }, { label: '3/8" = 1\'', drawing: 0.375, real: 1 }, { label: '1/2" = 1\'', drawing: 0.5, real: 1 }, { label: '3/4" = 1\'', drawing: 0.75, real: 1 }, { label: '1" = 1\'', drawing: 1, real: 1 }, { label: '1 1/2" = 1\'', drawing: 1.5, real: 1 }, { label: '3" = 1\'', drawing: 3, real: 1 }, ]; const handleFileUpload = (e) => { const file = e.target.files[0]; if (file && file.type.match('image.*|application/pdf')) { const reader = new FileReader(); reader.onload = (event) => { const img = new Image(); img.onload = () => { setImageSize({ width: img.width, height: img.height }); setUploadedImage(event.target.result); setPoints([]); setResult(""); }; img.src = event.target.result; }; reader.readAsDataURL(file); } }; const calculateScale = () => { if (scaleMode === "architectural") { // Convert architectural scale to pixels per foot // drawing inches per real foot, converted to pixels const pixelsPerInch = dpi; const drawingInchesPerRealFoot = archScale.drawing / archScale.real; return drawingInchesPerRealFoot * pixelsPerInch / 12; // pixels per real foot } return parseFloat(scale); }; const click = (e) => { const rect = e.target.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; if (mode === "line" && points.length >= 2) { setPoints([[x, y]]); } else if (mode === "area" && points.length >= 1) { setPoints([...points, [x, y]]); } else { setPoints([...points, [x, y]]); } }; const reset = () => { setPoints([]); setResult(""); }; const clearDocument = () => { setUploadedImage(null); setPoints([]); setResult(""); }; const measureLine = () => { if (points.length < 2) return; const [p1, p2] = points; const pixelDistance = Math.sqrt((p2[0] - p1[0]) ** 2 + (p2[1] - p1[1]) **