如何在电影院大厅布置座位之类的东西 [英] How to layout something like seats in cinema hall
问题描述
我想设计如下所示的东西.我应该如何在html/css中进行布局.我应该使用table还是flex更好呢?
I would like to design something like shown below.How should I go about laying it out in html/css.Should I use table or flex would be better or something else?
推荐答案
虽然这种风格的问题倾向于产生基于意见的答案,但人们对此并不满意,我认为就如何解决某个问题来征询专家意见是合理的在人们开始投资这项工作之前.
While questions of this style tend to produce opinion based answers and are as such frowned upon, I consider it legitimate to query expert opinions on how to tackle a certain problem before one starts to invest the work.
现在,我绝对不是html专家.但是,尽管没有在问题中提到,但我想这可能是关于在Web应用程序中显示状态信息,而不是在静态HTML文档中显示状态信息.也许在上下文中这是需要的,可能有一个Websocket或一些基于计时器的页面更新.座位分配数据可能来自服务器.
Now, by no means am I an html expert. But, while not mentioned in the question, I fancy this could be about displaying a status information in a web application rather than a static HTML document. Maybe within the context this is needed, there is a websocket or some timer based update of the page involved. And the seat allocation data might come from a server.
在我上面描述的场景中,没有表的一种实现方法如下所示.借助画布(如果花费了足够的时间,可以进行漂亮的渲染)和具有javascript函数,可以使用从某处进入脚本的数据.
In the scenario I depicted above, one way to do it without a table could be as shown below. With a canvas (which allows for pretty rendering, if enough time is invested) and with a javascript function, using the data coming into the script from somewhere.
这种方法是否优于基于html表格的解决方案,可能归结为:
Whether this approach is preferable to a html table based solution, might come down to:
- 这张照片应该有多漂亮?
- 什么是比较烦人的工作?用脚本填充html表或在脚本中渲染画布图片?
这是一个展示此方法的小原型:
Here a small prototype showing this approach:
<!DOCTYPE html>
<html>
<head>
<title>Demo of a canvas used to render seat plan in a Cinema</title>
<script>
var EMPTY = 0; // Still available for reservation and purchase.
var RESERVED = 1; // reserved but not yet paid for.
var BOUGHT = 2; // bought and paid for.
function Point(x,y) {
return { X: x, Y: y }
}
function Size(w,h) {
return {Width: w, Height: h}
}
function Rectangle(left,top,width,height) {
return {TopLeft: Point(left,top), Size: Size(width,height)}
}
function seatColorFromSeatStatus(seatStatus) {
switch(seatStatus) {
case EMPTY: return "white";
case RESERVED: return "green";
case BOUGHT: return "red";
default: return "black"; // Invalid value...
}
}
function mapSeatStatusToSeatColor(seats)
{
var result = {};
for(seat in seats) {
result[seat] = seatColorFromSeatStatus(seats[seat])
}
return result;
}
function seatKeyFromPosition(row,col) {
return JSON.stringify([row,col]);
}
function seatRowFromKey(key) {
return (JSON.parse(key))[0];
}
function seatColFromKey(key) {
return (JSON.parse(key)[1]);
}
function getSeatInfo(nrows,ncolumns) {
var result = { NRows: nrows, NColumns: ncolumns, Seats : {} };
for(row = 0; row < nrows; row++) {
for( col = 0; col < ncolumns; col++ ) {
result.Seats[seatKeyFromPosition(row,col)] = EMPTY;
}
}
result.Seats[seatKeyFromPosition(0,0)] = RESERVED;
result.Seats[seatKeyFromPosition(1,3)] = BOUGHT;
return result;
}
function renderSeat(ctx,r,fillColor) {
var backup = ctx.fillStyle;
ctx.strokeStyle = "blue";
ctx.rect(r.TopLeft.X+2,r.TopLeft.Y+2,r.Size.Width-4,r.Size.Height-4);
ctx.stroke();
ctx.fillStyle = fillColor;
ctx.fillRect(r.TopLeft.X+3,r.TopLeft.Y+3,r.Size.Width-5,r.Size.Height-5);
ctx.fillStyle = backup;
}
function renderSeatplan(seatInfo) {
var nrows = seatInfo.NRows;
var ncolumns = seatInfo.NColumns;
var seatColors = mapSeatStatusToSeatColor(seatInfo.Seats)
var canvas = document.getElementById("seatplan");
var ctx = canvas.getContext("2d");
var borderWidth = 10;
var rcContent = Rectangle(
borderWidth
, borderWidth
, canvas.width - 2 * borderWidth
, canvas.height - 2 * borderWidth
);
var szCell = Size(
Math.floor(rcContent.Size.Width / (ncolumns + 1))
, Math.floor(rcContent.Size.Height / (nrows + 1))
);
ctx.font = "30px Arial";
for(row = -1; row < nrows; row++) {
for(col = -1; col < ncolumns; col++ ) {
var r = Rectangle(
rcContent.TopLeft.X + szCell.Width * (col+1)
,rcContent.TopLeft.Y + szCell.Height * (row+1)
,szCell.Width
,szCell.Height
);
var center = Point(szCell.Width / 2, szCell.Height / 2);
if (row == -1 && col == -1) {
// nothing to render.
}
else if(row == -1){
// render column headers as numbers...
ctx.fillStyle = "black";
ctx.textAlign = "center";
ctx.fillText(col.toString(),r.TopLeft.X+center.X,r.TopLeft.Y+center.Y+6);
}
else if(col == -1){
// render row header
ctx.fillStyle = "black";
ctx.textAlign = "center";
ctx.fillText(String.fromCharCode(65 + row),r.TopLeft.X+center.X+4,r.TopLeft.Y+center.Y+6);
}
else
{
// render seat
renderSeat(ctx,r,seatColors[seatKeyFromPosition(row,col)]);
}
}
}
}
</script>
</head>
<body onload="renderSeatplan(getSeatInfo(10,16));">
<h1>Seatplan</h1>
<canvas id="seatplan" width="640" height="480"></canvas>
</body>
</html>
由于这是一个简单的方法,因此不要忘记,存在可以用更少的代码行解决相同问题的Web框架(例如angular,node.js等).
As this is a bare bone approach, it shall not be left unmentioned, that there are web frameworks (e.g. angular, node.js, ... ) which might solve the same problem in far fewer lines of code.
最后,我向所有实际上是html专家并发现我的编码风格很糟糕的人致歉;)
Last not least, my apologies to all those who actually are html experts and find my coding style terrible ;)
这篇关于如何在电影院大厅布置座位之类的东西的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!