Closed navono closed 6 years ago
I think I can help, but I am not sure exactly what you are trying to achieve. Are you trying to make it so that you click and drag such that the more you drag, the bigger the shape (and it's size is set once you release)? Or did you just want to just change the dimensions of the shape whenever the mouse moves?
@ejarzo Thank you for your reply. Two goals.
First, I want to dynamic generate shapes(e.g. a rect) on layer by mouse click(get the x
and y
position), then move mouse(dynamic update rect width
and heigh
, the rect also dynamic display in the layer), then mouse click again(determine the final width
and height
), done.
Second, dynamic adjust the dimensions of already exist shape. This can be easier like this demo, change the circle radius, make the circle bigger or smaller.
I hope this can explain clearly.
@ejarzo I move the creation of rect
into handleClick
. Pick the x
and y
position in first mouse click and create rect
in second mouse click and push it to children
, then it works.
But among the mouse movements, the rect
doesn't show. My intention is want to show it in among the mouse movements.
I think you should not create React elements in your "handle" function. Store in this.state
only real state of your app (like coordinates of Rects). Use render
function to create elements.
As this is not a bug or feature I will close the issue. Please use StackOverflow for questions.
I realize this isn't a bug/issue but just to follow up - @navono Instead of creating React elements in your handleClick
function, try only setting the state there, and letting render
handle the rest. React is declarative, meaning that you describe your app in state
, and render
automatically reflects any changes you make to state
.
If you represent your shapes as an array of objects (each having { x, y, width, height }
), and then display that array in render
, any time you change values in the array, the shapes will change on the screen. The dimension values will be props
for a ColoredRect
, so ColoredRect
will not need to manage its own dimensions - it can simply render the props
that it receives.
I made a demo here: https://codesandbox.io/s/wwpyr3j737
@ejarzo Sorry about this not a bug/issue. I should ask in SO.
Big thank you about the demo.
@ejarzo's answer is very instructive, but generally speaking the code presented at https://codesandbox.io/s/wwpyr3j737 is highly inefficient as it re-renders every square while drawing out a new square. Try drawing 20+ square to see how the browser slows down. Consider using konva's to()
method to animate the individual square that is being drawn.
@physicsai Very true. Using to()
could definitely work but depending on the situation, it may not be desirable because the state of your application would not be in sync with what is being drawn on the canvas. To keep the same declarative approach without ruining the performance, we could optimize the ColoredRect
component using shouldComponentUpdate()
or, similar to your suggestion, we could separate the shape that is currently being drawn from the rest so that only that one is re-rendered on drag. Then once it is completed, we add it to the list of static shapes.
Konva
is a great canvas framework andreact-konva
also nice. Thanks for the cool things!I want to dynamic create shape on layers, and I tried add shapes into a list, then
Layer
show the children, but it's doesn't draw the shape as I move mouse. Here is a reproduce demo.The problem seems like can't change the shape's props after update it's width and height with
setState
, but don't know why. Am I miss something or use wrong solution?Thanks for reply.