I have a simple Konva set up, with a Layer, Rect, and Text.
The canvas scales with the resizing of the window. My goal is for the text to be contained within the canvas, when dragged. At present, it works on the left and top bounds, but not the bottom and right bounds.
What am I doing wrong here?
illustrating gif
https://media.giphy.com/media/fBG0OGhFPwiHUOeGSJ/giphy.gif
code
import React from "react";
import ReactDOM from "react-dom";
import styled from "styled-components";
import Konva from "konva";
import { Stage, Layer, Text, Rect } from "react-konva";
const CANVAS_INNER_PADDING = 5;
const Container = styled.div`
width: 50vw;
height: 50vw;
background-color: lightgray;
`;
class Canvas extends React.Component {
constructor(props) {
super(props);
this.container = React.createRef();
this.rect = React.createRef();
window.addEventListener("resize", this.updateCanvasDimensions);
this.state = {
text: {
value: "hello",
x: CANVAS_INNER_PADDING,
y: CANVAS_INNER_PADDING
},
canvas: {
width: 0,
height: 0,
color: "red"
}
};
}
componentDidMount() {
this.updateCanvasDimensions();
}
updateCanvasDimensions = () => {
const height = this.container.current.clientHeight;
const width = this.container.current.clientWidth;
this.setState({
canvas: { ...this.state.canvas, height, width }
});
};
handleDragMove = e => {
const { canvas } = this.state;
const newX = e.target.x();
const newY = e.target.y();
let newerX = newX;
let newerY = newY;
if (newX < CANVAS_INNER_PADDING) {
newerX = CANVAS_INNER_PADDING;
}
if (newX > canvas.width - CANVAS_INNER_PADDING) {
newerX = canvas.width - CANVAS_INNER_PADDING;
}
if (newY < CANVAS_INNER_PADDING) {
newerY = CANVAS_INNER_PADDING;
}
if (newY > canvas.height - CANVAS_INNER_PADDING) {
newerY = canvas.height - CANVAS_INNER_PADDING;
}
this.setState({
text: { ...this.state.text, x: newerX, y: newerY }
});
};
handleDragEnd = e => {
const newX = e.target.x();
const newY = e.target.y();
this.setState({
text: { ...this.state.text, x: newX, y: newY }
});
};
render() {
const { text, canvas } = this.state;
return (
// Have to use `innerRef` with Styled Components.
<Container innerRef={this.container}>
<Stage height={canvas.height} width={canvas.width}>
<Layer>
<Rect
ref={this.rect}
x={0}
y={0}
height={canvas.height}
width={canvas.width}
fill={canvas.color}
/>
<Text
ref={this.text}
draggable
onDragMove={this.handleDragMove}
onDragEnd={this.handleDragEnd}
text={`${canvas.height}, ${canvas.width}`}
fill="black"
x={text.x}
y={text.y}
/>
</Layer>
</Stage>
</Container>
);
}
}
const mapStateToProps = state => ({
text: state.printState.text,
canvas: state.printState.canvas
});
const rootElement = document.getElementById("root");
ReactDOM.render(<Canvas />, rootElement);