Draw Arrow on Canvas with React-KonvaCapture HTML Canvas as gif/jpg/png/pdf?How to clear the canvas for redrawingHow to produce such page flip effects in Canvas?Using HTML5/Canvas/JavaScript to take in-browser screenshotsCanvas toDataURI() on chrome security issueLoop inside React JSXWhat do these three dots in React do?Programmatically navigate using react routerWhat is the difference between React Native and React?How to draw freely in a canvas in html 5 which is overlay above video?
Why weren't the bells paid heed to in S8E5?
How do I adjust encounters to challenge my lycanthrope players without negating their cool new abilities?
Is it wrong to omit object pronouns in these sentences?
complicated arrows in flowcharts
How to continually let my readers know what time it is in my story, in an organic way?
Is this a group? If so, what group is it?
Formal Definition of Dot Product
How does this Martian habitat 3D printer built for NASA work?
Filter a data-frame and add a new column according to the given condition
Should I communicate in my applications that I'm unemployed out of choice rather than because nobody will have me?
Segmentation fault when popping x86 stack
How to cope with regret and shame about not fully utilizing opportunities during PhD?
How to redirect stdout to a file, and stdout+stderr to another one?
Is it safe to use two single-pole breakers for a 240v circuit?
How to make a not so good looking person more appealing?
Why do the lights go out when someone enters the dining room on this ship?
How to describe a building set which is like LEGO without using the "LEGO" word?
Mark command as obsolete
Alexa-rank complaining about insecure generator meta-tag
Were any toxic metals used in the International Space Station?
Is 12 minutes connection in Bristol Temple Meads long enough?
Can a tourist shoot a gun for recreational purpose in the USA?
Why didn't the Avengers use this object earlier?
Substring join or additional table, which is faster?
Draw Arrow on Canvas with React-Konva
Capture HTML Canvas as gif/jpg/png/pdf?How to clear the canvas for redrawingHow to produce such page flip effects in Canvas?Using HTML5/Canvas/JavaScript to take in-browser screenshotsCanvas toDataURI() on chrome security issueLoop inside React JSXWhat do these three dots in React do?Programmatically navigate using react routerWhat is the difference between React Native and React?How to draw freely in a canvas in html 5 which is overlay above video?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
I would like to create a canvas where the user can draw an Arrow by using his mouse.
What I'm trying to accomplish is exactly this: https://jsfiddle.net/w33e9fpa/
But I don't understand how to convert that to React code, and my implementation currently doesn't work. When I run this code it seems that an arrow is drawn on the top left of the canvas, but nothing happens if I click on it.
Here's my code:
class DrawArrow extends Component
state =
isDrawing: false,
mode: "brush"
;
componentDidMount()
const canvas = document.createElement("canvas");
canvas.width = 300;
canvas.height = 300;
const context = canvas.getContext("2d");
this.setState( canvas, context );
handleMouseDown = () =>
this.setState( isDrawing: true );
// TODO: improve
const stage = this.arrow.parent.parent;
this.lastPointerPosition = stage.getPointerPosition();
this.setState(
posX: this.lastPointerPosition.x,
poxY: this.lastPointerPosition.y
)
handleMouseUp = () =>
this.setState( isDrawing: false );
;
handleMouseMove = () =>
if (this.state.drawing === true)
const stage = this.arrow.parent.parent;
this.lastPointerPosition = stage.getPointerPosition();
var pos = stage.getPointerPosition();
var oldPoints = this.arrow.points();
this.arrow.points([oldPoints[0], oldPoints[1], pos.x, pos.y])
this.arrow.getLayer().draw();
render()
return (
<Arrow
points= [this.state.posX,this.state.posY, this.state.posX, this.state.posY]
pointerLength= 20
pointerWidth= 20
fill= 'black'
stroke= 'black'
strokeWidth= 4
onMouseDown=this.handleMouseDown
onMouseUp=this.handleMouseUp
onMouseMove=this.handleMouseMove
/>
);
class NewWhite extends Component
render()
return (
<Stage width=900 height=700>
<Layer>
<DrawArrow />
</Layer>
</Stage>
);
Thanks for you help !
javascript reactjs canvas konvajs
add a comment |
I would like to create a canvas where the user can draw an Arrow by using his mouse.
What I'm trying to accomplish is exactly this: https://jsfiddle.net/w33e9fpa/
But I don't understand how to convert that to React code, and my implementation currently doesn't work. When I run this code it seems that an arrow is drawn on the top left of the canvas, but nothing happens if I click on it.
Here's my code:
class DrawArrow extends Component
state =
isDrawing: false,
mode: "brush"
;
componentDidMount()
const canvas = document.createElement("canvas");
canvas.width = 300;
canvas.height = 300;
const context = canvas.getContext("2d");
this.setState( canvas, context );
handleMouseDown = () =>
this.setState( isDrawing: true );
// TODO: improve
const stage = this.arrow.parent.parent;
this.lastPointerPosition = stage.getPointerPosition();
this.setState(
posX: this.lastPointerPosition.x,
poxY: this.lastPointerPosition.y
)
handleMouseUp = () =>
this.setState( isDrawing: false );
;
handleMouseMove = () =>
if (this.state.drawing === true)
const stage = this.arrow.parent.parent;
this.lastPointerPosition = stage.getPointerPosition();
var pos = stage.getPointerPosition();
var oldPoints = this.arrow.points();
this.arrow.points([oldPoints[0], oldPoints[1], pos.x, pos.y])
this.arrow.getLayer().draw();
render()
return (
<Arrow
points= [this.state.posX,this.state.posY, this.state.posX, this.state.posY]
pointerLength= 20
pointerWidth= 20
fill= 'black'
stroke= 'black'
strokeWidth= 4
onMouseDown=this.handleMouseDown
onMouseUp=this.handleMouseUp
onMouseMove=this.handleMouseMove
/>
);
class NewWhite extends Component
render()
return (
<Stage width=900 height=700>
<Layer>
<DrawArrow />
</Layer>
</Stage>
);
Thanks for you help !
javascript reactjs canvas konvajs
add a comment |
I would like to create a canvas where the user can draw an Arrow by using his mouse.
What I'm trying to accomplish is exactly this: https://jsfiddle.net/w33e9fpa/
But I don't understand how to convert that to React code, and my implementation currently doesn't work. When I run this code it seems that an arrow is drawn on the top left of the canvas, but nothing happens if I click on it.
Here's my code:
class DrawArrow extends Component
state =
isDrawing: false,
mode: "brush"
;
componentDidMount()
const canvas = document.createElement("canvas");
canvas.width = 300;
canvas.height = 300;
const context = canvas.getContext("2d");
this.setState( canvas, context );
handleMouseDown = () =>
this.setState( isDrawing: true );
// TODO: improve
const stage = this.arrow.parent.parent;
this.lastPointerPosition = stage.getPointerPosition();
this.setState(
posX: this.lastPointerPosition.x,
poxY: this.lastPointerPosition.y
)
handleMouseUp = () =>
this.setState( isDrawing: false );
;
handleMouseMove = () =>
if (this.state.drawing === true)
const stage = this.arrow.parent.parent;
this.lastPointerPosition = stage.getPointerPosition();
var pos = stage.getPointerPosition();
var oldPoints = this.arrow.points();
this.arrow.points([oldPoints[0], oldPoints[1], pos.x, pos.y])
this.arrow.getLayer().draw();
render()
return (
<Arrow
points= [this.state.posX,this.state.posY, this.state.posX, this.state.posY]
pointerLength= 20
pointerWidth= 20
fill= 'black'
stroke= 'black'
strokeWidth= 4
onMouseDown=this.handleMouseDown
onMouseUp=this.handleMouseUp
onMouseMove=this.handleMouseMove
/>
);
class NewWhite extends Component
render()
return (
<Stage width=900 height=700>
<Layer>
<DrawArrow />
</Layer>
</Stage>
);
Thanks for you help !
javascript reactjs canvas konvajs
I would like to create a canvas where the user can draw an Arrow by using his mouse.
What I'm trying to accomplish is exactly this: https://jsfiddle.net/w33e9fpa/
But I don't understand how to convert that to React code, and my implementation currently doesn't work. When I run this code it seems that an arrow is drawn on the top left of the canvas, but nothing happens if I click on it.
Here's my code:
class DrawArrow extends Component
state =
isDrawing: false,
mode: "brush"
;
componentDidMount()
const canvas = document.createElement("canvas");
canvas.width = 300;
canvas.height = 300;
const context = canvas.getContext("2d");
this.setState( canvas, context );
handleMouseDown = () =>
this.setState( isDrawing: true );
// TODO: improve
const stage = this.arrow.parent.parent;
this.lastPointerPosition = stage.getPointerPosition();
this.setState(
posX: this.lastPointerPosition.x,
poxY: this.lastPointerPosition.y
)
handleMouseUp = () =>
this.setState( isDrawing: false );
;
handleMouseMove = () =>
if (this.state.drawing === true)
const stage = this.arrow.parent.parent;
this.lastPointerPosition = stage.getPointerPosition();
var pos = stage.getPointerPosition();
var oldPoints = this.arrow.points();
this.arrow.points([oldPoints[0], oldPoints[1], pos.x, pos.y])
this.arrow.getLayer().draw();
render()
return (
<Arrow
points= [this.state.posX,this.state.posY, this.state.posX, this.state.posY]
pointerLength= 20
pointerWidth= 20
fill= 'black'
stroke= 'black'
strokeWidth= 4
onMouseDown=this.handleMouseDown
onMouseUp=this.handleMouseUp
onMouseMove=this.handleMouseMove
/>
);
class NewWhite extends Component
render()
return (
<Stage width=900 height=700>
<Layer>
<DrawArrow />
</Layer>
</Stage>
);
Thanks for you help !
javascript reactjs canvas konvajs
javascript reactjs canvas konvajs
asked Mar 23 at 13:38
Herbot SikaroHerbot Sikaro
646
646
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
Here you go:
import React, Component from "react";
import Stage, Layer, Arrow, Circle, Line from "react-konva";
import ReactDOM from "react-dom";
import "./styles.css";
class Drawable
constructor(startx, starty)
this.startx = startx;
this.starty = starty;
class ArrowDrawable extends Drawable
constructor(startx, starty)
super(startx, starty);
this.x = startx;
this.y = starty;
registerMovement(x, y)
this.x = x;
this.y = y;
render()
const points = [this.startx, this.starty, this.x, this.y];
return <Arrow points=points fill="black" stroke="black" />;
class CircleDrawable extends ArrowDrawable
constructor(startx, starty)
super(startx, starty);
this.x = startx;
this.y = starty;
render()
const dx = this.startx - this.x;
const dy = this.starty - this.y;
const radius = Math.sqrt(dx * dx + dy * dy);
return (
<Circle radius=radius x=this.startx y=this.starty stroke="black" />
);
class FreePathDrawable extends Drawable
constructor(startx, starty)
super(startx, starty);
this.points = [startx, starty];
registerMovement(x, y)
this.points = [...this.points, x, y];
render()
return <Line points=this.points fill="black" stroke="black" />;
class SceneWithDrawables extends Component
constructor(props)
super(props);
this.state =
drawables: [],
newDrawable: [],
newDrawableType: "FreePathDrawable"
;
getNewDrawableBasedOnType = (x, y, type) =>
const drawableClasses =
FreePathDrawable,
ArrowDrawable,
CircleDrawable
;
return new drawableClasses[type](x, y);
;
handleMouseDown = e =>
const newDrawable = this.state;
if (newDrawable.length === 0)
const x, y = e.target.getStage().getPointerPosition();
const newDrawable = this.getNewDrawableBasedOnType(
x,
y,
this.state.newDrawableType
);
this.setState(
newDrawable: [newDrawable]
);
;
handleMouseUp = e =>
const newDrawable, drawables = this.state;
if (newDrawable.length === 1)
const x, y = e.target.getStage().getPointerPosition();
const drawableToAdd = newDrawable[0];
drawableToAdd.registerMovement(x, y);
drawables.push(drawableToAdd);
this.setState(
newDrawable: [],
drawables
);
;
handleMouseMove = e =>
const newDrawable = this.state;
if (newDrawable.length === 1)
const x, y = e.target.getStage().getPointerPosition();
const updatedNewDrawable = newDrawable[0];
updatedNewDrawable.registerMovement(x, y);
this.setState(
newDrawable: [updatedNewDrawable]
);
;
render()
const drawables = [...this.state.drawables, ...this.state.newDrawable];
return (
<div>
<button
onClick=e =>
this.setState( newDrawableType: "ArrowDrawable" );
>
Draw Arrows
</button>
<button
onClick=e =>
this.setState( newDrawableType: "CircleDrawable" );
>
Draw Circles
</button>
<button
onClick=e =>
this.setState( newDrawableType: "FreePathDrawable" );
>
Draw FreeHand!
</button>
<Stage
onMouseDown=this.handleMouseDown
onMouseUp=this.handleMouseUp
onMouseMove=this.handleMouseMove
width=900
height=700
>
<Layer>
drawables.map(drawable =>
return drawable.render();
)
</Layer>
</Stage>
</div>
);
function App()
return <SceneWithDrawables />;
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Working example to play with:
https://codesandbox.io/s/w12qznzx5
thank you so much ! I didn't think about putting the arrow in an array and then just map it in the render. Will definitely help. Any idea on how to add multiple buttons, for example 'Pen' and 'Circle' so that the user can first choose, and then draw accordingly?
– Herbot Sikaro
Mar 23 at 18:33
1
@HerbotSikaro I added a circle and a freehand drawing option (I guess that is what you ment by pen). It made it a bit more hairy, but managed to keep it under 200 lines and rather simple. Although in your own project, you should start thinking about breaking this thing up into separate files. If you have any more questions, ask away! I'll answer within 24h
– Pärt Johanson
Mar 23 at 21:59
That is brilliant. I can't thank you enough.
– Herbot Sikaro
Mar 23 at 22:35
@HerbotSikaro this week I have lots of work to do, but I'll try to have a look at it during the weekend, if you haven't found a solution in the meantime.
– Pärt Johanson
Mar 25 at 21:11
Sure, I have been trying but I can't figure it out, so I'm kinda waiting for your help.. :/ Those last 4 functionalities all present challenges that are very hard to grasp, and the few examples that I can find online are too simple to be applicable..
– Herbot Sikaro
Mar 27 at 18:19
|
show 3 more comments
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55314284%2fdraw-arrow-on-canvas-with-react-konva%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Here you go:
import React, Component from "react";
import Stage, Layer, Arrow, Circle, Line from "react-konva";
import ReactDOM from "react-dom";
import "./styles.css";
class Drawable
constructor(startx, starty)
this.startx = startx;
this.starty = starty;
class ArrowDrawable extends Drawable
constructor(startx, starty)
super(startx, starty);
this.x = startx;
this.y = starty;
registerMovement(x, y)
this.x = x;
this.y = y;
render()
const points = [this.startx, this.starty, this.x, this.y];
return <Arrow points=points fill="black" stroke="black" />;
class CircleDrawable extends ArrowDrawable
constructor(startx, starty)
super(startx, starty);
this.x = startx;
this.y = starty;
render()
const dx = this.startx - this.x;
const dy = this.starty - this.y;
const radius = Math.sqrt(dx * dx + dy * dy);
return (
<Circle radius=radius x=this.startx y=this.starty stroke="black" />
);
class FreePathDrawable extends Drawable
constructor(startx, starty)
super(startx, starty);
this.points = [startx, starty];
registerMovement(x, y)
this.points = [...this.points, x, y];
render()
return <Line points=this.points fill="black" stroke="black" />;
class SceneWithDrawables extends Component
constructor(props)
super(props);
this.state =
drawables: [],
newDrawable: [],
newDrawableType: "FreePathDrawable"
;
getNewDrawableBasedOnType = (x, y, type) =>
const drawableClasses =
FreePathDrawable,
ArrowDrawable,
CircleDrawable
;
return new drawableClasses[type](x, y);
;
handleMouseDown = e =>
const newDrawable = this.state;
if (newDrawable.length === 0)
const x, y = e.target.getStage().getPointerPosition();
const newDrawable = this.getNewDrawableBasedOnType(
x,
y,
this.state.newDrawableType
);
this.setState(
newDrawable: [newDrawable]
);
;
handleMouseUp = e =>
const newDrawable, drawables = this.state;
if (newDrawable.length === 1)
const x, y = e.target.getStage().getPointerPosition();
const drawableToAdd = newDrawable[0];
drawableToAdd.registerMovement(x, y);
drawables.push(drawableToAdd);
this.setState(
newDrawable: [],
drawables
);
;
handleMouseMove = e =>
const newDrawable = this.state;
if (newDrawable.length === 1)
const x, y = e.target.getStage().getPointerPosition();
const updatedNewDrawable = newDrawable[0];
updatedNewDrawable.registerMovement(x, y);
this.setState(
newDrawable: [updatedNewDrawable]
);
;
render()
const drawables = [...this.state.drawables, ...this.state.newDrawable];
return (
<div>
<button
onClick=e =>
this.setState( newDrawableType: "ArrowDrawable" );
>
Draw Arrows
</button>
<button
onClick=e =>
this.setState( newDrawableType: "CircleDrawable" );
>
Draw Circles
</button>
<button
onClick=e =>
this.setState( newDrawableType: "FreePathDrawable" );
>
Draw FreeHand!
</button>
<Stage
onMouseDown=this.handleMouseDown
onMouseUp=this.handleMouseUp
onMouseMove=this.handleMouseMove
width=900
height=700
>
<Layer>
drawables.map(drawable =>
return drawable.render();
)
</Layer>
</Stage>
</div>
);
function App()
return <SceneWithDrawables />;
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Working example to play with:
https://codesandbox.io/s/w12qznzx5
thank you so much ! I didn't think about putting the arrow in an array and then just map it in the render. Will definitely help. Any idea on how to add multiple buttons, for example 'Pen' and 'Circle' so that the user can first choose, and then draw accordingly?
– Herbot Sikaro
Mar 23 at 18:33
1
@HerbotSikaro I added a circle and a freehand drawing option (I guess that is what you ment by pen). It made it a bit more hairy, but managed to keep it under 200 lines and rather simple. Although in your own project, you should start thinking about breaking this thing up into separate files. If you have any more questions, ask away! I'll answer within 24h
– Pärt Johanson
Mar 23 at 21:59
That is brilliant. I can't thank you enough.
– Herbot Sikaro
Mar 23 at 22:35
@HerbotSikaro this week I have lots of work to do, but I'll try to have a look at it during the weekend, if you haven't found a solution in the meantime.
– Pärt Johanson
Mar 25 at 21:11
Sure, I have been trying but I can't figure it out, so I'm kinda waiting for your help.. :/ Those last 4 functionalities all present challenges that are very hard to grasp, and the few examples that I can find online are too simple to be applicable..
– Herbot Sikaro
Mar 27 at 18:19
|
show 3 more comments
Here you go:
import React, Component from "react";
import Stage, Layer, Arrow, Circle, Line from "react-konva";
import ReactDOM from "react-dom";
import "./styles.css";
class Drawable
constructor(startx, starty)
this.startx = startx;
this.starty = starty;
class ArrowDrawable extends Drawable
constructor(startx, starty)
super(startx, starty);
this.x = startx;
this.y = starty;
registerMovement(x, y)
this.x = x;
this.y = y;
render()
const points = [this.startx, this.starty, this.x, this.y];
return <Arrow points=points fill="black" stroke="black" />;
class CircleDrawable extends ArrowDrawable
constructor(startx, starty)
super(startx, starty);
this.x = startx;
this.y = starty;
render()
const dx = this.startx - this.x;
const dy = this.starty - this.y;
const radius = Math.sqrt(dx * dx + dy * dy);
return (
<Circle radius=radius x=this.startx y=this.starty stroke="black" />
);
class FreePathDrawable extends Drawable
constructor(startx, starty)
super(startx, starty);
this.points = [startx, starty];
registerMovement(x, y)
this.points = [...this.points, x, y];
render()
return <Line points=this.points fill="black" stroke="black" />;
class SceneWithDrawables extends Component
constructor(props)
super(props);
this.state =
drawables: [],
newDrawable: [],
newDrawableType: "FreePathDrawable"
;
getNewDrawableBasedOnType = (x, y, type) =>
const drawableClasses =
FreePathDrawable,
ArrowDrawable,
CircleDrawable
;
return new drawableClasses[type](x, y);
;
handleMouseDown = e =>
const newDrawable = this.state;
if (newDrawable.length === 0)
const x, y = e.target.getStage().getPointerPosition();
const newDrawable = this.getNewDrawableBasedOnType(
x,
y,
this.state.newDrawableType
);
this.setState(
newDrawable: [newDrawable]
);
;
handleMouseUp = e =>
const newDrawable, drawables = this.state;
if (newDrawable.length === 1)
const x, y = e.target.getStage().getPointerPosition();
const drawableToAdd = newDrawable[0];
drawableToAdd.registerMovement(x, y);
drawables.push(drawableToAdd);
this.setState(
newDrawable: [],
drawables
);
;
handleMouseMove = e =>
const newDrawable = this.state;
if (newDrawable.length === 1)
const x, y = e.target.getStage().getPointerPosition();
const updatedNewDrawable = newDrawable[0];
updatedNewDrawable.registerMovement(x, y);
this.setState(
newDrawable: [updatedNewDrawable]
);
;
render()
const drawables = [...this.state.drawables, ...this.state.newDrawable];
return (
<div>
<button
onClick=e =>
this.setState( newDrawableType: "ArrowDrawable" );
>
Draw Arrows
</button>
<button
onClick=e =>
this.setState( newDrawableType: "CircleDrawable" );
>
Draw Circles
</button>
<button
onClick=e =>
this.setState( newDrawableType: "FreePathDrawable" );
>
Draw FreeHand!
</button>
<Stage
onMouseDown=this.handleMouseDown
onMouseUp=this.handleMouseUp
onMouseMove=this.handleMouseMove
width=900
height=700
>
<Layer>
drawables.map(drawable =>
return drawable.render();
)
</Layer>
</Stage>
</div>
);
function App()
return <SceneWithDrawables />;
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Working example to play with:
https://codesandbox.io/s/w12qznzx5
thank you so much ! I didn't think about putting the arrow in an array and then just map it in the render. Will definitely help. Any idea on how to add multiple buttons, for example 'Pen' and 'Circle' so that the user can first choose, and then draw accordingly?
– Herbot Sikaro
Mar 23 at 18:33
1
@HerbotSikaro I added a circle and a freehand drawing option (I guess that is what you ment by pen). It made it a bit more hairy, but managed to keep it under 200 lines and rather simple. Although in your own project, you should start thinking about breaking this thing up into separate files. If you have any more questions, ask away! I'll answer within 24h
– Pärt Johanson
Mar 23 at 21:59
That is brilliant. I can't thank you enough.
– Herbot Sikaro
Mar 23 at 22:35
@HerbotSikaro this week I have lots of work to do, but I'll try to have a look at it during the weekend, if you haven't found a solution in the meantime.
– Pärt Johanson
Mar 25 at 21:11
Sure, I have been trying but I can't figure it out, so I'm kinda waiting for your help.. :/ Those last 4 functionalities all present challenges that are very hard to grasp, and the few examples that I can find online are too simple to be applicable..
– Herbot Sikaro
Mar 27 at 18:19
|
show 3 more comments
Here you go:
import React, Component from "react";
import Stage, Layer, Arrow, Circle, Line from "react-konva";
import ReactDOM from "react-dom";
import "./styles.css";
class Drawable
constructor(startx, starty)
this.startx = startx;
this.starty = starty;
class ArrowDrawable extends Drawable
constructor(startx, starty)
super(startx, starty);
this.x = startx;
this.y = starty;
registerMovement(x, y)
this.x = x;
this.y = y;
render()
const points = [this.startx, this.starty, this.x, this.y];
return <Arrow points=points fill="black" stroke="black" />;
class CircleDrawable extends ArrowDrawable
constructor(startx, starty)
super(startx, starty);
this.x = startx;
this.y = starty;
render()
const dx = this.startx - this.x;
const dy = this.starty - this.y;
const radius = Math.sqrt(dx * dx + dy * dy);
return (
<Circle radius=radius x=this.startx y=this.starty stroke="black" />
);
class FreePathDrawable extends Drawable
constructor(startx, starty)
super(startx, starty);
this.points = [startx, starty];
registerMovement(x, y)
this.points = [...this.points, x, y];
render()
return <Line points=this.points fill="black" stroke="black" />;
class SceneWithDrawables extends Component
constructor(props)
super(props);
this.state =
drawables: [],
newDrawable: [],
newDrawableType: "FreePathDrawable"
;
getNewDrawableBasedOnType = (x, y, type) =>
const drawableClasses =
FreePathDrawable,
ArrowDrawable,
CircleDrawable
;
return new drawableClasses[type](x, y);
;
handleMouseDown = e =>
const newDrawable = this.state;
if (newDrawable.length === 0)
const x, y = e.target.getStage().getPointerPosition();
const newDrawable = this.getNewDrawableBasedOnType(
x,
y,
this.state.newDrawableType
);
this.setState(
newDrawable: [newDrawable]
);
;
handleMouseUp = e =>
const newDrawable, drawables = this.state;
if (newDrawable.length === 1)
const x, y = e.target.getStage().getPointerPosition();
const drawableToAdd = newDrawable[0];
drawableToAdd.registerMovement(x, y);
drawables.push(drawableToAdd);
this.setState(
newDrawable: [],
drawables
);
;
handleMouseMove = e =>
const newDrawable = this.state;
if (newDrawable.length === 1)
const x, y = e.target.getStage().getPointerPosition();
const updatedNewDrawable = newDrawable[0];
updatedNewDrawable.registerMovement(x, y);
this.setState(
newDrawable: [updatedNewDrawable]
);
;
render()
const drawables = [...this.state.drawables, ...this.state.newDrawable];
return (
<div>
<button
onClick=e =>
this.setState( newDrawableType: "ArrowDrawable" );
>
Draw Arrows
</button>
<button
onClick=e =>
this.setState( newDrawableType: "CircleDrawable" );
>
Draw Circles
</button>
<button
onClick=e =>
this.setState( newDrawableType: "FreePathDrawable" );
>
Draw FreeHand!
</button>
<Stage
onMouseDown=this.handleMouseDown
onMouseUp=this.handleMouseUp
onMouseMove=this.handleMouseMove
width=900
height=700
>
<Layer>
drawables.map(drawable =>
return drawable.render();
)
</Layer>
</Stage>
</div>
);
function App()
return <SceneWithDrawables />;
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Working example to play with:
https://codesandbox.io/s/w12qznzx5
Here you go:
import React, Component from "react";
import Stage, Layer, Arrow, Circle, Line from "react-konva";
import ReactDOM from "react-dom";
import "./styles.css";
class Drawable
constructor(startx, starty)
this.startx = startx;
this.starty = starty;
class ArrowDrawable extends Drawable
constructor(startx, starty)
super(startx, starty);
this.x = startx;
this.y = starty;
registerMovement(x, y)
this.x = x;
this.y = y;
render()
const points = [this.startx, this.starty, this.x, this.y];
return <Arrow points=points fill="black" stroke="black" />;
class CircleDrawable extends ArrowDrawable
constructor(startx, starty)
super(startx, starty);
this.x = startx;
this.y = starty;
render()
const dx = this.startx - this.x;
const dy = this.starty - this.y;
const radius = Math.sqrt(dx * dx + dy * dy);
return (
<Circle radius=radius x=this.startx y=this.starty stroke="black" />
);
class FreePathDrawable extends Drawable
constructor(startx, starty)
super(startx, starty);
this.points = [startx, starty];
registerMovement(x, y)
this.points = [...this.points, x, y];
render()
return <Line points=this.points fill="black" stroke="black" />;
class SceneWithDrawables extends Component
constructor(props)
super(props);
this.state =
drawables: [],
newDrawable: [],
newDrawableType: "FreePathDrawable"
;
getNewDrawableBasedOnType = (x, y, type) =>
const drawableClasses =
FreePathDrawable,
ArrowDrawable,
CircleDrawable
;
return new drawableClasses[type](x, y);
;
handleMouseDown = e =>
const newDrawable = this.state;
if (newDrawable.length === 0)
const x, y = e.target.getStage().getPointerPosition();
const newDrawable = this.getNewDrawableBasedOnType(
x,
y,
this.state.newDrawableType
);
this.setState(
newDrawable: [newDrawable]
);
;
handleMouseUp = e =>
const newDrawable, drawables = this.state;
if (newDrawable.length === 1)
const x, y = e.target.getStage().getPointerPosition();
const drawableToAdd = newDrawable[0];
drawableToAdd.registerMovement(x, y);
drawables.push(drawableToAdd);
this.setState(
newDrawable: [],
drawables
);
;
handleMouseMove = e =>
const newDrawable = this.state;
if (newDrawable.length === 1)
const x, y = e.target.getStage().getPointerPosition();
const updatedNewDrawable = newDrawable[0];
updatedNewDrawable.registerMovement(x, y);
this.setState(
newDrawable: [updatedNewDrawable]
);
;
render()
const drawables = [...this.state.drawables, ...this.state.newDrawable];
return (
<div>
<button
onClick=e =>
this.setState( newDrawableType: "ArrowDrawable" );
>
Draw Arrows
</button>
<button
onClick=e =>
this.setState( newDrawableType: "CircleDrawable" );
>
Draw Circles
</button>
<button
onClick=e =>
this.setState( newDrawableType: "FreePathDrawable" );
>
Draw FreeHand!
</button>
<Stage
onMouseDown=this.handleMouseDown
onMouseUp=this.handleMouseUp
onMouseMove=this.handleMouseMove
width=900
height=700
>
<Layer>
drawables.map(drawable =>
return drawable.render();
)
</Layer>
</Stage>
</div>
);
function App()
return <SceneWithDrawables />;
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Working example to play with:
https://codesandbox.io/s/w12qznzx5
edited Mar 23 at 22:01
answered Mar 23 at 17:07
Pärt JohansonPärt Johanson
906510
906510
thank you so much ! I didn't think about putting the arrow in an array and then just map it in the render. Will definitely help. Any idea on how to add multiple buttons, for example 'Pen' and 'Circle' so that the user can first choose, and then draw accordingly?
– Herbot Sikaro
Mar 23 at 18:33
1
@HerbotSikaro I added a circle and a freehand drawing option (I guess that is what you ment by pen). It made it a bit more hairy, but managed to keep it under 200 lines and rather simple. Although in your own project, you should start thinking about breaking this thing up into separate files. If you have any more questions, ask away! I'll answer within 24h
– Pärt Johanson
Mar 23 at 21:59
That is brilliant. I can't thank you enough.
– Herbot Sikaro
Mar 23 at 22:35
@HerbotSikaro this week I have lots of work to do, but I'll try to have a look at it during the weekend, if you haven't found a solution in the meantime.
– Pärt Johanson
Mar 25 at 21:11
Sure, I have been trying but I can't figure it out, so I'm kinda waiting for your help.. :/ Those last 4 functionalities all present challenges that are very hard to grasp, and the few examples that I can find online are too simple to be applicable..
– Herbot Sikaro
Mar 27 at 18:19
|
show 3 more comments
thank you so much ! I didn't think about putting the arrow in an array and then just map it in the render. Will definitely help. Any idea on how to add multiple buttons, for example 'Pen' and 'Circle' so that the user can first choose, and then draw accordingly?
– Herbot Sikaro
Mar 23 at 18:33
1
@HerbotSikaro I added a circle and a freehand drawing option (I guess that is what you ment by pen). It made it a bit more hairy, but managed to keep it under 200 lines and rather simple. Although in your own project, you should start thinking about breaking this thing up into separate files. If you have any more questions, ask away! I'll answer within 24h
– Pärt Johanson
Mar 23 at 21:59
That is brilliant. I can't thank you enough.
– Herbot Sikaro
Mar 23 at 22:35
@HerbotSikaro this week I have lots of work to do, but I'll try to have a look at it during the weekend, if you haven't found a solution in the meantime.
– Pärt Johanson
Mar 25 at 21:11
Sure, I have been trying but I can't figure it out, so I'm kinda waiting for your help.. :/ Those last 4 functionalities all present challenges that are very hard to grasp, and the few examples that I can find online are too simple to be applicable..
– Herbot Sikaro
Mar 27 at 18:19
thank you so much ! I didn't think about putting the arrow in an array and then just map it in the render. Will definitely help. Any idea on how to add multiple buttons, for example 'Pen' and 'Circle' so that the user can first choose, and then draw accordingly?
– Herbot Sikaro
Mar 23 at 18:33
thank you so much ! I didn't think about putting the arrow in an array and then just map it in the render. Will definitely help. Any idea on how to add multiple buttons, for example 'Pen' and 'Circle' so that the user can first choose, and then draw accordingly?
– Herbot Sikaro
Mar 23 at 18:33
1
1
@HerbotSikaro I added a circle and a freehand drawing option (I guess that is what you ment by pen). It made it a bit more hairy, but managed to keep it under 200 lines and rather simple. Although in your own project, you should start thinking about breaking this thing up into separate files. If you have any more questions, ask away! I'll answer within 24h
– Pärt Johanson
Mar 23 at 21:59
@HerbotSikaro I added a circle and a freehand drawing option (I guess that is what you ment by pen). It made it a bit more hairy, but managed to keep it under 200 lines and rather simple. Although in your own project, you should start thinking about breaking this thing up into separate files. If you have any more questions, ask away! I'll answer within 24h
– Pärt Johanson
Mar 23 at 21:59
That is brilliant. I can't thank you enough.
– Herbot Sikaro
Mar 23 at 22:35
That is brilliant. I can't thank you enough.
– Herbot Sikaro
Mar 23 at 22:35
@HerbotSikaro this week I have lots of work to do, but I'll try to have a look at it during the weekend, if you haven't found a solution in the meantime.
– Pärt Johanson
Mar 25 at 21:11
@HerbotSikaro this week I have lots of work to do, but I'll try to have a look at it during the weekend, if you haven't found a solution in the meantime.
– Pärt Johanson
Mar 25 at 21:11
Sure, I have been trying but I can't figure it out, so I'm kinda waiting for your help.. :/ Those last 4 functionalities all present challenges that are very hard to grasp, and the few examples that I can find online are too simple to be applicable..
– Herbot Sikaro
Mar 27 at 18:19
Sure, I have been trying but I can't figure it out, so I'm kinda waiting for your help.. :/ Those last 4 functionalities all present challenges that are very hard to grasp, and the few examples that I can find online are too simple to be applicable..
– Herbot Sikaro
Mar 27 at 18:19
|
show 3 more comments
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55314284%2fdraw-arrow-on-canvas-with-react-konva%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown