Skip to content

Commit

Permalink
Merge branch 'main' of github.com:AMISH-KHAN/Draw-it-out into issue_#121
Browse files Browse the repository at this point in the history
  • Loading branch information
AMISH-KHAN committed May 20, 2024
2 parents 30fd28e + c2e3a5f commit b511ffe
Show file tree
Hide file tree
Showing 9 changed files with 1,246 additions and 39 deletions.
1,110 changes: 1,079 additions & 31 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"preview": "vite preview"
},
"dependencies": {
"fabric": "^5.3.0",
"jspdf": "^2.5.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand All @@ -28,6 +29,6 @@
"eslint-plugin-react-refresh": "^0.4.6",
"postcss": "^8.4.38",
"tailwindcss": "^3.4.3",
"vite": "^5.2.8"
"vite": "^5.2.11"
}
}
17 changes: 14 additions & 3 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { FaRegEye, FaRegEyeSlash, FaMoon, FaSun } from "react-icons/fa";

import Joyride from "react-joyride";

const tourSteps = [
const tourSteps = [
{
target: "body",
placement: "center",
Expand Down Expand Up @@ -81,8 +81,19 @@ function App() {



<Joyride steps={steps} continuous showSkipButton={true} />

<Joyride
steps={steps}
continuous
showSkipButton={true}
locale={{
back: 'Back',
close: 'Close',
last: 'Start',
next: 'Next',
skip: 'Skip',
}}
/>

<div className="bg-[#d3d5d8] flex flex-col min-w-full justify-center gsm:flex-row">

{showMenuAndBgColor && (
Expand Down
Binary file added src/assets/images/circle.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/assets/images/circle.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/assets/images/rectangle.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/assets/images/triangle.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
124 changes: 124 additions & 0 deletions src/components/DrawingShapes.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import { useEffect, useState } from "react";
import rectImg from "../assets/images/rectangle.svg";
import circleImg from "../assets/images/circle.svg";
import triangleImg from "../assets/images/triangle.svg";
import { PiPencilSimpleFill } from "react-icons/pi";

const DrawingShapes = ({ brushWidth, selectedColor, fillColor, canvasRef }) => {
const [isDrawing, setIsDrawing] = useState(false);
const [prevMouseX, setPrevMouseX] = useState(0);
const [prevMouseY, setPrevMouseY] = useState(0);
const [selectedTool, setSelectedTool] = useState("brush");
const [snapshot, setSnapshot] = useState(null);

useEffect(() => {
const canvas = canvasRef.current;
if (!canvas) return;
const ctx = canvas.getContext("2d", { willReadFrequently: true });

const drawRect = (e) => {
const currentX = e.offsetX;
const currentY = e.offsetY;
const width = currentX - prevMouseX;
const height = currentY - prevMouseY;
ctx.putImageData(snapshot, 0, 0);
if (!fillColor) {
ctx.strokeRect(prevMouseX, prevMouseY, width, height);
} else {
ctx.fillRect(prevMouseX, prevMouseY, width, height);
}
};

const drawCircle = (e) => {
ctx.putImageData(snapshot, 0, 0);
ctx.beginPath();
const radius = Math.sqrt(Math.pow(prevMouseX - e.offsetX, 2) + Math.pow(prevMouseY - e.offsetY, 2));
ctx.arc(prevMouseX, prevMouseY, radius, 0, 2 * Math.PI);
fillColor ? ctx.fill() : ctx.stroke();
};

const drawTriangle = (e) => {
ctx.putImageData(snapshot, 0, 0);
ctx.beginPath();
ctx.moveTo(prevMouseX, prevMouseY);
ctx.lineTo(e.offsetX, e.offsetY);
ctx.lineTo(prevMouseX * 2 - e.offsetX, e.offsetY);
ctx.closePath();
fillColor ? ctx.fill() : ctx.stroke();
};

const startDraw = (e) => {
setIsDrawing(true);
setPrevMouseX(e.offsetX);
setPrevMouseY(e.offsetY);
ctx.beginPath();
ctx.moveTo(e.offsetX, e.offsetY);
ctx.lineWidth = brushWidth;
ctx.strokeStyle = selectedColor;
ctx.fillStyle = selectedColor;
setSnapshot(ctx.getImageData(0, 0, canvas.width, canvas.height));
};

const drawing = (e) => {
if (!isDrawing) return;

if (selectedTool === "brush") {
ctx.lineTo(e.offsetX, e.offsetY);
ctx.stroke();
} else if (selectedTool === "rectangle") {
drawRect(e);
} else if (selectedTool === "circle") {
drawCircle(e);
} else if (selectedTool === "triangle") {
drawTriangle(e);
}
};

const stopDrawing = () => {
if (!isDrawing) return;
ctx.closePath();
setIsDrawing(false);
};

// Add event listeners
canvas.addEventListener("mousedown", startDraw);
canvas.addEventListener("mousemove", drawing);
canvas.addEventListener("mouseup", stopDrawing);
canvas.addEventListener("mouseout", stopDrawing);

// Cleanup event listeners
return () => {
canvas.removeEventListener("mousedown", startDraw);
canvas.removeEventListener("mousemove", drawing);
canvas.removeEventListener("mouseup", stopDrawing);
canvas.removeEventListener("mouseout", stopDrawing);
};
}, [brushWidth, fillColor, selectedTool, selectedColor, snapshot, canvasRef, isDrawing]);

return (
<div className="drawing-container flex">
<div className="controls">
<ul className="options flex space-x-4">
{/* <li className="option tool" id="brush" onClick={() => setSelectedTool("brush")}>
<PiPencilSimpleFill className={`text-[2rem] md:text-[3rem] p-[0.5rem] md:p-[0.8rem] shadow-black shadow-vsm rounded-[0.5rem] text-black cursor-pointer dark:bg-[#111111] dark:text-[#ffffff] transform transition duration-300 ease-in-out hover:bg-[#B7BABF] dark:hover:bg-gray-800 ${
isDrawing ? "bg-gray-400" : ""
}`} />
</li> */}
<div className="flex space-x-4 text-[2rem] md:text-[3rem] p-[0.5rem] md:p-[0.8rem] shadow-black shadow-vsm rounded-[0.5rem] text-black cursor-pointer dark:bg-[#111111] dark:text-[#ffffff] transform transition duration-300 ease-in-out hover:bg-[#B7BABF] dark:hover:bg-gray-800">
<li className="option tool " id="rectangle" onClick={() => setSelectedTool("rectangle")}>
<img src={rectImg} alt="Rectangle" />
</li>
<li className="option tool" id="circle" onClick={() => setSelectedTool("circle")}>
<img src={circleImg} alt="Circle" />
</li>
<li className="option tool" id="triangle" onClick={() => setSelectedTool("triangle")}>
<img src={triangleImg} alt="Triangle" />
</li>
</div>
</ul>
</div>
</div>
);
};

export default DrawingShapes;
22 changes: 18 additions & 4 deletions src/components/Menu.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/* eslint-disable react/prop-types */
import { PiPencilSimpleFill } from "react-icons/pi";
import { FaChevronDown } from "react-icons/fa";

import { FaFeatherPointed } from "react-icons/fa6";
import { RiScreenshot2Fill } from "react-icons/ri";
import { FaFilePdf } from "react-icons/fa";
Expand All @@ -18,11 +17,10 @@ import { PiPlus } from "react-icons/pi";
import { PiMinus } from "react-icons/pi";
import { increaseHeight } from "../utils/canvas.js";
import { decreaseHeight } from "../utils/canvas.js";
import DrawingShapes from "./DrawingShapes.jsx";
// import BgColor from "./BgColor.jsx";

const Menu = ({
isDrawing,
setIsDrawing,
thickness,
setThickness,
color,
Expand All @@ -36,6 +34,7 @@ const Menu = ({
const [pencilWidth, setPencilWidth] = useState(false);
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
const [isOpen, setIsOpen] = useState(false);
const [fillColor, setFillColor] = useState(false);

const toggleDropdown = () => {
setIsDropdownOpen(!isDropdownOpen);
Expand Down Expand Up @@ -115,7 +114,21 @@ const Menu = ({
}`}
/>
</div>

<DrawingShapes
brushWidth={thickness}
selectedColor={color}
fillColor={fillColor}
canvasRef={canvasRef}
/>
<button>
<input
type="checkbox"
id="fill-color"
onChange={(e) => setFillColor(e.target.checked)}
title="Fill Color"
/>
<label htmlFor="fill-color">Fill color</label>
</button>
<button className="relative">
<FaFeatherPointed
className={`text-[2rem] md:text-[3rem] p-[0.5rem] md:p-[0.8rem] shadow-black shadow-vsm mx-auto rounded-[0.5rem] text-black dark:bg-[#111111] dark:text-[#ffffff] cursor-pointer hover:bg-[#B7BABF]transform transition duration-300 ease-in-out ${
Expand Down Expand Up @@ -252,3 +265,4 @@ const Menu = ({
};

export default Menu;

0 comments on commit b511ffe

Please sign in to comment.