如何解决当适合容器大小时,画布会变大
我要实现的布局是(无需阅读,JSFiddle不言自明。尝试调整大小):
- #content应该完全是屏幕/视口的100%高度,既不能高也不能低
- 两行,#content-header和#panels。 #panels行应填充垂直空间
- #panels应该包含div,其中一些是包装好的画布。画布应为正方形,其大小应为包装纸的宽度和高度的最小值。
我有2个问题:
- 调整窗口大小可使画布无限扩大。 (尝试调整JSFiddle框架的大小)
- 从最初的调整大小调用中可以猜出内容是垂直溢出的。
我试图使示例尽可能简单,并注释了大部分代码,希望足够了。
test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Test</title>
<link rel="stylesheet" href="normalize.css">
<link rel="stylesheet" href="test.css">
<script src="test.js"></script>
</head>
<body>
<div id="content">
<div id="content-header">HEADER</div>
<div id="panels">
<div class="canvas-wrapper">
<canvas id="test-canvas"></canvas>
</div>
</div>
</div>
</body>
</html>
test.css
/* Border box */
html {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
*,*::before,*::after {
-webkit-box-sizing: inherit;
-moz-box-sizing: inherit;
box-sizing: inherit;
}
/* Full height #content */
html,body,#content {
height: 100%;
}
/* #panels fills verical space */
#content {
display: flex;
flex-direction: column;
}
#content-header {
flex: 0 1 0;
}
#panels {
flex: 1 0 0;
}
/* #panels is flex row container */
#panels {
display: flex;
flex-direction: row;
}
/* Wrapping canvas to calculate size from flex container */
.canvas-wrapper {
display: block;
/* Can grow and can shrink */
flex: 1 1 auto;
background-color: rgba(0,255,0.2);
}
canvas {
display: block;
/* Center horizontally */
margin: 0 auto;
border: 1px solid red;
}
test.js
// width X height -> size X size,size is min(parentWidth,parentHeight)
function fitToParent(element) {
// parent element is the .canvas-wrapper
const parentWidth = element.parentElement.clientWidth;
const parentHeight = element.parentElement.clientHeight;
const size = Math.min(parentWidth,parentHeight);
// for debug
console.log('Wrapper size = ' + parentWidth + 'x' + parentHeight + ' Canvas size = ' + size + 'x' + size);
element.width = size;
element.height = size;
}
window.addEventListener('load',function() {
const canvas = document.getElementById('test-canvas');
const ctx = canvas.getContext('2d');
function resize() {
fitToParent(canvas);
// random draw operation,doesn't matter
ctx.fillStyle = 'green';
ctx.fillRect(10,10,150,100);
}
window.addEventListener('resize',resize);
resize();
});
解决方法
经过更多测试,似乎是由于#panels flex容器(或其他任何显示样式)将画布的尺寸最小化了,所以出现了问题。
我发现一种解决方法是在调整大小之前先将画布的宽度和高度设置为0。 但是我不确定是否应该这样做,它会引起一些我想避免的生涩动画。万一有人想到别的东西,我将等待接受这个答案。
第二个问题(垂直溢出)仍然存在。
// width X height -> size X size,size is min(parentWidth,parentHeight)
function fitToParent(element) {
// WORKAROUND
element.width = 0;
element.height = 0;
// parent element is the .canvas-wrapper
const parentWidth = element.parentElement.clientWidth;
const parentHeight = element.parentElement.clientHeight;
const size = Math.min(parentWidth,parentHeight);
// for debug
console.log('Wrapper size = ' + parentWidth + 'x' + parentHeight + ' Canvas size = ' + size + 'x' + size);
element.width = size;
element.height = size;
}
JSFiddle及其解决方法
编辑
很明显,画布的width和height属性不考虑框的大小,因此从边框溢出。通过将css属性设置为与元素属性(宽度,高度-> style.width,style.height)相同的值来解决。
所以,我认为第二个问题已解决。
// width X height -> size X size,parentHeight)
function fitToParent(element) {
// WORKAROUND
element.width = 0;
element.height = 0;
element.style.width = 0;
element.style.height = 0;
// parent element is the .canvas-wrapper
const parentWidth = element.parentElement.clientWidth;
const parentHeight = element.parentElement.clientHeight;
const size = Math.min(parentWidth,parentHeight);
// for debug
console.log('Wrapper size = ' + parentWidth + 'x' + parentHeight + ' Canvas size = ' + size + 'x' + size);
element.width = size;
element.height = size;
element.style.width = size + 'px';
element.style.height = size + 'px';
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。