我有一個(gè)完整大小的頁(yè)面,包含一個(gè)頂部工具欄,下面是一個(gè)包含兩列的容器:
右欄 包含畫布(在此列中水平和垂直居中)的左列,它有自己的坐標(biāo)系(通常為4000 x 3000 ),并且應(yīng)該保持此縱橫比。這幅油畫有一個(gè)& quot+& quot;按鈕分層放在上面。(在我的真實(shí)代碼中,有幾個(gè)畫布用于多個(gè)層和多個(gè)按鈕,但在這里并不重要)
在這里,它幾乎可以工作,但是我不能讓畫布占據(jù)左欄的全部可用空間。
在我嘗試的所有方法中(最大寬度:100%,最大高度:100%),當(dāng)我們?cè)跒g覽器中放大/縮小時(shí),要么失敗(70% 80%...150 %),或者失敗是因?yàn)槭褂玫姆椒ㄗ柚拱粹o停留在畫布的頂部,在它的右上角。
TL;DR:如何讓這塊畫布占據(jù)左欄所有可用空間,保持它的長(zhǎng)寬比,保持分層按鈕,不溢出?
注意:我在尋找一個(gè)CSS解決方案,JS不是為了定位,而只是繪圖。
ctx = document.querySelector("canvas").getContext("2d");
ctx.fillStyle = "#FF0000"; ctx.fillRect(0, 0, 1000, 1000);
ctx.fillStyle = "#00FF00"; ctx.fillRect(1000, 1000, 1000, 1000);
ctx.fillStyle = "#0000FF"; ctx.fillRect(2000, 2000, 1000, 1000);
ctx.fillStyle = "#000000"; ctx.fillRect(3000, 0, 1000, 1000);
* {
padding: 0;
margin: 0;
}
.page {
display: flex;
flex-direction: column;
height: 100vh;
}
.toolbar {
background-color: yellow;
flex: 0 0 5em;
}
.container {
background-color: orange;
flex: 1 0 0;
display: flex;
}
.left {
background-color: magenta;
flex: 1 0 0;
display: flex;
align-items: center;
justify-content: center;
}
.right {
background-color: salmon;
flex: 0 0 10em;
}
.canvas-wrapper {
background-color: grey;
display: flex;
position: relative;
}
canvas {
height: 100px;
background-color: white;
}
.button {
background-color: yellow;
position: absolute;
top: 0;
right: 0;
width: 1em;
height: 1em;
}
<div class="page">
<div class="toolbar">
TOOLBAR OF HEIGHT 5 EM
</div>
<div class="container">
<div class="left">
<div class="canvas-wrapper">
<canvas width="4000" height="3000"></canvas>
<div class="button">+</div>
</div>
</div>
<div class="right">
RIGHT OF WIDTH 10 EM
</div>
</div>
</div>
您需要更改一些對(duì)齊、寬度、高度、伸縮并添加一個(gè)HTML包裝器(即& ltdiv class = & quot畫布-包裝-內(nèi)部& quot& gt).
請(qǐng)看下面的片段。
ctx = document.querySelector("canvas").getContext("2d");
ctx.fillStyle = "#FF0000";
ctx.fillRect(0, 0, 1000, 1000);
ctx.fillStyle = "#00FF00";
ctx.fillRect(1000, 1000, 1000, 1000);
ctx.fillStyle = "#0000FF";
ctx.fillRect(2000, 2000, 1000, 1000);
ctx.fillStyle = "#000000";
ctx.fillRect(3000, 0, 1000, 1000);
* {
padding: 0;
margin: 0;
}
.page {
display: flex;
flex-direction: column;
height: 100vh;
}
.toolbar {
background-color: yellow;
flex: 0 0 5em;
}
.container {
background-color: orange;
flex: 1 0 0;
display: flex;
}
.left {
background-color: magenta;
flex: 1 0 0;
display: flex;
align-items: center;
justify-content: center;
}
.right {
background-color: salmon;
flex: 0 0 10em;
}
.canvas-wrapper {
background-color: grey;
display: flex;
position: relative;
flex-grow: 1; /* Added */
align-self: stretch; /* Added */
align-items: center; /* Added */
justify-content: center; /* Added */
}
canvas {
width: 100%; /* Added */
flex-grow: 1; /* Added */
object-fit: contain; /* Added */
max-height: calc(100vh - 5em); /* Added */
}
.button {
background-color: yellow;
position: absolute;
top: 0;
right: 0;
width: 1em;
height: 1em;
}
/* Added */
.canvas-wrapper-inner {
position: relative;
}
<div class="page">
<div class="toolbar">
TOOLBAR OF HEIGHT 5 EM
</div>
<div class="container">
<div class="left">
<div class="canvas-wrapper">
<div class="canvas-wrapper-inner">
<canvas width="4000" height="3000"></canvas>
<div class="button">+</div>
</div>
</div>
</div>
<div class="right">
RIGHT OF WIDTH 10 EM
</div>
</div>
</div>
有一種方便的單位大小叫做cqmin,它是內(nèi)聯(lián)或塊大小的最小大小。將容器包裝器設(shè)置為size類型的容器,以便內(nèi)容響應(yīng)塊和內(nèi)聯(lián)尺寸,然后將畫布的寬度設(shè)置為100cqmin。使用縱橫比來保持呃縱橫比。參見下面的例子。我也在這里放了一個(gè)密碼本。
ctx = document.querySelector("canvas").getContext("2d");
ctx.fillStyle = "#FF0000"; ctx.fillRect(0, 0, 1000, 1000);
ctx.fillStyle = "#00FF00"; ctx.fillRect(1000, 1000, 1000, 1000);
ctx.fillStyle = "#0000FF"; ctx.fillRect(2000, 2000, 1000, 1000);
ctx.fillStyle = "#000000"; ctx.fillRect(3000, 0, 1000, 1000);
* {
padding: 0;
margin: 0;
}
.page {
display: flex;
flex-direction: column;
height: 100vh;
}
.toolbar {
background-color: yellow;
flex: 0 0 5em;
}
.container {
background-color: orange;
flex: 1 0 0;
display: flex;
}
.left {
container-type: size;
background-color: magenta;
flex: 1 0 0;
display: flex;
align-items: center;
justify-content: center;
}
.right {
background-color: salmon;
flex: 0 0 10em;
}
.canvas-wrapper {
position: relative;
width: 100cqmin;
}
.button {
background-color: yellow;
position: absolute;
top: 0;
right: 0;
width: 1em;
height: 1em;
}
canvas {
width: 100%;
aspect-ratio: 4/3;
background-color: white;
}
<div class="page">
<div class="toolbar">
TOOLBAR OF HEIGHT 5 EM
</div>
<div class="container">
<div class="left">
<div class="canvas-wrapper">
<canvas width="4000" height="3000"></canvas>
<div class="button">+</div>
</div>
</div>
<div class="right">
RIGHT OF WIDTH 10 EM
</div>
</div>
</div>
下面是基于RokBenko的答案的一個(gè)答案,這個(gè)答案似乎有效,但沒有第二個(gè)包裝器和第二個(gè)flex:
ctx = document.querySelector("canvas").getContext("2d");
ctx.fillStyle = "#FF0000";
ctx.fillRect(0, 0, 1000, 1000);
ctx.fillStyle = "#00FF00";
ctx.fillRect(1000, 1000, 1000, 1000);
ctx.fillStyle = "#0000FF";
ctx.fillRect(2000, 2000, 1000, 1000);
ctx.fillStyle = "#000000";
ctx.fillRect(3000, 0, 1000, 1000);
* {
padding: 0;
margin: 0;
}
.page {
display: flex;
flex-direction: column;
height: 100vh;
}
.toolbar {
background-color: yellow;
flex: 0 0 5em;
}
.container {
background-color: orange;
flex: 1 0 0;
display: flex;
}
.left {
background-color: magenta;
flex: 1 0 0;
display: flex;
align-items: center;
justify-content: center;
}
.right {
background-color: salmon;
flex: 0 0 10em;
}
.canvas-wrapper {
background-color: #aaa;
position: relative;
}
canvas {
background-color: white;
width: 100%;
max-height: calc(100vh - 5em);
}
.button {
background-color: yellow;
position: absolute;
top: 0;
right: 0;
width: 1em;
height: 1em;
}
<div class="page">
<div class="toolbar">
TOOLBAR OF HEIGHT 5 EM
</div>
<div class="container">
<div class="left">
<div class="canvas-wrapper">
<canvas width="4000" height="3000"></canvas>
<div class="button">+</div>
</div>
</div>
<div class="right">
RIGHT OF WIDTH 10 EM
</div>
</div>
</div>
canvas-wrapper需要與canvas具有相同的大小和位置,但是canvas的大小和位置基于它的grand parent。一個(gè)簡(jiǎn)單的解決方案是將畫布尺寸作為縱橫比復(fù)制到其父元素:
ctx = document.querySelector("canvas").getContext("2d");
ctx.fillStyle = "#FF0000";
ctx.fillRect(0, 0, 1000, 1000);
ctx.fillStyle = "#00FF00";
ctx.fillRect(1000, 1000, 1000, 1000);
ctx.fillStyle = "#0000FF";
ctx.fillRect(2000, 2000, 1000, 1000);
ctx.fillStyle = "#000000";
ctx.fillRect(3000, 0, 1000, 1000);
body {
margin: 0;
}
.page {
height: 100vh;
display: flex;
flex-direction: column;
}
.toolbar {
background-color: yellow;
flex: 0 0 5em;
}
.container {
background-color: orange;
flex: 1 1 auto;
/* wrapper for two column layout */
display: flex;
flex-direction: row;
}
.left {
background-color: magenta;
flex: 1 1 auto;
/* reference element for size and position */
position: relative;
}
.right {
background-color: salmon;
flex: 0 0 10em;
align-self: center;
}
.canvas-wrapper {
background-color: gray;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
max-width: 100%;
max-height: 100%;
}
canvas {
display: block;
width: 100%;
height: 100%;
}
.button {
background-color: cyan;
position: absolute;
top: 0;
right: 0;
padding: .5em;
}
<div class="page">
<div class="toolbar">
TOOLBAR OF HEIGHT 5 EM
</div>
<div class="container">
<div class="left">
<div class="canvas-wrapper" style="aspect-ratio: 4000 / 3000;">
<canvas width="4000" height="3000"></canvas>
<div class="button">+</div>
</div>
</div>
<div class="right">
RIGHT OF WIDTH 10 EM
</div>
</div>
</div>