admin管理员组文章数量:1296841
I would like to create a canvas where the user can draw an Arrow by using his mouse.
What I'm trying to acplish is exactly this: /
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"
};
ponentDidMount() {
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 !
I would like to create a canvas where the user can draw an Arrow by using his mouse.
What I'm trying to acplish is exactly this: https://jsfiddle/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"
};
ponentDidMount() {
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 asked Mar 23, 2019 at 13:38 Herbot SikaroHerbot Sikaro 1992 gold badges3 silver badges10 bronze badges 1- alternatively you can use an svg solution such as npmjs./package/react-simple-arrows – Ulad Kasach Commented Feb 9, 2020 at 13:34
1 Answer
Reset to default 10Here 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
本文标签: javascriptDraw Arrow on Canvas with ReactKonvaStack Overflow
版权声明:本文标题:javascript - Draw Arrow on Canvas with React-Konva - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741644861a2390126.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论