Resizing KonvaJS Dynamically Similar to Canvas

I have a need to adjust the KonvaJS Container/Stage in a similar way to a canvas element. I’ve provided an example below showcasing my exact need. In this code the source of the image to select is the canvas, and so I need the canvas and the Konva elements to dynamically update to the screen size and perfectly align while still maintaining dimensions of 1000×1000.

However, for some reason the Konva container’s (select-container) width is not adjusting the same way as the canvas does with the same css. In addition, it seems that the stage is not adjusting to the fit within the container. Is there any built in solution to fix my issue?

<!DOCTYPE html>
<html>
  <head>
    <script src="https://unpkg.com/[email protected]/konva.min.js"></script>
    <meta charset="utf-8" />
    <title>Canvas to Konva Object</title>
    <style>
      body {
        margin: 0;
        padding: 0;
        overflow: hidden;
        background-color: #f0f0f0;
      }
      .over-container {
            top: 100%;
            display: flex;
            flex-wrap: nowrap; /* Prevent wrapping */
            flex-direction: column;
            width: 100%;
            height: 100vh;
            align-items: center;
            margin-top: 35px;
        }

        #canvas-container {
            position: relative;
            width: 100%;
            overflow: hidden;
            /* Aspect Ratio */
            padding-top: 100%;
            display: flex;
            justify-content: center;
        }

        #select-container {
            cursor: crosshair;
            position: absolute;
            top: 0;
            left: 50%;
            transform: translate(-50%);
            max-width: calc(100vw - 10px); /* Subtracting 5px margin on both sides */
            /* Set explicitly or let JavaScript control */
            border: 1px solid #571bfa;
            flex: 1;
        }

        #canvas {
            cursor: crosshair;
            position: absolute;
            top: 0;
            left: 50%;
            transform: translate(-50%);
            /* Adjust size based on viewport */
            max-width: calc(100vw - 10px); /* Subtracting 5px margin on both sides */
            touch-action: none; 
            image-rendering: pixelated; 
            flex: 1;
            border: 1px solid #000;
        }
    </style>
  </head>
  <body>
    <div class="over-container" id="Ocontainer">
        <div id="canvas-container">
            <canvas id="canvas"></canvas>
            <div id="select-container"></div>
        </div>
    </div>
    <script>
        var width = 1000;
        var height = 1000;

        // Get the canvas and set dimensions
        var canvas = document.getElementById('canvas');
        canvas.width = width;
        canvas.height = height;

        var ctx = canvas.getContext('2d');
        ctx.fillStyle = 'blue';
        ctx.fillRect(50, 50, 300, 200);
        ctx.fillStyle = 'orange';
        ctx.fillRect(400, 100, 200, 300);

        // Create Konva stage and layer
        var stage = new Konva.Stage({
            container: 'select-container',
            width: width,
            height: height,
        });

        var layer = new Konva.Layer();
        stage.add(layer);

        var selectionRectangle = new Konva.Rect({
            fill: 'rgba(0, 0, 255, 0.5)',
            visible: false,
            listening: false,
        });
        layer.add(selectionRectangle);

        var x1, y1, x2, y2, selecting = false, activeObject = null;
        var copiedObject = null;
        var objects = [];
        var transformers = []; // Keep track of transformers for cleanup

        // Helper function to create a transformer for a given object
        function createTransformer(object) {
            const transformer = new Konva.Transformer({
            nodes: [object],
            });
            layer.add(transformer);
            transformer.update();
            transformers.push(transformer); // Keep track of the transformer
            return transformer;
        }

        stage.on('mousedown touchstart', (e) => {
            if (e.target !== stage) return;

            e.evt.preventDefault();
            x1 = stage.getPointerPosition().x;
            y1 = stage.getPointerPosition().y;
            selecting = true;

            selectionRectangle.setAttrs({
            visible: true,
            x: x1,
            y: y1,
            width: 0,
            height: 0,
            });
        });

        stage.on('mousemove touchmove', (e) => {
            if (!selecting) return;

            e.evt.preventDefault();
            x2 = stage.getPointerPosition().x;
            y2 = stage.getPointerPosition().y;

            let width = Math.abs(x2 - x1);
            let height = Math.abs(y2 - y1);

            // Check if Shift key is held
            if (e.evt.shiftKey) {
            // Force square by setting width and height to the smaller of the two
            const sideLength = Math.min(width, height);
            width = sideLength;
            height = sideLength;

            // Adjust x2 and y2 to maintain the square shape
            if (x2 < x1) x2 = x1 - width; // Adjust for leftward movement
            else x2 = x1 + width; // Adjust for rightward movement

            if (y2 < y1) y2 = y1 - height; // Adjust for upward movement
            else y2 = y1 + height; // Adjust for downward movement
            }

            selectionRectangle.setAttrs({
            x: Math.min(x1, x2),
            y: Math.min(y1, y2),
            width: width,
            height: height,
            });

            layer.batchDraw();
        });

        stage.on('mouseup touchend', () => {
            if (!selecting) return;
            selecting = false;
            selectionRectangle.visible(false);

            const box = selectionRectangle.getClientRect();
            const sx = box.x;
            const sy = box.y;
            const sw = box.width;
            const sh = box.height;

            if (sw === 0 || sh === 0) return;

            // Get the selected area from the visible canvas
            const imageData = ctx.getImageData(sx, sy, sw, sh);

            // Remove the selected portion from the canvas
            ctx.clearRect(sx, sy, sw, sh);

            // Create an off-screen canvas to crop the image data
            const tempCanvas = document.createElement('canvas');
            tempCanvas.width = sw;
            tempCanvas.height = sh;
            const tempCtx = tempCanvas.getContext('2d');
            tempCtx.putImageData(imageData, 0, 0);

            // Create a Konva.Image from the cropped area
            const image = new Konva.Image({
                x: sx,
                y: sy,
                image: tempCanvas,
                draggable: true,
            });
            layer.add(image);
            objects.push(image);

            // Create a transformer for this object
            createTransformer(image);

            activeObject = image;
            layer.batchDraw();
        });

        window.addEventListener('keydown', (e) => {
            if (e.ctrlKey && e.key === 'c' && activeObject) {
                // Copy the active object
                const clonedCanvas = document.createElement('canvas');
                clonedCanvas.width = activeObject.image().width;
                clonedCanvas.height = activeObject.image().height;
                const clonedCtx = clonedCanvas.getContext('2d');
                clonedCtx.drawImage(activeObject.image(), 0, 0);

                copiedObject = {
                    x: activeObject.x() + 10,
                    y: activeObject.y() + 10,
                    image: clonedCanvas,
                    rotation: activeObject.rotation(),
                    scaleX: activeObject.scaleX(),
                    scaleY: activeObject.scaleY(),
                };
            }
            if (e.ctrlKey && e.key === 'v' && copiedObject) {
                // Paste the copied object
                const newCopy = new Konva.Image({
                    x: copiedObject.x,
                    y: copiedObject.y,
                    image: copiedObject.image,
                    draggable: true,
                    rotation: copiedObject.rotation,
                    scaleX: copiedObject.scaleX,
                    scaleY: copiedObject.scaleY,
                });
                layer.add(newCopy);
                objects.push(newCopy);

                // Create a transformer for the new copy
                createTransformer(newCopy);

                activeObject = newCopy;
                layer.batchDraw();
            }
        });

        stage.on('click tap', (e) => {
            if (activeObject && e.target === stage) {
            // Apply all objects back to the canvas
            objects.forEach((obj) => {
                const image = obj.image(); // Get the underlying image
                const rotation = obj.rotation(); // Rotation angle in degrees

                // Use getClientRect to get transformed position
                const clientRect = obj.getClientRect();
                const boundingBoxCenterX = clientRect.x + clientRect.width / 2;
                const boundingBoxCenterY = clientRect.y + clientRect.height / 2;

                // Use the original image dimensions
                const originalWidth = image.width;
                const originalHeight = image.height;

                // Use scaleX and scaleY for scaling
                const scaledWidth = originalWidth * obj.scaleX();
                const scaledHeight = originalHeight * obj.scaleY();

                // Save the canvas context state
                ctx.save();

                // Translate to the bounding box center
                ctx.translate(boundingBoxCenterX, boundingBoxCenterY);

                // Rotate the canvas context around the center of the bounding box
                ctx.rotate((rotation * Math.PI) / 180);

                // Draw the object onto the canvas using the original dimensions and scaling
                ctx.drawImage(
                image,
                -scaledWidth / 2, // Center the image horizontally
                -scaledHeight / 2, // Center the image vertically
                scaledWidth,
                scaledHeight
                );

                // Restore the canvas context state
                ctx.restore();
            });

            // Destroy all Konva objects and transformers
            objects.forEach((obj) => obj.destroy());
            transformers.forEach((transformer) => transformer.destroy());
            transformers = [];

            // Reset state variables
            objects = [];
            activeObject = null;

            // Redraw the layer
            layer.batchDraw();
            }
        });

        const selectContainer = document.getElementById('select-container');
        const canvasContainer = document.getElementById('canvas-container');
        let imageSize = 1000;

        resizeCanvas();
        window.addEventListener('resize', resizeCanvas);
        window.addEventListener('load', resizeCanvas);
        document.body.addEventListener('resize', function(event) {
            document.body.style.zoom = 1;
        });

        function resizeCanvas() {
            const screenWidth = window.innerWidth;
            const screenHeight = window.innerHeight;
            const spaceToBottom = window.innerHeight - (canvasContainer.offsetTop + canvasContainer.offsetHeight);
            const topElementsHeight = screenHeight;

            canvas.width = Math.round(imageSize);
            canvas.height = Math.round(imageSize);

            canvas.style.maxHeight = topElementsHeight + 'px';
            canvas.style.height = topElementsHeight - spaceToBottom + 'px';

            selectContainer.style.setProperty('width', Math.round(imageSize) + 'px', 'important');
            selectContainer.style.setProperty('height', Math.round(imageSize) + 'px', 'important');

            selectContainer.style.setProperty('max-height', topElementsHeight + 'px', 'important');
            selectContainer.style.setProperty('height', topElementsHeight - spaceToBottom + 'px', 'important');


            const newWidth = Math.round(imageSize);
            const newHeight = Math.round(imageSize);

            stage.width(newWidth);
            stage.height(newHeight);
            stage.batchDraw();

            redrawCanvas();
        }

        function redrawCanvas() {
            // Clear the main canvas and set the background to white
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            ctx.fillStyle = 'blue';
            ctx.fillRect(50, 50, 300, 200);
            ctx.fillStyle = 'orange';
            ctx.fillRect(400, 100, 200, 300);
        }
    </script>
  </body>
</html>