Bra*_*rad 20 css html5 css3 flexbox object-fit
我有一个外部容器,其大小和宽度可变.假设在这个容器里面,我有一个画布,我想尽可能多地增长,同时保持比例而不是裁剪.为此,我通常会使用object-fit: contain.
现在,假设不是仅仅使用画布,我有一个画布,旁边放置了另一个元素.
HTML:
<div class="outerContainer">
<canvas width="640" height="360"></canvas>
<div class="beside">
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
CSS:
.outerContainer {
display: flex;
border: 0.5em solid #444;
margin-bottom: 2em;
object-fit: contain;
}
.outerContainer canvas {
flex-grow: 1;
background: #77a;
}
/* This element has a fixed width, and should be whatever height the <canvas> is */
.outerContainer .beside {
flex-basis: 3em;
flex-grow: 0;
flex-shrink: 0;
background: #7a7;
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我想缩放整个outerContainer大小,就像我使用canvas一样.问题是object-fit实际上没有扩展元素......它会扩展其内容.这似乎不适用于普通块元素,导致如果有足够的宽度,内部画布可能会倾斜.
如果我添加object-fit: contain到canvas元素,它保持比例但仍使用全宽,这意味着.beside元素一直向右.这是用画布上的紫色背景可视化的.
我想要的是outerContainer使用画布内容进行缩放,以便.beside始终具有画布内容的高度.本.outerContainer应在父元素为中心,占据尽可能多的空间,因为它可以在不扭曲的画布.像这样,在任何比例尺度:
这对现代CSS有用吗?或者我必须使用脚本解决方案吗?
我不知道你是否可以,但我认为如果你允许更多的HTML,它可以主要在css中完成.
考虑以下html
<div class="outerContainer">
<div class="canvasContainer">
<canvas width="640" height="360"></canvas>
</div>
<div class="beside">
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
我刚刚在画布上添加了一个小div.这样我们就让画布处理它的东西,我们使用div来实现灵活的东西.
使用以下css:
* {
box-sizing: border-box;
}
.outerContainer {
display: flex;
border: 0.5em solid #444;
margin-bottom: 2em;
}
.canvasContainer canvas {
width: 100%;
background: #777;
margin-bottom: -4px
}
.canvasContainer {
flex-grow: 1;
background: #77a;
}
/* This element has a fixed width, and should be whatever height the <canvas> is */
.outerContainer .beside {
flex-basis: 3em;
flex-grow: 0;
flex-shrink: 0;
background: #7a7;
}
Run Code Online (Sandbox Code Playgroud)
我们有帆布容器占用所有可用空间.然后画布相应地适应图像缩放.但是我不知道为什么,画布的底部有一点余量,因此它的负边距.
小提琴:https://jsfiddle.net/L8p6xghb/3/
作为旁注,如果你想将它用于字幕,那么就有html5元素,就像<figure>和<figcaption>!
考虑到您需要的解决方案,我认为纯CSS 解决方案有点牵强 - 这是一个使用脚本的提案,涉及以下步骤:
找到最适合可用空间的图像的长宽比canvas
更新width和canvas的flexbox高度。
现在在画布中绘制图像。
请注意,为了便于说明,在调整窗口大小时,我重新加载了框架 - 有关详细信息,请参阅下面的演示(内联给出了更多解释):
// Document.ready
$(() => {
putImageOnCanvas();
});
// Window resize event
((() => {
window.addEventListener("resize", resizeThrottler, false);
var resizeTimeout;
function resizeThrottler() {
if (!resizeTimeout) {
resizeTimeout = setTimeout(function() {
resizeTimeout = null;
actualResizeHandler();
}, 66);
}
}
function actualResizeHandler() {
// handle the resize event - reloading page for illustration
window.location.reload();
}
})());
function putImageOnCanvas() {
$('.outerContainer canvas').each((index, canvas) => {
const ctx = canvas.getContext('2d');
canvas.width = $(canvas).innerWidth();
canvas.height = $(canvas).innerHeight();
const img = new Image;
img.src = 'https://static1.squarespace.com/static/56a1d17905caa7ee9f27e273/t/56a1d56617e4f1177a27178d/1453446712144/Picture7.png';
img.onload = (() => {
// find the aspect ratio that fits the container
let ratio = Math.min(canvas.width / img.width, canvas.height / img.height);
let centerShift_x = (canvas.width - img.width * ratio) / 2;
let centerShift_y = (canvas.height - img.height * ratio) / 2;
canvas.width -= 2 * centerShift_x;
canvas.height -= 2 * centerShift_y;
// reset the flexbox height and canvas flex-basis (adjusting for the 0.5em border too)
$('.outerContainer').css({
'height': 'calc(' + canvas.height + 'px + 1em)'
});
$('.outerContainer canvas').css({
'width': 'calc(' + canvas.width + 'px)'
});
// draw the image in the canvas now
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, img.width * ratio, img.height * ratio);
});
});
}Run Code Online (Sandbox Code Playgroud)
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.outerContainer {
display: flex;
border: 0.5em solid #444;
margin-bottom: 2em;
/*max available flexbox height*/
height: calc(100vh - 2em);
}
.outerContainer canvas {
background: #77a;
/*max available canvas width*/
width: calc(100vw - 4em);
}
.outerContainer .beside {
flex-basis: 3em;
flex-grow: 0;
flex-shrink: 0;
background: #7a7;
}Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="outerContainer">
<canvas></canvas>
<div class="beside">
</div>
</div>Run Code Online (Sandbox Code Playgroud)
编辑:
我最初的设置是flex-basis-canvas但 Firefox 表现不佳 - 所以现在我改用它width。
Snippet 在 Firefox 中再次出现屏幕大小调整(页面重新加载)问题 - 因此也包含了一个小提琴。