Skip to content

Commit

Permalink
fix: move draw function to helper file
Browse files Browse the repository at this point in the history
  • Loading branch information
bertyhell committed Aug 16, 2024
1 parent f47c07e commit f02d417
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 112 deletions.
201 changes: 89 additions & 112 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
MouseEvent,
useCallback,
useEffect,
useMemo,
useState,
WheelEvent,
} from 'react';
Expand All @@ -16,27 +17,11 @@ import {
MOUSE_ZOOM_MULTIPLIER,
SNAP_POINT_DISTANCE,
} from './App.consts.ts';
import {
clearCanvas,
drawActiveEntity,
drawCursor,
drawDebugEntities,
drawEntities,
drawHelpers,
drawSnapPoint,
} from './helpers/draw-functions.ts';
import { Toolbar } from './components/Toolbar.tsx';
import { findClosestEntity } from './helpers/find-closest-entity.ts';
import { convertEntitiesToSvgString } from './helpers/export-entities-to-svg.ts';
import { saveAs } from 'file-saver';
import { compact } from './helpers/compact.ts';
import {
getClosestSnapPoint,
getClosestSnapPointWithinRadius,
} from './helpers/get-closest-snap-point.ts';
import { isPointEqual } from './helpers/is-point-equal.ts';
import { getDrawHelpers } from './helpers/get-draw-guides.ts';
import { trackHoveredSnapPoint } from './helpers/track-hovered-snap-points.ts';
import { getClosestSnapPointWithinRadius } from './helpers/get-closest-snap-point.ts';
import { handleSelectToolClick } from './helpers/tools/select-tool.ts';
import {
deSelectAndDeHighlightEntities,
Expand All @@ -46,7 +31,9 @@ import { handleCircleToolClick } from './helpers/tools/circle-tool.ts';
import { handleRectangleToolClick } from './helpers/tools/rectangle-tool.ts';
import { handleLineToolClick } from './helpers/tools/line-tool.ts';
import { screenToWorld } from './helpers/world-screen-conversion.ts';
import { LineEntity } from './entities/LineEntity.ts';
import { findClosestEntity } from './helpers/find-closest-entity.ts';
import { draw } from './helpers/draw.ts';
import { getDrawHelpers } from './helpers/get-draw-guides.ts';

function App() {
const [canvasSize, setCanvasSize] = useState<Point>(new Point(0, 0));
Expand All @@ -57,13 +44,7 @@ function App() {
const [activeTool, setActiveTool] = useState(Tool.Line);
const [entities, setEntities] = useState<Entity[]>([]);
const [activeEntity, setActiveEntity] = useState<Entity | null>(null);
const [shouldDrawCursor, setShouldDrawCursor] = useState(false);
const [helperEntities, setHelperEntities] = useState<Entity[]>([
new LineEntity(new Point(0, 0), new Point(0, 1000)),
new LineEntity(new Point(0, 0), new Point(1000, 0)),
new LineEntity(new Point(100, 0), new Point(100, 1000)),
new LineEntity(new Point(0, 100), new Point(1000, 100)),
]);
const [shouldDrawCursor, setShouldDrawCursor] = useState(true);
const [debugEntities] = useState<Entity[]>([]);
const [angleStep, setAngleStep] = useState(45);
const [screenOffset, setScreenOffset] = useState<Point>(new Point(0, 0));
Expand Down Expand Up @@ -99,6 +80,10 @@ function App() {
height: window.innerHeight,
});
setCanvasSize(new Point(window.innerWidth, window.innerHeight));
if (canvasRef.current) {
canvasRef.current.width = window.innerWidth;
canvasRef.current.height = window.innerHeight;
}
};

function handleMouseUpPoint(
Expand Down Expand Up @@ -176,7 +161,7 @@ function App() {
}

function handleMouseOut() {
setShouldDrawCursor(false);
// setShouldDrawCursor(false);
}

/**
Expand Down Expand Up @@ -310,58 +295,6 @@ function App() {
saveAs(blob, 'open-web-cad--drawing.svg');
}, [canvasSize, entities]);

const draw = useCallback(
(context: CanvasRenderingContext2D) => {
const drawInfo: DrawInfo = {
context,
canvasSize,
worldMouseLocation: worldMouseLocation,
screenMouseLocation: screenMouseLocation,
screenOffset,
screenZoom: screenScale,
};

clearCanvas(drawInfo);

drawHelpers(drawInfo, helperEntities);
drawEntities(drawInfo, entities);
drawDebugEntities(drawInfo, debugEntities);
drawActiveEntity(drawInfo, activeEntity);

const [, closestSnapPoint] = getClosestSnapPoint(
compact([snapPoint, snapPointOnAngleGuide]),
worldMouseLocation,
);
const isMarked =
!!closestSnapPoint &&
hoveredSnapPoints.some(hoveredSnapPoint =>
isPointEqual(
hoveredSnapPoint.snapPoint.point,
closestSnapPoint.point,
),
);
// console.log('isMarked: ', isMarked);
drawSnapPoint(drawInfo, closestSnapPoint, isMarked);

drawCursor(drawInfo, shouldDrawCursor);
},
[
activeEntity,
canvasSize,
debugEntities,
entities,
helperEntities,
hoveredSnapPoints,
screenMouseLocation,
screenOffset,
screenScale,
shouldDrawCursor,
snapPoint,
snapPointOnAngleGuide,
worldMouseLocation,
],
);

/**
* Init the canvas and add event listeners
*/
Expand All @@ -372,6 +305,13 @@ function App() {

handleWindowResize();

// const context = canvasRef?.current?.getContext('2d');
// if (!context) {
// console.error('No canvas context');
// return;
// }
// startDrawLoop(context);

return () => {
document.removeEventListener('keyup', handleKeyUp);
window.removeEventListener('resize', handleWindowResize);
Expand All @@ -382,19 +322,19 @@ function App() {
/**
* Keep track of the hovered snap points
*/
useEffect(() => {
const watchSnapPointTimerId = setInterval(() => {
trackHoveredSnapPoint(
snapPoint,
hoveredSnapPoints,
setHoveredSnapPoints,
SNAP_POINT_DISTANCE / screenScale,
);
}, 100);
return () => {
clearInterval(watchSnapPointTimerId);
};
}, [hoveredSnapPoints, snapPoint]);
// useEffect(() => {
// const watchSnapPointTimerId = setInterval(() => {
// trackHoveredSnapPoint(
// snapPoint,
// hoveredSnapPoints,
// setHoveredSnapPoints,
// SNAP_POINT_DISTANCE / screenScale,
// );
// }, 100);
// return () => {
// clearInterval(watchSnapPointTimerId);
// };
// }, [hoveredSnapPoints, snapPoint]);

/**
* Redraw the canvas when the mouse moves or the window resizes
Expand All @@ -404,20 +344,17 @@ function App() {
canvasRef.current?.getContext('2d');
if (!context) return;

draw(context);
}, [
canvasSize.x,
canvasSize.y,
screenMouseLocation.x,
screenMouseLocation.y,
draw,
canvasRef,
]);

/**
* Show the angle guides and closest snap point when drawing a shape
*/
useEffect(() => {
const drawInfo: DrawInfo = {
context,
canvasSize,
worldMouseLocation: worldMouseLocation,
screenMouseLocation: screenMouseLocation,
screenOffset,
screenZoom: screenScale,
};
let helperEntitiesTemp: Entity[] = [];
let snapPointTemp: SnapPoint | null = null;
let snapPointOnAngleGuideTemp: SnapPoint | null = null;
if ([Tool.Line, Tool.Rectangle, Tool.Circle].includes(activeTool)) {
// If you're in the progress of drawing a shape, show the angle guides and closest snap point
let firstPoint: Point | null = null;
Expand All @@ -440,22 +377,58 @@ function App() {
angleStep,
SNAP_POINT_DISTANCE / screenScale,
);
setHelperEntities(angleGuides);
setSnapPoint(entitySnapPoint);
setSnapPointOnAngleGuide(angleSnapPoint);
helperEntitiesTemp = angleGuides;
snapPointTemp = entitySnapPoint;
snapPointOnAngleGuideTemp = angleSnapPoint;
// setHelperEntities(angleGuides);
// setSnapPoint(entitySnapPoint);
// setSnapPointOnAngleGuide(angleSnapPoint);
}
draw(
drawInfo,
entities,
debugEntities,
helperEntitiesTemp,
activeEntity,
snapPointTemp,
snapPointOnAngleGuideTemp,
hoveredSnapPoints,
worldMouseLocation,
shouldDrawCursor,
);
}, [
activeEntity,
activeTool,
angleStep,
canvasRef,
canvasSize,
debugEntities,
entities,
hoveredSnapPoints,
screenMouseLocation,
screenOffset,
screenScale,
shouldDrawCursor,
worldMouseLocation,
]);

/**
* Show the angle guides and closest snap point when drawing a shape
*/
// useEffect(() => {
//
// }, [
// // activeEntity,
// activeTool,
// angleStep,
// // entities,
// // hoveredSnapPoints,
// // screenMouseLocation,
// // screenOffset,
// // screenScale,
// worldMouseLocation,
// ]);

/**
* Highlight the entity closest to the mouse when the select tool is active
*/
Expand All @@ -479,11 +452,9 @@ function App() {
}
}, [activeTool, setEntities, screenMouseLocation, screenOffset, screenScale]);

return (
<div>
const renderedCanvas = useMemo(() => {
return (
<canvas
width={canvasSize.x}
height={canvasSize.y}
ref={canvasRef}
onMouseDown={handleMouseDown}
onMouseMove={handleMouseMove}
Expand All @@ -492,6 +463,12 @@ function App() {
onMouseOut={handleMouseOut}
onMouseEnter={handleMouseEnter}
></canvas>
);
}, [canvasRef, handleMouseMove, handleMouseUp, handleMouseWheel]);

return (
<div>
{renderedCanvas}
<Toolbar
activeTool={activeTool}
onToolClick={handleToolClick}
Expand Down
49 changes: 49 additions & 0 deletions src/helpers/draw.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { DrawInfo, HoverPoint, SnapPoint } from '../App.types.ts';
import {
clearCanvas,
drawActiveEntity,
drawCursor,
drawDebugEntities,
drawEntities,
drawHelpers,
drawSnapPoint,
} from './draw-functions.ts';
import { getClosestSnapPoint } from './get-closest-snap-point.ts';
import { compact } from './compact.ts';
import { isPointEqual } from './is-point-equal.ts';
import { Entity } from '../entities/Entitity.ts';
import { Point } from '@flatten-js/core';

export function draw(
drawInfo: DrawInfo,
entities: Entity[],
debugEntities: Entity[],
helperEntities: Entity[],
activeEntity: Entity | null,
snapPoint: SnapPoint | null,
snapPointOnAngleGuide: SnapPoint | null,
hoveredSnapPoints: HoverPoint[],
worldMouseLocation: Point,
shouldDrawCursor: boolean,
) {
clearCanvas(drawInfo);

drawHelpers(drawInfo, helperEntities);
drawEntities(drawInfo, entities);
drawDebugEntities(drawInfo, debugEntities);
drawActiveEntity(drawInfo, activeEntity);

const [, closestSnapPoint] = getClosestSnapPoint(
compact([snapPoint, snapPointOnAngleGuide]),
worldMouseLocation,
);
const isMarked =
!!closestSnapPoint &&
hoveredSnapPoints.some(hoveredSnapPoint =>
isPointEqual(hoveredSnapPoint.snapPoint.point, closestSnapPoint.point),
);
// console.log('isMarked: ', isMarked);
drawSnapPoint(drawInfo, closestSnapPoint, isMarked);

drawCursor(drawInfo, shouldDrawCursor);
}

0 comments on commit f02d417

Please sign in to comment.