背景
这是一个非常难的问题,我现在已经苦苦挣扎了几天。我试图以幻灯片格式显示课程。所以课程由不同的幻灯片组成。现在覆盖在每张幻灯片的顶部的是一个适合屏幕大小的画布元素。
canvas.width = document.body.clientWidth;
canvas.height = document.body.clientHeight;
这允许教师在画布上绘制笔记并突出显示课程的各个部分。
问题
幻灯片的内容由HTML组成,加载幻灯片时看起来像这样。
当我调整页面大小时......
所以这里的问题是画布'图像'根据CSS页面的宽高比调整大小。
#theCanvas {
position:fixed;
top:0;
right:0;
bottom:0;
left:0;
}
但实际的HTML保持相同的大小,但重新排列其换行点,不好。
我尝试过什么
首先,我使用CSS根据窗口的宽度和高度调整所有HTML元素的大小:
h1 {
font-family: 'Open Sans Condensed', sans-serif;
color: #222222;
font-weight: 200;
font-size: 5.9vw;
}
h2 {
font-family: 'Open Sans Condensed', sans-serif;
color: #222222;
font-weight: 200;
font-size: 3.0vh;
}
h4 {
font-family: 'Open Sans Condensed', sans-serif;
color: #444444;
font-weight: 200;
font-size: 2vmin;
}
p {
font-family: 'Open Sans Condensed';
font-size: 2vmin;
font-weight: 200;
}
接下来我使用以下方法保存并调整画布图像的大小:
window.onresize = function(event) {
var data = canvas.toDataURL();
// resize the canvas
canvas.width = document.body.clientWidth;
canvas.height = document.body.clientHeight;
//alert($(container).width());
// scale and redraw the canvas content
var img=new Image();
img.width = document.body.clientWidth;
img.height = document.body.clientHeight;
img.onload=function(){
context.drawImage(img,0,0,img.width,img.height);
}
img.src=data;
};
全屏(1920px宽度)的结果
单击调整大小窗口按钮(1200px)
非常接近。
问题
现在当我拖动窗口的一角来调整大小时:
问题
1 - 当我手动调整窗口角落时,为什么window.onresize函数不会触发?
(奖金问题)我是否以正确的方式解决这个问题,或者是否需要在HTML元素上覆盖画布以进行交互式课程的麻烦呢?
答案 0 :(得分:7)
我想我误解了你的问题。
如果您希望手绘内容与html元素匹配,那么您需要确保HTML元素永远不会更改布局并始终保持相同的相对大小。在您的示例中,已经 NOT 的情况。你已经得到了这个" 25m"在左上方"欢迎"在中间,当你将页面拖得更高时,这2个元素的分离量与元素的其他大小不成比例,所以你已经要求的东西基本上不可能了。
您可以将SVG用于所有文本,这样就可以将其缩放到任意大小,而普通HTML文本也可以。换句话说,如果你使用SVG使页面变得非常高大,你会得到高而细的文本,所有的位置和大小都与原始位置和大小成正比,而HTML的文本也不会拉伸,你将大小设置为vh
的各种设置,但这只是意味着浏览器将选择大小,而不是按比例缩放文本。
示例:原始所需显示
将窗口更改为高大(font-size: 10vh;
)
请注意,字体未拉伸,因此相对尺寸和距离为" 25m"和欢迎"不再匹配
使用preserveAspectRatio="none"
现在请注意" 25m"和#34;欢迎"也高大瘦弱。这意味着如果你在画布上画了两个框,那么在缩放后两个框仍然会匹配。没有那些东西是不匹配的。
以上是
的HTML版本
body { margin: 0; }
.center {
position: absolute;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
font-size: 20vh;
}

<div id="time">25m</div>
<div class="center">
<div>Welcome</div>
</div>
&#13;
和SVG版本
body { margin: 0; }
#foo {
width: 100vw;
height: 100vh;
display: block;
}
&#13;
<svg
id="foo"
width="100%"
height="100%"
viewBox="0 0 640 480"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
preserveAspectRatio="none"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:space="preserve"
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">
<text x="187px" y="240px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:64px;">W<tspan x="246px 282px " y="240px 240.084px ">el</tspan>come</text>
<text x="19px" y="35px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:16px;">25m</text>
</svg>
&#13;
答案 1 :(得分:1)
您可以在没有任何调整大小事件的情况下响应画布。当你需要在画布上绘制某些东西时,你需要将一个点从窗口坐标转换为画布坐标。
#theCanvas {
max-width: 100%;
height: auto;
}
或
#theCanvas {
max-height: 100%;
width: auto;
}
=============================================== ============================
var actualCanvasSize = canvas.getBoundingClientRect();
var initialCanvasSize = {width:canvas.width, height:canvas.height};
你怎么看?
但是如果你想通过调整大小事件来做到这一点。有一个用于检测HTML元素调整大小的库。这个lib使用了一些css3技巧和窍门。并且工作完美,它更有用,可以通过窗口调整大小来解决您的问题。但是您需要将画布放在div中,然后将调整大小的侦听器附加到div。 github.com/sdecima/javascript-detect-element-resize