Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pwa: true
29 changes: 29 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
"version": "1.0.0",
"private": true,
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.30",
"@fortawesome/free-solid-svg-icons": "^5.14.0",
"@fortawesome/react-fontawesome": "^0.1.11",
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.5.0",
"@testing-library/user-event": "^7.2.1",
"@types/lodash": "^4.14.156",
"@types/react-color": "^3.0.4",
"react": "^16.13.1",
"react-color": "^2.18.1",
"react-dom": "^16.13.1",
"react-scripts": "3.4.1",
"typescript": "^3.9.5"
Expand Down
62 changes: 41 additions & 21 deletions src/Components/CanvasComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
import React from "react";
import { SketchPicker } from "react-color";
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faEraser, faCircle, faSquare, faPaintBrush, faDownload, faSync } from '@fortawesome/free-solid-svg-icons'

interface Point {
x: number;
y: number;
}

interface Color {
hex: string;
}

class CanvasComponent extends React.Component {
colorInput;

constructor(props) {
super(props);
this.colorInput = React.createRef();
}

state = {
background: "#121212",
color: "#000000",
choice: "brush",
canvas: {} as HTMLCanvasElement,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Canvas should not be a state, it should be a ref.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically, whatever data you need to render the component (color, choice, isDrawStarted, etc.) should either be a state or prop. UI elements like canvas, websocket connection, etc are important but they are not exactly data that you want to display. They should be stored inside refs. They are also mutable which might cause undefined behaviour with state: state and props should always be immutable.

};

handleChangeComplete = (color) => {
this.setState({ background: color.hex });
handleChangeComplete = (e) => {
this.setState({ color: e.target.value });
};

componentDidMount() {
Expand All @@ -29,6 +34,11 @@ class CanvasComponent extends React.Component {
const canvas: HTMLCanvasElement = document.getElementById(
"canvas"
) as HTMLCanvasElement;

// Setting up width and height of canvas
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

const canvasWidth = canvas.width;
const canvasHeight = canvas.height;
const ctx:any = canvas.getContext("2d");
Expand All @@ -41,7 +51,7 @@ class CanvasComponent extends React.Component {
this.setState({ canvas });

ctx.beginPath();
ctx.rect(0, 0, canvasHeight, canvasWidth);
ctx.rect(0, 0, canvasWidth, canvasHeight);
ctx.fillStyle = "#ffffff";
ctx.fill();

Expand Down Expand Up @@ -112,7 +122,7 @@ class CanvasComponent extends React.Component {
plvaly = e.clientY;
}
ctx.drawImage(canvasPic, 0, 0);
ctx.fillStyle = this.state.background;
ctx.fillStyle = this.state.color;
ctx.beginPath();
ctx.rect(
lastPoint.x,
Expand Down Expand Up @@ -142,7 +152,7 @@ class CanvasComponent extends React.Component {
plvaly = e.clientY;
}
ctx.drawImage(canvasPic, 0, 0);
ctx.fillStyle = this.state.background;
ctx.fillStyle = this.state.color;
ctx.beginPath();
ctx.arc(
lastPoint.x,
Expand All @@ -169,7 +179,7 @@ class CanvasComponent extends React.Component {
for (let i = 0; i < dist; i++) {
x = lastPoint.x + Math.sin(angle) * i - 0;
y = lastPoint.y + Math.cos(angle) * i - 0;
ctx.fillStyle = this.state.background;
ctx.fillStyle = this.state.color;
ctx.beginPath();
ctx.rect(x, y, 5, 5);
ctx.fill();
Expand All @@ -192,33 +202,46 @@ class CanvasComponent extends React.Component {
render() {
return (
<React.Fragment>
<canvas id="canvas" ref="canvas" width={500} height={500} />
<canvas id="canvas" ref="canvas"/>
<div className="toolset">
<button
onClick={() => {
this.setState({ choice: "brush" });
}}
>
Brush
<FontAwesomeIcon icon={faPaintBrush}/>
</button>

<button
onClick={() => {
this.colorInput.current.value="#ffffff";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't change this directly. You should only change the state.

this.setState({ choice: "brush" });
this.setState({ color: "#ffffff" });
}}
>
<FontAwesomeIcon icon={faEraser}/>
</button>


<button
onClick={() => {
this.setState({ choice: "rectangle" });
}}
>
Rectangle
<FontAwesomeIcon icon={faSquare}/>
</button>

<button
onClick={() => {
this.setState({ choice: "circle" });
}}
>
Circle
<FontAwesomeIcon icon={faCircle}/>
</button>

<button onClick={this.updateCanvas.bind(this)}>Clear</button>
<button onClick={this.updateCanvas.bind(this)}>
<FontAwesomeIcon icon={faSync}/>
</button>

<button
onClick={() => {
Expand All @@ -228,12 +251,9 @@ class CanvasComponent extends React.Component {
link.click();
}}
>
Download
<FontAwesomeIcon icon={faDownload}/>
</button>
<SketchPicker
color={this.state.background}
onChangeComplete={this.handleChangeComplete}
/>
<input type="color" ref={this.colorInput} onChange={this.handleChangeComplete}/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The handler name can be more specific than handleChangeComplete.

Copy link
Contributor

@sriram-kailasam sriram-kailasam Aug 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Set value to this.state.color. That way, you won't have to explicitly set the value in the handler. You also won't need the ref this way.

</div>
</React.Fragment>
);
Expand Down
2 changes: 1 addition & 1 deletion src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ class Main extends React.Component {
}
}

ReactDOM.render(<Main />, document.getElementById("root"));
ReactDOM.render(<Main />, document.getElementById("root"));
2 changes: 1 addition & 1 deletion src/serviceWorker.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const isLocalhost = Boolean(
)
);

export function register(config) {
export default function register(config) {
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
// The URL constructor is available in all browsers that support SW.
const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
Expand Down
26 changes: 22 additions & 4 deletions src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,35 @@ body{
margin: 0;
overflow: hidden;
}
.main{
height: 100vh;
width: 100vw;
position: relative;
box-shadow: 0 0 5px gray;
}
canvas{
box-shadow: 0 0 5px gray;
cursor: crosshair;
}
.toolset{
float: right;
position: absolute;
top: 0;
right: 0;
display: flex;
flex-direction: column;
padding: 5px;
}
.sketch-picker{
width: 115px !Important;
.toolset > button{
height: 30px;
}
.circle-picker{
border: 1px solid rgba(0,0,0,0.4);
background-color: #e5e5e5;
text-align: center !important;
width: 90px !Important;
cursor: pointer;
}
.circle-picker > span >div{
width: 22px !important;
height: 22px !important;
margin: 2px !important;
}