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;








1















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 !










share|improve this question




























    1















    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 !










    share|improve this question
























      1












      1








      1








      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 !










      share|improve this question














      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






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Mar 23 at 13:38









      Herbot SikaroHerbot Sikaro

      646




      646






















          1 Answer
          1






          active

          oldest

          votes


















          1














          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






          share|improve this answer

























          • 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












          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
          );



          );













          draft saved

          draft discarded


















          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









          1














          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






          share|improve this answer

























          • 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
















          1














          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






          share|improve this answer

























          • 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














          1












          1








          1







          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






          share|improve this answer















          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







          share|improve this answer














          share|improve this answer



          share|improve this answer








          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


















          • 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




















          draft saved

          draft discarded
















































          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.




          draft saved


          draft discarded














          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





















































          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







          Popular posts from this blog

          Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

          Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

          Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript