canvas、ResizeObserver 和 FlexBox 之间的奇怪交互
A strange interaction between canvas, ResizeObserver and FlexBox
我正在尝试按照配方 here 进行自我调整 canvas(第 4 节末尾,“改为做什么”下)。所以我连接了一个 ResizeObserver
来监视我的 canvas 元素的变化。 canvas 元素具有 100% 的高度,并且位于容器元素内,该容器元素本身是 flex
元素的子元素。这种确切的情况似乎会导致 canvas 的高度随时间不断增加的连锁反应。
我想要这个的原因是因为我希望 canvas 填充它的容器,因此是 100% 的高度,但我不希望它的实际渲染内容被浏览器拉伸。
Here 是一个 JSFiddle,这里是代码中的最小示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body
{
display: flex;
}
main
{
max-height: 1000px; /* not necessary, for convenience */
}
canvas
{
height: 100%;
background-color: pink;
}
</style>
</head>
<body>
<main>
<canvas></canvas>
</main>
<script>
let canvas = document.querySelector("canvas");
let renderer = canvas.getContext("2d");
let resizeObserver = new ResizeObserver(render);
resizeObserver.observe(canvas);
function render()
{
renderer.canvas.height = renderer.canvas.clientHeight;
}
</script>
</body>
</html>
这是因为您的 canvas 将其 display
设置为 inline-block
,因此它受到父 <main>
的 line-height
值的影响,并且将在这个父级中占用比实际大小更多的space。
为避免这种情况,请将 <main>
的 line-height
设置为 0
,
let canvas = document.querySelector("canvas");
let renderer = canvas.getContext("2d");
let resizeObserver = new ResizeObserver(resize);
resizeObserver.observe(canvas, { box: "content-box"});
i = 0;
function resize()
{
canvas.height = canvas.clientHeight;
}
body
{
display: flex;
}
main
{
line-height: 0;
}
canvas
{
height: 100%;
background-color: pink;
}
<main>
<canvas></canvas>
</main>
或将<canvas>
显示设置为block
。
let canvas = document.querySelector("canvas");
let renderer = canvas.getContext("2d");
let resizeObserver = new ResizeObserver(resize);
resizeObserver.observe(canvas, { box: "content-box"});
i = 0;
function resize()
{
canvas.height = canvas.clientHeight;
}
body
{
display: flex;
}
canvas
{
height: 100%;
background-color: pink;
display: block;
}
<main>
<canvas></canvas>
</main>
我正在尝试按照配方 here 进行自我调整 canvas(第 4 节末尾,“改为做什么”下)。所以我连接了一个 ResizeObserver
来监视我的 canvas 元素的变化。 canvas 元素具有 100% 的高度,并且位于容器元素内,该容器元素本身是 flex
元素的子元素。这种确切的情况似乎会导致 canvas 的高度随时间不断增加的连锁反应。
我想要这个的原因是因为我希望 canvas 填充它的容器,因此是 100% 的高度,但我不希望它的实际渲染内容被浏览器拉伸。
Here 是一个 JSFiddle,这里是代码中的最小示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body
{
display: flex;
}
main
{
max-height: 1000px; /* not necessary, for convenience */
}
canvas
{
height: 100%;
background-color: pink;
}
</style>
</head>
<body>
<main>
<canvas></canvas>
</main>
<script>
let canvas = document.querySelector("canvas");
let renderer = canvas.getContext("2d");
let resizeObserver = new ResizeObserver(render);
resizeObserver.observe(canvas);
function render()
{
renderer.canvas.height = renderer.canvas.clientHeight;
}
</script>
</body>
</html>
这是因为您的 canvas 将其 display
设置为 inline-block
,因此它受到父 <main>
的 line-height
值的影响,并且将在这个父级中占用比实际大小更多的space。
为避免这种情况,请将 <main>
的 line-height
设置为 0
,
let canvas = document.querySelector("canvas");
let renderer = canvas.getContext("2d");
let resizeObserver = new ResizeObserver(resize);
resizeObserver.observe(canvas, { box: "content-box"});
i = 0;
function resize()
{
canvas.height = canvas.clientHeight;
}
body
{
display: flex;
}
main
{
line-height: 0;
}
canvas
{
height: 100%;
background-color: pink;
}
<main>
<canvas></canvas>
</main>
或将<canvas>
显示设置为block
。
let canvas = document.querySelector("canvas");
let renderer = canvas.getContext("2d");
let resizeObserver = new ResizeObserver(resize);
resizeObserver.observe(canvas, { box: "content-box"});
i = 0;
function resize()
{
canvas.height = canvas.clientHeight;
}
body
{
display: flex;
}
canvas
{
height: 100%;
background-color: pink;
display: block;
}
<main>
<canvas></canvas>
</main>