javascript - 为什么在收缩包含 flexbox 的 Canvas 时 BoundingClientRect 不折叠?

标签 javascript html css canvas flexbox

我有一个带有 <header> 的简单布局, 内容 <div>和一个 <footer> , 包裹在 <main> 中使用 flexbox .目的是当视口(viewport)调整大小时,中间的 Canvas 会增大/缩小,而页眉/页脚保持静态,这 3 个组件组合起来始终填充 100% 的视口(viewport)空间,而不会显示滚动条。

内容<div>当视口(viewport)调整大小时自动调整大小(由于 flex),但内部的 Canvas 需要明确重新调整尺寸。

我在窗口的 resize 上使用 Javascript 执行此操作事件,通过请求内容 <div>通过 getBoundingClientRect() 的新尺寸.

这在增加 窗口高度时完美运行,但在缩小时拒绝运行。 getBoundingClientRect()函数似乎永远不会为 height 返回一个较小的值.

出于某种原因,水平调整大小会导致 height回归急剧增加。这非常令人困惑。

我无法确定这是我使用 flexbox、使用 Canvas 还是使用 getBoundingClientRect() 的问题.

这是一个fiddle showing the problem ,这里是相关的代码片段:

HTML:

<main>
  <header>
    <h1>This is my header</h1>
  </header>
  <div id="content">
    <canvas id="canvas"></canvas>
  </div>
  <footer>
    <span>Simple footer text</span>
  </footer>
</main>

CSS:

main {
  /* Main page container with a standard column layout of header -> content -> footer */ 
  display: flex; 
  flex-direction: column;

  /* Ensure our main container is always 100% height */
  min-height: 100vh; 
}
canvas {
  display: block; /* Avoiding unexplainable weird behaviour */
}
#content {
  flex: 1; /* Stretch the content div to fill the <main> */
  overflow-y: auto;
}

Javascript:

var contentDiv = document.getElementById('content');
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var img = new Image();
var pattern;

// Load up an image and create a pattern
img.onload = function() {
  pattern = ctx.createPattern(img, 'repeat');
  resize();
  draw();
};
img.src = 'http://www.html5canvastutorials.com/demos/assets/wood-pattern.png';

// Resizes the <canvas> to match its parent, which has been sized by flex
function resize () {
    // Here is the problem.  INCREASING the height of the flexbox works
    // perfectly.  The canvas is resized appropriately.  However, DECREASING
    // it does nothing.  Even though the contentDiv is sized by flexbox,
    // its getBoundingClientRect() doesn't return a smaller height when
    // shrinking it.
    var boundingRect = contentDiv.getBoundingClientRect();
    canvas.height = boundingRect.height;
    canvas.width = boundingRect.width;
}

function draw () {
  ctx.rect(0, 0, canvas.width, canvas.height);
  ctx.fillStyle = pattern;
  ctx.fill();
}

window.addEventListener('resize', function () {
    resize();
    draw();
});

最佳答案

那是因为你正在使用

min-height: 100vh;

由于您只施加了一个最小值,当您减小窗口高度时, Canvas 不会神奇地缩小,因为约束已经成立。

相反,你应该使用

height: 100vh;

var contentDiv = document.getElementById('content');
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var img = new Image();
var pattern;

// Load up an image and create a pattern
img.onload = function() {
  pattern = ctx.createPattern(img, 'repeat');
  resize();
  draw();
};
img.src = 'http://www.html5canvastutorials.com/demos/assets/wood-pattern.png';

// Resizes the <canvas> to match its parent, which has been sized by flex
function resize () {
	// Here is the problem.  INCREASING the height of the flexbox works perfectly.  The canvas is resized appropriately.  However, DECREASING it does nothing.  Even though the contentDiv is sized by flexbox, its getBoundingClientRect() doesn't return a smaller height when shrinking it.
	var boundingRect = contentDiv.getBoundingClientRect();
	canvas.height = boundingRect.height;
  canvas.width = boundingRect.width;
}

function draw () {
  ctx.rect(0, 0, canvas.width, canvas.height);
  ctx.fillStyle = pattern;
  ctx.fill();
  
  ctx.font = "14pt Verdana";
  ctx.fillStyle = "lime";
  ctx.fillText('Resize the window vertically.', 40, 40);
  ctx.fillText('Watch the canvas increase in', 40, 70);
  ctx.fillText('height but NOT decrease!', 40, 100);
}
window.addEventListener('resize', function () {
	resize();
	draw();
});
html, body {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
header > h1 {
  margin: 0;
}
header, footer {
  background-color: #CCC;
}

main {
  /* Main page container with a standard column layout of header -> content -> footer */ 
  display: flex; 
  flex-direction: column;
  
  /* Ensure our main container is always 100% height */
  height: 100vh; 
}
canvas {
  display: block; /* Avoiding unexplainable weird behaviour */
}
#content {
  flex: 1; /* Stretch the content div to fill the <main> */
  overflow-y: auto;
}
<main>
  <header>
    <h1>This is my header</h1>
  </header>
  <div id="content">
    <canvas id="canvas"></canvas>
  </div>
  <footer>
    <span>Simple footer text</span>
  </footer>
</main>

关于javascript - 为什么在收缩包含 flexbox 的 Canvas 时 BoundingClientRect 不折叠?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39029629/

相关文章:

CSS定位问题

javascript - 在图像悬停Jquery上显示div

.net 相当于 Javascript 函数

javascript - 函数已定义但从未使用

php - 带有限制的php中的select语句

html - 使用浏览器让我的导航器改变大小

javascript - 如何获取具有特定元素的前一个元素?

javascript - 动态更改 React jsx 类,无需 DOM 操作

PHP - 根据文件夹名称激活链接

html - 页脚。它重叠在 div 上