Browse Source

Platform: use CSS classes instead of IDs for Emscripten markup.

IDs restrict the usability to a single canvas on the page. For backwards
compatibility purposes those are still kept, but the use is discouraged
now.
pull/481/head
Vladimír Vondruš 6 years ago
parent
commit
2d0c97d4c0
  1. 151
      doc/platforms-html5.dox
  2. 117
      src/Magnum/Platform/WebApplication.css

151
doc/platforms-html5.dox

@ -129,11 +129,11 @@ variables.
</head> </head>
<body> <body>
<h1>Magnum Emscripten Application</h1> <h1>Magnum Emscripten Application</h1>
<div id="container"> <div class="mn-container">
<div id="sizer"><div id="expander"><div id="listener"> <div class="mn-sizer"><div class="mn-expander"><div class="mn-listener">
<canvas id="canvas"></canvas> <canvas class="mn-canvas" id="canvas"></canvas>
<div id="status">Initialization...</div> <div class="mn-status" id="status">Initialization...</div>
<div id="status-description"></div> <div class="mn-status-description" id="status-description"></div>
<script src="EmscriptenApplication.js"></script> <script src="EmscriptenApplication.js"></script>
<script async="async" src="{{ application }}.js"></script> <script async="async" src="{{ application }}.js"></script>
</div></div></div> </div></div></div>
@ -142,17 +142,29 @@ variables.
</html> </html>
@endcode @endcode
@m_class{m-note m-danger}
@par
For backwards compatibility purposes the default CSS style supports also
@cb{.css} #container @ce, @cb{.css} #sizer @ce, @cb{.css} #expander @ce,
@cb{.css} #listener @ce, @cb{.css} #canvas @ce, @cb{.css} #status @ce and
@cb{.css} #status-description @ce IDs instead of the @cb{.css} .mn- @ce
prefixed classes, but their use is discouraged as the classes are less
likely to clash with other markup and allow more than one
@cb{.html} <canvas> @ce on a page. This compatibility is scheduled to be
removed in the future.
For basic usage you don't need to modify the CSS and JS files at all and For basic usage you don't need to modify the CSS and JS files at all and
everything can be set up directly from the HTML markup. Replace everything can be set up directly from the HTML markup. Replace
@cb{.jinja} {{ application }} @ce with the name of your application executable @cb{.jinja} {{ application }} @ce with the name of your application executable
and adapt page title and heading as desired. You can modify all files to your and adapt page title and heading as desired. You can modify all files to your
liking, but the HTML file must contain at least liking, but the HTML file must contain at least a
@cb{.html} <canvas id="canvas"> @ce enclosed in @cb{.html} <canvas id="canvas"> @ce referenced in @cb{.js} Module.canvas @ce.
@cb{.html} <div id="listener"> @ce. The JavaScript file contains event The JavaScript file contains event listeners that print loading status on the
listeners that print loading status on the page. The status is displayed in the page. The status is displayed in the remaining two @cb{.html} <div> @ce s, if
remaining two @cb{.html} <div> @ce s, if they are available. The CSS file they are available. The CSS file contains a basic style, see
contains a basic style, see @ref platforms-html5-layout "below" for available @ref platforms-html5-layout "below" for available options to tweak the default
options to tweak the default look. look.
In order to deploy the app, you need to put the JS driver code, the WebAssembly In order to deploy the app, you need to put the JS driver code, the WebAssembly
binary (or the asm.js memory image, in case you are compiling with the classic binary (or the asm.js memory image, in case you are compiling with the classic
@ -228,12 +240,12 @@ and `MAGNUM_WEBAPPLICATION_CSS` CMake variables.
</head> </head>
<body> <body>
<h1>Magnum Windowless Emscripten Application</h1> <h1>Magnum Windowless Emscripten Application</h1>
<div id="container"> <div class="mn-container">
<div id="sizer"><div id="expander"><div id="listener"> <div class="mn-sizer"><div class="mn-expander"><div class="mn-listener">
<canvas id="canvas" class="hidden"></canvas> <canvas class="mn-canvas mn-hidden" id="canvas"></canvas>
<pre id="log"></pre> <pre class="mn-log" id="log"></pre>
<div id="status">Initialization...</div> <div class="mn-status" id="status">Initialization...</div>
<div id="status-description"></div> <div class="mn-status-description" id="status-description"></div>
<script src="WindowlessEmscriptenApplication.js"></script> <script src="WindowlessEmscriptenApplication.js"></script>
<script async="async" src="{{ application }}.js"></script> <script async="async" src="{{ application }}.js"></script>
</div></div></div> </div></div></div>
@ -242,6 +254,18 @@ and `MAGNUM_WEBAPPLICATION_CSS` CMake variables.
</html> </html>
@endcode @endcode
@m_class{m-note m-danger}
@par
For backwards compatibility purposes the default CSS style supports also
@cb{.css} #container @ce, @cb{.css} #sizer @ce, @cb{.css} #expander @ce,
@cb{.css} #listener @ce, @cb{.css} #canvas @ce, @cb{.css} #log @ce,
@cb{.css} #status @ce and @cb{.css} #status-description @ce IDs instead of
the @cb{.css} .mn- @ce prefixed classes, but their use is discouraged as
the classes are less likely to clash with other markup and allow more than
one @cb{.html} <canvas> @ce on a page. This compatibility is scheduled to
be removed in the future.
Replace @cb{.jinja} {{ application }} @ce with the name of your application Replace @cb{.jinja} {{ application }} @ce with the name of your application
executable. You can modify all the files to your liking, but the HTML file must executable. You can modify all the files to your liking, but the HTML file must
contain at least the @cb{.html} <canvas> @ce enclosed in listener @cb{.html} <div> @ce contain at least the @cb{.html} <canvas> @ce enclosed in listener @cb{.html} <div> @ce
@ -273,69 +297,82 @@ endif()
@section platforms-html5-layout Modifying page style, canvas size and aspect ratio @section platforms-html5-layout Modifying page style, canvas size and aspect ratio
The `WebApplication.css` file contains a basic style and the additional The `WebApplication.css` file contains a basic style and the additional
@cb{.css} #container @ce, @cb{.css} #sizer @ce, @cb{.css} #expander @ce and @cb{.css} .mn-container @ce, @cb{.css} .mn-sizer @ce, @cb{.css} .mn-expander @ce
@cb{.css} #listener @ce @cb{.html} <div> @ce s take care of aligning the canvas and @cb{.css} .mn-listener @ce @cb{.html} <div> @ce s take care of aligning the
to the center and making it responsively scale on narrow screens, preserving canvas to the center and making it responsively scale on narrow screens,
aspect ratio. For proper responsiveness on all platforms it's important to preserving aspect ratio. For proper responsiveness on all platforms it's
include the @cb{.html} <meta name="viewport"> @ce tag in the HTML markup as important to include the @cb{.html} <meta name="viewport"> @ce tag in the HTML
well. markup as well.
By default the canvas is @cpp 640px @ce wide with a 4:3 aspect ratio, you can By default the canvas is @cpp 640px @ce wide with a 4:3 aspect ratio, you can
modify this by placing one of the @cb{.css} .aspect-* @ce CSS classes on the modify this by placing one of the @cb{.css} .mn-aspect-* @ce CSS classes on the
@cb{.html} <div id="container"> @ce: @cb{.html} <div class="mn-container"> @ce:
Aspect ratio | CSS class (landscape/portrait) Aspect ratio | CSS class (landscape/portrait)
--------------- | ------------------------------ --------------- | ------------------------------
1:1 | @cb{.css} .aspect-1-1 @ce <b></b> 1:1 | @cb{.css} .mn-aspect-1-1 @ce <b></b>
4:3 (1.33:1) | @cb{.css} .aspect-4-3 @ce (default) / @cb{.css} .aspect-3-4 @ce 4:3 (1.33:1) | @cb{.css} .mn-aspect-4-3 @ce (default) / @cb{.css} .mn-aspect-3-4 @ce
3:2 (1.5:1) | @cb{.css} .aspect-3-2 @ce / @cb{.css} .aspect-2-3 @ce 3:2 (1.5:1) | @cb{.css} .mn-aspect-3-2 @ce / @cb{.css} .mn-aspect-2-3 @ce
16:9 (1.78:1) | @cb{.css} .aspect-16-9 @ce / @cb{.css} .aspect-9-16 @ce 16:9 (1.78:1) | @cb{.css} .mn-aspect-16-9 @ce / @cb{.css} .mn-aspect-9-16 @ce
2:1 | @cb{.css} .aspect-2-1 @ce / @cb{.css} .aspect-1-2 @ce 2:1 | @cb{.css} .mn-aspect-2-1 @ce / @cb{.css} .mn-aspect-1-2 @ce
For example, for a 640x360 canvas (16:9 aspect ratio), you would use For example, for a 640x360 canvas (16:9 aspect ratio), you would use
@cb{.html} <div id="container" class="aspect-16-9"> @ce. Besides the predefined @cb{.html} <div class="mn-container mn-aspect-16-9"> @ce. Besides the
classes above, it's also possible to specify your own aspect ratio using a predefined classes above, it's also possible to specify your own aspect ratio
@cb{.css} padding-bottom @ce style with a percentage equal to inverse of using a @cb{.css} padding-bottom @ce style with a percentage equal to inverse
the ratio for @cb{.css} div#expander @ce --- for example, a 2.35:1 ratio would of the ratio for @cb{.css} div#expander @ce --- for example, a 2.35:1 ratio
be @cb{.html} <div id="expander" style="padding-bottom: 42.553%"> @ce. would be @cb{.html} <div class="mn-expander" style="padding-bottom: 42.553%"> @ce.
Size of the canvas can be also overriden by specifying one of the Size of the canvas can be also overriden by specifying one of the
@cb{.css} .width-* @ce CSS classes on the @cb{.html} <div id="container"> @ce: @cb{.css} .mn-width-* @ce CSS classes on the
@cb{.html} <div class="mn-container"> @ce:
Width | CSS class Width | CSS class
--------------- | --------- --------------- | ---------
240px | @cb{.css} .width-240 @ce <b></b> 240px | @cb{.css} .mn-width-240 @ce <b></b>
320px | @cb{.css} .width-320 @ce <b></b> 320px | @cb{.css} .mn-width-320 @ce <b></b>
360px | @cb{.css} .width-360 @ce <b></b> 360px | @cb{.css} .mn-width-360 @ce <b></b>
480px | @cb{.css} .width-480 @ce <b></b> 480px | @cb{.css} .mn-width-480 @ce <b></b>
600px | @cb{.css} .width-600 @ce <b></b> 600px | @cb{.css} .mn-width-600 @ce <b></b>
640px | @cb{.css} .width-640 @ce (default) 640px | @cb{.css} .mn-width-640 @ce (default)
800px | @cb{.css} .width-800 @ce <b></b> 800px | @cb{.css} .mn-width-800 @ce <b></b>
For example, for a 480x640 canvas (3:4, portrait) you would use For example, for a 480x640 canvas (3:4, portrait) you would use
@cb{.html} <div id="container" class="width-480 aspect-3-4"> @ce. Besides the @cb{.html} <div class="mn-container mn-width-480 mn-aspect-3-4"> @ce. Besides
predefined classes above, it's also possible to specify your own by adding a the predefined classes above, it's also possible to specify your own by adding
@cb{.css} width @ce style to the @cb{.css} div#sizer @ce --- for example, a a @cb{.css} width @ce style to the @cb{.css} div.mn-sizer @ce --- for example,
1024x768 canvas would be @cb{.html} <div id="sizer" style="width: 1024px"> @ce. a 1024x768 canvas would be
Again note that if the canvas is larger than window width, it gets @cb{.html} <div class="mn-sizer" style="width: 1024px"> @ce. Again note that if
automatically scaled down, preserving its aspect ratio. the canvas is larger than window width, it gets automatically scaled down,
preserving its aspect ratio.
It's also possible to stretch the canvas to occupy the full page using the It's also possible to stretch the canvas to occupy the full page using the
@cb{.css} .fullsize @ce CSS class set to @cb{.css} div#container @ce. In this @cb{.css} .mn-fullsize @ce CSS class set to @cb{.css} div.mn-container @ce. In
case it's advised to remove all other elements (such as the @cb{.html} <h1> @ce this case it's advised to remove all other elements (such as the
element) from the page to avoid them affecting the canvas. Combining @cb{.html} <h1> @ce element) from the page to avoid them affecting the canvas.
@cb{.css} .fullsize @ce with the other @cb{.css} .aspect-* @ce or Combining @cb{.css} .mn-fullsize @ce with the other @cb{.css} .mn-aspect-* @ce
@cb{.css} .width-* @ce classes is not supported. or @cb{.css} .mn-width-* @ce classes is not supported.
Besides the canvas, there's minimal styling for @cb{.html} <h1> @ce, Besides the canvas, there's minimal styling for @cb{.html} <h1> @ce,
@cb{.html} <p> @ce and @cb{.html} <code> @ce tags. Putting extra content inside @cb{.html} <p> @ce and @cb{.html} <code> @ce tags. Putting extra content inside
the @cb{.css} div#sizer @ce will center it, following the canvas width. If you the @cb{.css} div.mn-sizer @ce will center it, following the canvas width. If
need more advanced styling, check out [m.css](https://mcss.mosra.cz). you need more advanced styling, check out [m.css](https://mcss.mosra.cz).
@note It's also possible to modify the container CSS classes from the C++ side @note It's also possible to modify the container CSS classes from the C++ side
using @ref Platform::EmscriptenApplication::setContainerCssClass() / using @ref Platform::EmscriptenApplication::setContainerCssClass() /
@ref Platform::Sdl2Application::setContainerCssClass(). @ref Platform::Sdl2Application::setContainerCssClass().
@m_class{m-note m-danger}
@par
For backwards compatibility purposes, on a markup that uses the discouraged
@cb{.css} #container @ce, @cb{.css} #sizer @ce, @cb{.css} #expander @ce,
@cb{.css} #listener @ce, @cb{.css} #status @ce, @cb{.css} #canvas @ce and
@cb{.css} #status-description @ce IDs, the above @cb{.css} .mn-width-* @ce
and @cb{.css} .mn-aspect-* @ce CSS classes are supported without the
@cb{.css} .mn- @ce prefix. This compatibility is scheduled to be removed in
the future.
@section platforms-html5-files Bundling files @section platforms-html5-files Bundling files
Emscripten applications don't have access to a filesystem, which means you need Emscripten applications don't have access to a filesystem, which means you need

117
src/Magnum/Platform/WebApplication.css

@ -36,31 +36,37 @@ body {
color: #dcdcdc; /*var(--color)*/ color: #dcdcdc; /*var(--color)*/
} }
/* #container makes the canvas occupy the whole page width /* .mn-container makes the canvas occupy the whole page width
#sizer centers it .mn-sizer centers it
#expander does aspect ratio preservation .mn-expander does aspect ratio preservation
#listener snaps to #expander edges .mn-listener snaps to #expander edges
#listener::before does the border, which finally goes below the canvas */ .mn-listener::before does the border, which finally goes below the canvas
#container { .mn-canvas is the canvas
The #container, #sizer, #expander, #listener, #canvas IDs are kept for
backwards compatibility purposes but are discouraged as the mn-prefixed
classes are less likely to clash with other markup and allow more than one
canvas on a page. TODO: remove in 2022 and require classes */
.mn-container, #container {
margin: 1rem -1rem 1rem -1rem; margin: 1rem -1rem 1rem -1rem;
} }
#sizer { .mn-sizer, #sizer {
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
max-width: 100%; max-width: 100%;
width: 640px; width: 640px;
} }
#expander { .mn-expander, #expander {
position: relative; position: relative;
} }
#listener { .mn-listener, #listener {
position: absolute; position: absolute;
top: 0; top: 0;
bottom: 0; bottom: 0;
left: 0; left: 0;
right: 0; right: 0;
} }
#listener::before { .mn-listener::before, #listener::before {
position: absolute; position: absolute;
content: ' '; content: ' ';
top: 0; top: 0;
@ -74,8 +80,9 @@ body {
border-color: #405363; /*var(--line-color)*/ border-color: #405363; /*var(--line-color)*/
} }
/* Canvas size and aspect ratio knobs */ /* Canvas size and aspect ratio knobs. Again the unprefixed variants are for
#container.fullsize { backwards compatibility purposes. */
.mn-container.mn-fullsize, #container.fullsize {
position: absolute; position: absolute;
top: 0; top: 0;
bottom: 0; bottom: 0;
@ -83,63 +90,97 @@ body {
right: 0; right: 0;
margin: 0; margin: 0;
} }
#container.fullsize #sizer, #container.fullsize #expander { .mn-container.mn-fullsize .mn-sizer, #container.fullsize #sizer,
.mn-container.mn-fullsize .mn-expander, #container.fullsize #expander {
width: 100%; height: 100%; width: 100%; height: 100%;
} }
#container.width-240 #sizer { width: 240px; } .mn-container.mn-width-240 .mn-sizer, #container.width-240 #sizer {
#container.width-320 #sizer { width: 320px; } width: 240px;
#container.width-360 #sizer { width: 360px; } }
#container.width-480 #sizer { width: 480px; } .mn-container.mn-width-320 .mn-sizer, #container.width-320 #sizer {
#container.width-600 #sizer { width: 600px; } width: 320px;
#container.width-640 #sizer, #container #sizer { }
.mn-container.mn-width-360 .mn-sizer, #container.width-360 #sizer {
width: 360px;
}
.mn-container.mn-width-480 .mn-sizer, #container.width-480 #sizer {
width: 480px;
}
.mn-container.mn-width-600 .mn-sizer, #container.width-600 #sizer {
width: 600px;
}
.mn-container.mn-width-640 .mn-sizer, #container.width-640 #sizer,
.mn-container .mn-sizer, #container #sizer {
width: 640px; /* default */ width: 640px; /* default */
} }
#container.width-800 #sizer { width: 800px; } .mn-container.mn-width-800 .mn-sizer, #container.width-800 #sizer {
width: 800px;
}
#container.aspect-1-1 #expander { padding-bottom: 100%; } .mn-container.mn-aspect-1-1 .mn-expander, #container.aspect-1-1 #expander {
#container.aspect-4-3 #expander, #container:not(.fullsize):not([class*='aspect-']) #expander { padding-bottom: 100%;
}
.mn-container.mn-aspect-4-3 .mn-expander, #container.aspect-4-3 #expander,
.mn-container:not(.mn-fullsize):not([class*='mn-aspect-']) .mn-expander,
#container:not(.fullsize):not([class*='aspect-']) #expander {
padding-bottom: 75%; /* default */ padding-bottom: 75%; /* default */
} }
#container.aspect-3-4 #expander { padding-bottom: 133.3333%; } .mn-container.mn-aspect-3-4 .mn-expander, #container.aspect-3-4 #expander {
#container.aspect-3-2 #expander { padding-bottom: 66.6667%; } padding-bottom: 133.3333%;
#container.aspect-2-3 #expander { padding-bottom: 150%; } }
#container.aspect-16-9 #expander { padding-bottom: 56.25% } .mn-container.mn-aspect-3-2 .mn-expander, #container.aspect-3-2 #expander {
#container.aspect-9-16 #expander { padding-bottom: 177.7778% } padding-bottom: 66.6667%;
#container.aspect-2-1 #expander { padding-bottom: 50%; } }
#container.aspect-1-2 #expander { padding-bottom: 200%; } .mn-container.mn-aspect-2-3 .mn-expander, #container.aspect-2-3 #expander {
padding-bottom: 150%;
}
.mn-container.mn-aspect-16-9 .mn-expander, #container.aspect-16-9 #expander {
padding-bottom: 56.25%
}
.mn-container.mn-aspect-9-16 .mn-expander, #container.aspect-9-16 #expander {
padding-bottom: 177.7778%
}
.mn-container.mn-aspect-2-1 .mn-expander, #container.aspect-2-1 #expander {
padding-bottom: 50%;
}
.mn-container.mn-aspect-1-2 .mn-expander, #container.aspect-1-2 #expander {
padding-bottom: 200%;
}
#canvas, pre#log { .mn-canvas, #canvas, pre.mn-log, pre#log {
max-width: 100%; max-width: 100%;
width: 100%; width: 100%;
z-index: 10; z-index: 10;
border-radius: 0.2rem; /*var(--border-radius)*/ border-radius: 0.2rem; /*var(--border-radius)*/
} }
#canvas:focus { outline-color: #5b9dd9; } /*var(--header-link-current-color)*/ .mn-canvas:focus, #canvas:focus {
#canvas { outline-color: #5b9dd9; /*var(--header-link-current-color)*/
}
.mn-canvas, #canvas {
height: 100%; height: 100%;
margin-bottom: -0.25rem; /* otherwise there's scrollbar w/ fullsize (why?) */ margin-bottom: -0.25rem; /* otherwise there's scrollbar w/ fullsize (why?) */
} }
#status, #status-description { .mn-status, #status, .mn-status-description, #status-description {
position: absolute; position: absolute;
text-align: center; text-align: center;
width: 100%; width: 100%;
z-index: 9; z-index: 9;
} }
#status { .mn-status, #status {
top: 10%; top: 10%;
font-size: 1.5rem; font-size: 1.5rem;
font-weight: 600; font-weight: 600;
} }
#status-description { .mn-status-description, #status-description {
top: 22.5%; top: 22.5%;
padding-left: 2rem; padding-left: 2rem;
padding-right: 2rem; padding-right: 2rem;
} }
#canvas.hidden { .mn-canvas.mn-hidden, #canvas.hidden {
display: none; display: none;
} }
pre#log { pre.mn-log, pre#log {
/* Make it fill at least the space given to it but let it expand beyond /* Make it fill at least the space given to it but let it expand beyond
(scrollbars in that tiny area are useless) */ (scrollbars in that tiny area are useless) */
min-height: 100%; min-height: 100%;
@ -158,7 +199,7 @@ h1 {
font-size: 1.75rem; font-size: 1.75rem;
font-weight: 600; font-weight: 600;
} }
#sizer p { .mn-sizer p, #sizer p {
text-align: center; text-align: center;
} }
code { code {

Loading…
Cancel
Save