【问题标题】:Two layered canvas scaled to automatically fill flex column space两层画布缩放以自动填充弹性列空间
【发布时间】:2023-01-18 00:27:34
【问题描述】:

我想要两个左画布(彼此叠放)以适应左列(100% 宽度减去右列的 300 像素宽度)。

即使画布的高度和宽度动态变化,它也应该工作,当画布宽度从 500 像素宽变为 1500 像素宽时,请在 1 秒和 3 秒后查看此处。

var c1 = document.getElementById("canvas1"), ctx1 = c1.getContext("2d");
var c2 = document.getElementById("canvas2"), ctx2 = c2.getContext("2d");
setTimeout(() => {
    ctx1.canvas.width = 500;
    ctx1.canvas.height = 300; 
    ctx1.rect(0, 0, 500, 300);
    ctx1.fill();
    ctx2.canvas.width = 500;
    ctx2.canvas.height = 300; 
    ctx2.rect(50, 50, 100, 100);
    ctx2.fillStyle = "green";
    ctx2.fill();
}, 1000);
setTimeout(() => {
    ctx1.canvas.width = 1500;
    ctx1.canvas.height = 500; 
    ctx1.rect(0, 0, 1500, 500);
    ctx1.fill();
    ctx2.canvas.width = 1500;
    ctx2.canvas.height = 500; 
    ctx2.rect(100, 100, 100, 100);
    ctx2.fillStyle = "red";
    ctx2.fill();
}, 3000);
.container { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; background-color: yellow; }
.column { border: 1px solid black; }
.canvas-wrapper { margin: 1rem; flex: 1; }
#canvas2 { position: absolute; top: 0; left: 0; }
.right-column { width: 300px; }
<div class="container">
    <div class="canvas-wrapper column">
        <canvas id="canvas1"></canvas>
        <canvas id="canvas2"></canvas>
    </div>
    <div class="right-column column">
        Hello world
    </div>
</div>

它应该是这样的,在这两种情况下都应该重新缩放以适合左列。
在第二种情况下(红色方块),画布应按比例缩小以适合左列(例如,如果浏览器视口宽度为 1300 像素,宽度为 ~1000 像素,减去右列的 300 像素) , 即使真正的画布宽度仍然是 1500 px.

我尝试了flexbox 的多种变体,但没有成功。

如果可能的话,我想保留 flex 并避免使用 calc(100% - 300px) 规则。

TL;DR:如何使两个相同大小的分层画布彼此重叠(此大小可以变化)自动适合 flex 布局中的列?

【问题讨论】:

    标签: javascript html css canvas flexbox


    【解决方案1】:

    更改为网格有帮助吗?

    这个 sn-p 在网格中有两列,第一列占据了 300px 列之后剩下的部分。画布的宽度和高度设置为单元格尺寸的最大值。

    var c1 = document.getElementById("canvas1"),
      ctx1 = c1.getContext("2d");
    var c2 = document.getElementById("canvas2"),
      ctx2 = c2.getContext("2d");
    setTimeout(() => {
      ctx1.canvas.width = 500;
      ctx1.canvas.height = 300;
      ctx1.rect(0, 0, 500, 300);
      ctx1.fill();
      ctx2.canvas.width = 500;
      ctx2.canvas.height = 300;
      ctx2.rect(50, 50, 100, 100);
      ctx2.fillStyle = "green";
      ctx2.fill();
    }, 1000);
    setTimeout(() => {
      ctx1.canvas.width = 1500;
      ctx1.canvas.height = 500;
      ctx1.rect(0, 0, 1500, 500);
      ctx1.fill();
      ctx2.canvas.width = 1500;
      ctx2.canvas.height = 500;
      ctx2.rect(100, 100, 100, 100);
      ctx2.fillStyle = "red";
      ctx2.fill();
    }, 3000);
    .container {
      display: grid;
      grid-template-columns: 1fr 300px;
      align-items: center;
      justify-content: center;
      width: 100%;
      height: 100%;
      background-color: yellow;
    }
    
    .column {
      border: 1px solid black;
    }
    
    .canvas-wrapper {
      margin: 1rem;
      flex: 1;
    }
    
    #canvas2 {
      position: absolute;
      top: 0;
      left: 0;
    }
    
    canvas {
      max-width: 100%;
      max-height: 100%;
    }
    
    .right-column {
      width: 300px;
    }
    <div class="container">
      <div class="canvas-wrapper column">
        <canvas id="canvas1"></canvas>
        <canvas id="canvas2"></canvas>
      </div>
      <div class="right-column column">
        Hello world
      </div>
    </div>

    【讨论】:

    • 谢谢@AHaworth,最大宽度/最大高度确实在做这项工作!最后一件事:你如何自动将画布垂直/水平居中在左列中(就像我的模型截图一样)?这可能在没有额外的 flex/grid 的情况下可行,但直接使用现有的 grid,对吗?
    猜你喜欢
    • 1970-01-01
    • 2017-04-17
    • 1970-01-01
    • 1970-01-01
    • 2019-01-05
    • 2010-12-11
    • 2014-05-14
    • 1970-01-01
    • 2016-05-12
    相关资源
    最近更新 更多