0

I have a rectangle which I want to be responsive according to the width.

Currently, my logic is straight-forward:

aspectRatio = 16 / 9
win = {
    width: window.innerWidth,
    height: window.innerHeight,
}

get browser() {
    const width = this.win.width - 250
    const height = width / this.aspectRatio

    return {
        width,
        height,
    }
}

I calculate my width by subtracting sidebar width which is 250 from win.width.

And for my height, I divide width by aspectRatio.

However, this results in 0 height when I reduce my window size to ~700px.

My application looks like:

screenshot of my application

Demo → https://gqhhl.csb.app/

CodeSandBox → https://codesandbox.io/s/add-padding-to-centered-canvas-with-sidebar-gqhhl

What I really want is for that papayawhip rectangle to be responsive. I'm not sure which algorithm to use? I'm using Canvas using KonvaJS but the logic is in JavaScript.

How do I make it responsive & proportional? Currently, the height gets shortened very quick.

4

3 回答 3

1

Here is my solution:

function App() {
  const store = useStore();
  const { win, browser, aspectRatio } = store;
  const pad = 50;

  const rectWidth = browser.width - pad;
  const rectHeight = rectWidth / aspectRatio;

  return (
    <div className="flex">
      <div id="sidebar">
        <h1 className="text">
          Center <span>papayawhip</span> Canvas
        </h1>
      </div>
      <Stage width={browser.width} height={browser.height} id="konva">
        <Layer>
          <Rect
            width={rectWidth}
            height={rectHeight}
            x={pad / 2}
            y={(win.height - rectHeight) / 2}
            fill="papayawhip"
          />
        </Layer>
      </Stage>
    </div>
  );
}

Also, I changed the store, so browser returns canvas area:

get browser() {
        const width = this.win.width - 250
        const height = this.win.height

        return {
            width,
            height,
        }
}

Demo: https://codesandbox.io/s/react-konva-responsive-canvas-ogk1n

于 2021-01-13T00:13:38.010 回答
0

First Solution

width: 100%;
padding-top: 56.25%; /* 16:9 Aspect Ratio */

Second Solution

padding-top: calc(9 / 16 * 100%);
于 2021-01-12T08:26:45.457 回答
0

You need to change CSS but say your component is buried 3 levels deep. Unlike the CSS file, which is next to your .tsx and imported already, so use it!

Line 5 of your code:

import "./styles.css"

Add this to the end of the file (copied from @deadcoder's answer which solves the ratio issue). Also see the breakpoint below it for how a responsive breakpoint goes. That's how you do the responsive thing without it shrinking to nothing.

canvas {
  width: 100%;
  padding-top: 56.25%; /* 16:9 Aspect Ratio */
}

@media screen and (max-width: 1200px) {
    canvas {
      width: 100%;
      height: 400px;
      padding: 0; /* reset the ratio for smaller sizes so you can crop it */
    }
}
@media screen and (max-width: 600px) {
    canvas {
      width: 100%;
      height: 200px;
      padding: 0; /* reset the ratio for smaller sizes so you can crop it */
    }
}

Also consider giving that canvas an ID or class to single it out.

If the height is disappearing too quickly still, consider using the whole area as the canvas or using a background image

于 2021-01-12T10:53:48.260 回答