Search code examples
javascriptreactjslineresponsivekonvajs

Responsive canvas with React and Konva


I use React and Konva libraries to draw a simple line. But when i resize the screen, the line stays out of the screen. So, how can I make it responsive?

This is my code:

import React from "react";
import { Stage, Layer,Line } from 'react-konva';

class App extends React.Component {

  constructor(props) {
    super(props);
  }

  render() {
    return (
        <div>
            <Stage width={window.innerWidth} height={window.innerHeight}>
                <Layer>
                    <Line
                        x={100}
                        y={100}
                        points={[0,0,576,456,509,403,20,15,300,207,111,222,293,177]}
                        stroke="black"
                        strokeWidth={5}
                        ref="line"
                    />
                </Layer>
            </Stage>
        </div>
    );
  }
}

export default App;

Solution

  • The "responsive logic" really depends on your app and on your desired UI goals. The simplest way you can add responsive here is to use scaling:

    import React from "react";
    import { Stage, Layer,Line } from 'react-konva';
    
    class App extends React.Component {
    
      constructor(props) {
        super(props);
      }
    
      render() {
        // lets think you want to make all your objects visible in
        // 700x700 scene
        const CANVAS_VIRTUAL_WIDTH = 700;
        const CANVAS_VIRTUAL_HEIGHT = 700;
    
        // now you may want to make it visible even on small screens
        // we can just scale it
        const scale = Math.min(
          window.innerWidth / CANVAS_VIRTUAL_WIDTH,
          window.innerHeight / CANVAS_VIRTUAL_HEIGHT
        );
    
        return (
            <div>
                <Stage width={window.innerWidth} height={window.innerHeight} scaleX={scale} scaleY={scale}>
                    <Layer>
                        <Line
                            x={100}
                            y={100}
                            points={[0,0,576,456,509,403,20,15,300,207,111,222,293,177]}
                            stroke="black"
                            strokeWidth={5}
                            ref="line"
                        />
                    </Layer>
                </Stage>
            </div>
        );
      }
    }
    
    export default App;