如何给 canvas max space 并在其上放置左(可滚动)和右 "menu" div?
How to give a canvas max space and place left (scrollable) and right "menu" divs on it?
我已经为我的问题准备了一个完整而简单的jsFiddle。
我的 word game 目前使用 HTML table 来布置 HTML canvas 和 jQuery UI 按钮。
我想摆脱 HTML table 而是使用 HTML div 元素,我已经在 red/yellow屏幕截图中带箭头的框:
我想要 div 元素的以下结构:
- fullDiv (should occupy 100% width and height of browser window)
-- hintDiv (100% width, min height, visible on top)
-- mainDiv (100% width, max height)
--- gameDiv (100% width, max height)
---- myCanvas (100% width, max height)
-- leftDiv (min width, same height as mainDiv, scrollable) <- relative position
-- rightDiv (min width, same height as mainDiv) <- relative position
-- totalDiv (100% width, min height, visible on bottom)
想法是尽可能多地给 myCanvas
space 并将 leftDiv
和 rightDiv
作为其两侧的“菜单”。 leftDiv
将是一个带有可滚动游戏列表的导航菜单,并且具有与 myCanvas
和 rightDiv
.
相同的最大可能高度
所以我尝试了下面的代码-
$(function () {
$(':button').button();
$('#fullCheck').checkboxradio();
var gamesMenu = $('#gamesMenu').menu({
items: '> :not(.ui-widget-header)'
});
for (var game = 1; game <= 50; game++) {
gamesMenu.append('<LI VALUE="' + game + '">GAME ' + game + '</LI>');
}
gamesMenu.menu('refresh');
});
body {
margin: 0;
padding: 0;
}
#fullDiv {
width: 100%;
height: 100vh;
background: #FFF;
}
#hintDiv,
#totalDiv {
text-align: center;
}
#mainDiv,
#gameDiv {
width: 100%;
height: 100%;
}
#myCanvas {
width: 100%;
height: 100%;
border: 4px red dotted;
background: #CCF;
}
#leftDiv {
position: relative;
left: 0;
top: 0;
/* bottom: 0; */
text-align: center;
background: #FCC;
}
#rightDiv {
position: relative;
right: 0;
top: 0;
/* bottom: 0; */
text-align: center;
background: #CFC;
}
#gamesMenu {
overflow-y: scroll;
}
#hintDiv {
font-style: italic;
}
<div id="fullDiv">
<div id="hintDiv">Hint</div>
<div id="mainDiv">
<div id="gameDiv">
<canvas id="myCanvas"></canvas>
</div>
<div id="leftDiv">
<button id="newBtn">New game</button>
<ul id="gamesMenu"></ul>
</div>
<div id="rightDiv">
<input id="fullCheck" type="checkbox">
<label for="fullCheck">Full screen</label><br>
<button id="recallBtn">Recall</button><br>
<button id="shuffleBtn">Shuffle</button><br>
<button id="swapBtn">Swap</button><br>
<button id="skipBtn">Skip</button><br>
<button id="resignBtn">Resign</button><br>
<button id="pileBtn">Pile</button><br>
<button id="movesBtn">Moves history</button><br>
<button id="shareBtn">Share</button><br>
<button id="playBtn">Play</button>
</div>
</div>
<div id="totalDiv">Total</div>
</div>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
但是,我的屏幕现在完全乱了:
- 元素
myCanvas
、leftDiv
和 rightDiv
被放置在彼此之后而不是 leftDiv
/rightDiv
覆盖 myCanvas
双方
myCanvas
占据整个浏览器 window,将 hintDiv
/totalDiv
推出屏幕
gamesMenu
完全显示而不是可滚动
更新:
这是 Derek 的解决方案(谢谢!)
$(function () {
$(':button').button();
$('#fullCheck').checkboxradio();
var gamesMenu = $('#gamesMenu').menu({
items: '> :not(.ui-widget-header)'
});
for (var game = 1; game <= 50; game++) {
gamesMenu.append('<LI VALUE="' + game + '">GAME ' + game + '</LI>');
}
gamesMenu.menu('refresh');
});
body {
margin: 0;
padding: 0;
}
#fullDiv {
width: 100%;
height: 100vh;
background: #FFF;
display: flex;
flex-direction: column;
}
#hintDiv,
#totalDiv {
text-align: center;
background: yellow;
}
#leftDiv {
text-align: center;
background: #FCC;
display: flex;
flex-direction: column;
}
#gamesMenu {
overflow-y: auto;
}
#mainDiv {
flex-grow: 1;
display: flex;
justify-content: space-between;
overflow: hidden;
}
#gameDiv {
flex-grow: 1;
}
#myCanvas {
width: 100%;
height: 100%;
box-sizing: border-box;
border: 4px red dotted;
background: #CCF;
}
#rightDiv {
text-align: center;
background: #CFC;
overflow-y: auto;
}
#hintDiv {
font-style: italic;
}
<div id="fullDiv">
<div id="hintDiv">Hint</div>
<div id="mainDiv">
<div id="leftDiv">
<button id="newBtn">New game</button>
<ul id="gamesMenu"></ul>
</div>
<div id="gameDiv">
<canvas id="myCanvas"></canvas>
</div>
<div id="rightDiv">
<input id="fullCheck" type="checkbox">
<label for="fullCheck">Full screen</label><br>
<button id="recallBtn">Recall</button><br>
<button id="shuffleBtn">Shuffle</button><br>
<button id="swapBtn">Swap</button><br>
<button id="skipBtn">Skip</button><br>
<button id="resignBtn">Resign</button><br>
<button id="pileBtn">Pile</button><br>
<button id="movesBtn">Moves history</button><br>
<button id="shareBtn">Share</button><br>
<button id="playBtn">Play</button>
</div>
</div>
<div id="totalDiv">Total</div>
</div>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
更新 2:
出于某种原因 jQuery UI 菜单不可悬停(尽管在 official demo 中是)...
目前我的解决方法是(至少可以看到所选项目):
li.selected {
font-weight: bold;
background-color: yellow;
}
var gamesMenu = $('#gamesMenu').menu({
items: '> :not(.ui-widget-header)',
select: function(ev, ui) {
ui.item.addClass('selected').siblings().removeClass('selected');
}
});
这可以使用 flex 布局来完成。
- 使
#fullDiv
与 flex-direction: column
一起使用 flex
布局,以便它可以在列上对齐。
- 将
flex: 1 1 auto
设置为#mainDiv
,这样就可以取space,除了#fullDiv
上的#hintDiv
和#totalDiv
。
- 也将
#mainDiv
设置为 flex
布局 justify-content: space-between
。你会在 this guide. 上知道的
- 根据该指南,交换
#leftDiv
和 #gameDiv
。
- 在
#gameDiv
上,我已将 canvas 宽度和高度更新为 calc(100% - 8px)
,因为边框大小将添加到实际 canvas 大小。所以现在,canvas 边框宽度是 4px 所以 canvas 宽度将是 (100% - 8px) + 8px(border size) = 100%
.
/*$(function () {
$(':button').button();
$('#fullCheck').checkboxradio();
var gamesMenu = $('#gamesMenu').menu({
items: '> :not(.ui-widget-header)'
});
for (var game = 1; game <= 50; game++) {
gamesMenu.append('<LI VALUE="' + game + '">GAME ' + game + '</LI>');
}
});*/
body {
font-family: Arial, Helvetica, sans-serif;
margin: 0;
padding: 0;
}
#fullDiv {
width: 100%;
height: 100vh;
background: #FFF;
}
#hintDiv,
#totalDiv {
text-align: center;
}
#myCanvas {
width: calc(100% - 8px);
height: calc(100% - 8px);
border: 4px red dotted;
background: #CCF;
}
#leftDiv {
text-align: center;
background: #FCC;
}
#rightDiv {
text-align: center;
background: #CFC;
}
#gamesMenu {
overflow-y: scroll;
}
#publishBtn {
max-width: 200px;
}
#timer1,
#timer2 {
color: red;
}
#hintDiv {
font-style: italic;
}
/*** Additional Codes ***/
#fullDiv {
display: flex;
flex-direction: column;
}
#mainDiv {
flex: 1 1 auto;
display: flex;
justify-content: space-between;
}
#gameDiv {
flex: 1 1 auto;
}
<div id="fullDiv">
<div id="hintDiv">Hint</div>
<div id="mainDiv">
<div id="leftDiv">
<button id="newBtn">New game</button>
<ul id="gamesMenu"></ul>
</div>
<div id="gameDiv">
<canvas id="myCanvas"></canvas>
</div>
<div id="rightDiv">
<input id="fullCheck" type="checkbox">
<label for="fullCheck">Full screen</label><br>
<button id="recallBtn">Recall</button><br>
<button id="shuffleBtn">Shuffle</button><br>
<button id="swapBtn">Swap</button><br>
<button id="skipBtn">Skip</button><br>
<button id="resignBtn">Resign</button><br>
<button id="pileBtn">Pile</button><br>
<button id="movesBtn">Moves history</button><br>
<button id="shareBtn">Share</button><br>
<button id="playBtn">Play</button>
</div>
</div>
<div id="totalDiv">Total</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
我已经为我的问题准备了一个完整而简单的jsFiddle。
我的 word game 目前使用 HTML table 来布置 HTML canvas 和 jQuery UI 按钮。
我想摆脱 HTML table 而是使用 HTML div 元素,我已经在 red/yellow屏幕截图中带箭头的框:
我想要 div 元素的以下结构:
- fullDiv (should occupy 100% width and height of browser window)
-- hintDiv (100% width, min height, visible on top)
-- mainDiv (100% width, max height)
--- gameDiv (100% width, max height)
---- myCanvas (100% width, max height)
-- leftDiv (min width, same height as mainDiv, scrollable) <- relative position
-- rightDiv (min width, same height as mainDiv) <- relative position
-- totalDiv (100% width, min height, visible on bottom)
想法是尽可能多地给 myCanvas
space 并将 leftDiv
和 rightDiv
作为其两侧的“菜单”。 leftDiv
将是一个带有可滚动游戏列表的导航菜单,并且具有与 myCanvas
和 rightDiv
.
所以我尝试了下面的代码-
$(function () {
$(':button').button();
$('#fullCheck').checkboxradio();
var gamesMenu = $('#gamesMenu').menu({
items: '> :not(.ui-widget-header)'
});
for (var game = 1; game <= 50; game++) {
gamesMenu.append('<LI VALUE="' + game + '">GAME ' + game + '</LI>');
}
gamesMenu.menu('refresh');
});
body {
margin: 0;
padding: 0;
}
#fullDiv {
width: 100%;
height: 100vh;
background: #FFF;
}
#hintDiv,
#totalDiv {
text-align: center;
}
#mainDiv,
#gameDiv {
width: 100%;
height: 100%;
}
#myCanvas {
width: 100%;
height: 100%;
border: 4px red dotted;
background: #CCF;
}
#leftDiv {
position: relative;
left: 0;
top: 0;
/* bottom: 0; */
text-align: center;
background: #FCC;
}
#rightDiv {
position: relative;
right: 0;
top: 0;
/* bottom: 0; */
text-align: center;
background: #CFC;
}
#gamesMenu {
overflow-y: scroll;
}
#hintDiv {
font-style: italic;
}
<div id="fullDiv">
<div id="hintDiv">Hint</div>
<div id="mainDiv">
<div id="gameDiv">
<canvas id="myCanvas"></canvas>
</div>
<div id="leftDiv">
<button id="newBtn">New game</button>
<ul id="gamesMenu"></ul>
</div>
<div id="rightDiv">
<input id="fullCheck" type="checkbox">
<label for="fullCheck">Full screen</label><br>
<button id="recallBtn">Recall</button><br>
<button id="shuffleBtn">Shuffle</button><br>
<button id="swapBtn">Swap</button><br>
<button id="skipBtn">Skip</button><br>
<button id="resignBtn">Resign</button><br>
<button id="pileBtn">Pile</button><br>
<button id="movesBtn">Moves history</button><br>
<button id="shareBtn">Share</button><br>
<button id="playBtn">Play</button>
</div>
</div>
<div id="totalDiv">Total</div>
</div>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
但是,我的屏幕现在完全乱了:
- 元素
myCanvas
、leftDiv
和rightDiv
被放置在彼此之后而不是leftDiv
/rightDiv
覆盖myCanvas
双方 myCanvas
占据整个浏览器 window,将hintDiv
/totalDiv
推出屏幕gamesMenu
完全显示而不是可滚动
更新:
这是 Derek 的解决方案(谢谢!)
$(function () {
$(':button').button();
$('#fullCheck').checkboxradio();
var gamesMenu = $('#gamesMenu').menu({
items: '> :not(.ui-widget-header)'
});
for (var game = 1; game <= 50; game++) {
gamesMenu.append('<LI VALUE="' + game + '">GAME ' + game + '</LI>');
}
gamesMenu.menu('refresh');
});
body {
margin: 0;
padding: 0;
}
#fullDiv {
width: 100%;
height: 100vh;
background: #FFF;
display: flex;
flex-direction: column;
}
#hintDiv,
#totalDiv {
text-align: center;
background: yellow;
}
#leftDiv {
text-align: center;
background: #FCC;
display: flex;
flex-direction: column;
}
#gamesMenu {
overflow-y: auto;
}
#mainDiv {
flex-grow: 1;
display: flex;
justify-content: space-between;
overflow: hidden;
}
#gameDiv {
flex-grow: 1;
}
#myCanvas {
width: 100%;
height: 100%;
box-sizing: border-box;
border: 4px red dotted;
background: #CCF;
}
#rightDiv {
text-align: center;
background: #CFC;
overflow-y: auto;
}
#hintDiv {
font-style: italic;
}
<div id="fullDiv">
<div id="hintDiv">Hint</div>
<div id="mainDiv">
<div id="leftDiv">
<button id="newBtn">New game</button>
<ul id="gamesMenu"></ul>
</div>
<div id="gameDiv">
<canvas id="myCanvas"></canvas>
</div>
<div id="rightDiv">
<input id="fullCheck" type="checkbox">
<label for="fullCheck">Full screen</label><br>
<button id="recallBtn">Recall</button><br>
<button id="shuffleBtn">Shuffle</button><br>
<button id="swapBtn">Swap</button><br>
<button id="skipBtn">Skip</button><br>
<button id="resignBtn">Resign</button><br>
<button id="pileBtn">Pile</button><br>
<button id="movesBtn">Moves history</button><br>
<button id="shareBtn">Share</button><br>
<button id="playBtn">Play</button>
</div>
</div>
<div id="totalDiv">Total</div>
</div>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
更新 2:
出于某种原因 jQuery UI 菜单不可悬停(尽管在 official demo 中是)...
目前我的解决方法是(至少可以看到所选项目):
li.selected {
font-weight: bold;
background-color: yellow;
}
var gamesMenu = $('#gamesMenu').menu({
items: '> :not(.ui-widget-header)',
select: function(ev, ui) {
ui.item.addClass('selected').siblings().removeClass('selected');
}
});
这可以使用 flex 布局来完成。
- 使
#fullDiv
与flex-direction: column
一起使用flex
布局,以便它可以在列上对齐。 - 将
flex: 1 1 auto
设置为#mainDiv
,这样就可以取space,除了#fullDiv
上的#hintDiv
和#totalDiv
。 - 也将
#mainDiv
设置为flex
布局justify-content: space-between
。你会在 this guide. 上知道的
- 根据该指南,交换
#leftDiv
和#gameDiv
。 - 在
#gameDiv
上,我已将 canvas 宽度和高度更新为calc(100% - 8px)
,因为边框大小将添加到实际 canvas 大小。所以现在,canvas 边框宽度是 4px 所以 canvas 宽度将是(100% - 8px) + 8px(border size) = 100%
.
/*$(function () {
$(':button').button();
$('#fullCheck').checkboxradio();
var gamesMenu = $('#gamesMenu').menu({
items: '> :not(.ui-widget-header)'
});
for (var game = 1; game <= 50; game++) {
gamesMenu.append('<LI VALUE="' + game + '">GAME ' + game + '</LI>');
}
});*/
body {
font-family: Arial, Helvetica, sans-serif;
margin: 0;
padding: 0;
}
#fullDiv {
width: 100%;
height: 100vh;
background: #FFF;
}
#hintDiv,
#totalDiv {
text-align: center;
}
#myCanvas {
width: calc(100% - 8px);
height: calc(100% - 8px);
border: 4px red dotted;
background: #CCF;
}
#leftDiv {
text-align: center;
background: #FCC;
}
#rightDiv {
text-align: center;
background: #CFC;
}
#gamesMenu {
overflow-y: scroll;
}
#publishBtn {
max-width: 200px;
}
#timer1,
#timer2 {
color: red;
}
#hintDiv {
font-style: italic;
}
/*** Additional Codes ***/
#fullDiv {
display: flex;
flex-direction: column;
}
#mainDiv {
flex: 1 1 auto;
display: flex;
justify-content: space-between;
}
#gameDiv {
flex: 1 1 auto;
}
<div id="fullDiv">
<div id="hintDiv">Hint</div>
<div id="mainDiv">
<div id="leftDiv">
<button id="newBtn">New game</button>
<ul id="gamesMenu"></ul>
</div>
<div id="gameDiv">
<canvas id="myCanvas"></canvas>
</div>
<div id="rightDiv">
<input id="fullCheck" type="checkbox">
<label for="fullCheck">Full screen</label><br>
<button id="recallBtn">Recall</button><br>
<button id="shuffleBtn">Shuffle</button><br>
<button id="swapBtn">Swap</button><br>
<button id="skipBtn">Skip</button><br>
<button id="resignBtn">Resign</button><br>
<button id="pileBtn">Pile</button><br>
<button id="movesBtn">Moves history</button><br>
<button id="shareBtn">Share</button><br>
<button id="playBtn">Play</button>
</div>
</div>
<div id="totalDiv">Total</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>