我在flexbox中有一个canvas元素,可以调整大小。我如何让画布填充可用空间而不失去其宽高比(2/3),而不被切断?
(我想改变CSS尺寸,而不是画布分辨率)。
我试过使用object-fit: contain
和clamp(...)
,但我不能得到我想要的结果。要么画布没有保持它的长宽比,要么它长出了它的容器。
body {
margin: 0;
}
#mainContent {
background: grey;
height: 100vh;
display: flex;
flex-wrap: nowrap;
align-items: center;
}
#someOtherElem {
background: red;
width: 200px;
height: 200px;
margin-left: 1rem;
}
#canvasContainer {
display: flex;
flex: 1;
height: 100%;
justify-content: center;
align-items: center;
}
canvas {
width: calc(100% - 2rem);
height: calc(100% - 2rem);
background: green;
object-fit: contain;
}
<div id="mainContent">
<div id="someOtherElem"></div>
<div id="canvasContainer">
<canvas height="300" width="200"></canvas>
</div>
</div>
这是我一直在尝试的精简版本:https://jsfiddle.net/mwq4502v/.
我不确定实现这一目标的最佳方法是什么,所以任何帮助都会非常感激!
您可以为canvas
指定aspect-ratio
或2 / 3
,并为100%
或<parent-height> * 2 / 3
指定宽度,以较小者为准。
canvas {
aspect-ratio: 2 / 3;
width: min(100%, 100vh * 2 / 3);
/* ...or height: min(100%, calc(100vw - 210px) * 3 / 2). Same spirit. */
}
一些数学:设容器的宽度和高度分别为w
和h
。因为画布需要尽可能的大,它将总是触摸至少两个容器的边界(或全部),这意味着它的大小可以是w / (w / (2 / 3))
或(h * 2 / 3) / h
,这取决于容器的大小。
w / h
>2 / 3
:
◄──────────── w ────────────►
┌────────┬─────────┬────────┐ ▲
│ │ │ │ │
│ │ │ │ │
│ │ │ │ │
│ │ │ │ h
│ │ │ │ │
│ │ │ │ │
│ │ │ │ │
└────────┴─────────┴────────┘ ▼
◄ (h*2/3) ►
w / h
<2 / 3
:
◄─── w ───►
┌─────────┐ ▲
│ │ │
▲ ├─────────┤ │
│ │ │ │
│ │ │ │
(w*3/2) │ │ h
│ │ │ │
│ │ │ │
▼ ├─────────┤ │
│ │ │
└─────────┘ ▼
这意味着宽度需要为min(w, h * 2 / 3)
,或者在CSS中为min(100%, 100vh * 2 / 3)
。
试一试:
canvas {
aspect-ratio: 2 / 3;
width: min(100%, 100vh * 2 / 3);
}
/* Demo only */
#canvasContainer {
outline: 1px solid #000; /* Just so we know where it is */
}
body {
margin: 0;
}
#mainContent {
display: flex;
align-items: center;
height: 100vh;
}
#someOtherElem {
margin-left: 1rem;
width: 200px;
height: 200px;
background: red;
}
#canvasContainer {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
height: 100%;
}
canvas {
background: green;
}
<div id="mainContent">
<div id="someOtherElem"></div>
<div id="canvasContainer">
<canvas></canvas>
</div>
</div>