12.11 - Overlays¶
WebGL 3D graphics are always rendered into a HTML canvas
element. The canvas is
always a rectangle. That said, it is possible to render arbitrary areas
of a canvas to make a rendering appear non-rectangular. And
it is possible to overlay the 2D HTML elements of a web page and a WebGL 3D rendering
in interesting ways. This lesson explains how to do the following:
- Render a 3D scene behind (or in the background) of a web page.
- Render a 3D scene in front of a web page.
- Render multiple canvas elements on top of each other.
- Render a HTML element (and its child elements) in full screen mode.
Overlays Using CSS Properties¶
HTML elements have a “stack ordering” based on their CSS (Cascading Style Sheets)
z-index
property. Elements are rendered to a web page based on their
z-index
ordering – from smallest to largest. This is identical to the “painter’s
algorithm” described in lesson 12.2. Elements rendered later in the process of creating
a web page over-write (or blend) any previously rendered elements. Using the z-index
property,
3D graphics can be rendered behind or in-front-of other HTML elements.
The z-index
property only affects elements that are rendered on top of each
other. Therefore, the z-index
ordering only works on elements
whose position
property is absolute
, relative
, or fixed
, which are
defined as follows:
absolute
: The element is positioned relative to its first positioned (not static) ancestor element.relative
: The element is positioned relative to its normal position.fixed
: The element is positioned relative to the browser window.
The z-index
property has no impact on an HTML element if its position
property is
static
, initial
, or inherit
, which are defined as follows,
static
: Elements render in order, as they appear in the document flow. (Default)initial
: Use its default value.inherit
: Inherits this property from its parent element.
The examples in this lesson are created by setting appropriate position
, width
,
height
, top
, bottom
, left
and right
properties to make elements overlap and then setting the
rendering order using the z-index
property. The alpha component
of the background color is also used to implement transparency.
Positioning HTML elements can be very tricky. The examples in this lesson use this strategy:
- Create a
div
“container” to hold the overlapping elements. Set itsposition
property torelative
and itsheight
property to the the total height of the overlapping HTML elements. This allows elements after this “container” to follow the normal flow of the web page (which is left-to-right, top-to-bottom). - Create the overlapping elements and make their
position
property beabsolute
orrelative
. Set each element’s size (width
andheight
) and its relative location using two of the properties:top
,bottom
,left
andright
. (For example, to position an element in the upper-right corner of an area, use thetop
andright
properties.)
To investigate the details of the examples in this lesson, right-click over a HTML element and select “Inspect”. The browser’s “development tools” will display the HTML source code and the CSS settings for the element.
3D Graphics Behind Text¶
To create 3D graphics behind HTML elements, position a canvas and the HTML
elements in the same relative position on a web page. In addition, assign the canvas
a z-index
value that is less than the HTML element’s z-index
value.
Here are a set of example CSS definitions that define the example below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #graphics_under { /* The "container" <div>. */
position: relative;
height: 400px;
}
#W1_text { /* The "front" element */
position: absolute;
top: 0px;
left: 0px;
width: 400px;
height: 400px;
z-index: 1;
}
#W1_canvas { /* The "back" element. */
position: absolute;
top: 0px;
left: 0px;
width: 400px;
height: 400px;
z-index: 0;
}
|
The HTML code looks like this, where the inner <div>
and the canvas
are
taking up the same area of the web page:
1 2 3 4 5 6 7 8 9 | <div id="graphics_under">
<div id="W1_text">
The following description is from ...
</div>
<canvas id="W1_canvas">
Please use a browser that supports "canvas"
</canvas>
</div>
|
Example: Graphics Under Text¶
The following description is from https://en.wikipedia.org/wiki/Stanford_bunny
The Stanford bunny is a computer graphics 3D test model developed by Greg Turk and Marc Levoy in 1994 at Stanford University. The model consists of data describing 69,451 triangles determined by 3D scanning a ceramic figurine of a rabbit.[1] This figurine and others were scanned to test methods of range scanning physical objects.[2]
The data can be used to test various graphics algorithms, including polygonal simplification, compression, and surface smoothing. There are a few complications with this dataset that can occur in any 3D scan data. The model is manifold connected and has holes in the data, some due to scanning limits and some due to the object being hollow.[3] ...
The model was originally available in .ply (polygons) file format with 4 different resolutions, 69,451 polygons being the highest.
Alpha value of the canvas' background color: [0.85, 0.60, 0.60, 0.00]
0.0 1.0
Notes about 3D Graphics Under Text:¶
- In all previous WebGL programs in this textbook, event callbacks to
convert mouse drags into model rotations were attached to a canvas element.
Since the canvas is totally covered by a
div
, any events associated with thecanvas
are never activated. The mouse events that manipulate the canvas graphics must be bound to the top HTML element of the overlay. Try rotating the bunny using a mouse click and drag. The mouse events are bound to the<div>
element, not thecanvas
element. - The alpha value of the canvas’ background color can be used to
blend the canvas with the web page’s background. If you set the
alpha value of the “clear color” to 1.0, the area covered by the canvas will
have the color of the canvas. If you set the
alpha value of the “clear color” to 0.0, the area covered by the canvas will
have the color of the web page.
3D Graphics in Front of Text¶
To render 3D graphics over the top of HTML elements, change the
z-index
property of the canvas to have the
largest z-index
value of the overlapping elements. This
causes the canvas to be rendered last, thus overwriting (or blending with)
any previous rendering at that location on the web page. Use an alpha value of 0.0 for the
canvas’ background color to allow the “back elements” to be visible.
Example:¶
The following description is from https://en.wikipedia.org/wiki/Stanford_bunny
The Stanford bunny is a computer graphics 3D test model developed by Greg Turk and Marc Levoy in 1994 at Stanford University. The model consists of data describing 69,451 triangles determined by 3D scanning a ceramic figurine of a rabbit.[1] This figurine and others were scanned to test methods of range scanning physical objects.[2]
The data can be used to test various graphics algorithms, including polygonal simplification, compression, and surface smoothing. There are a few complications with this dataset that can occur in any 3D scan data. The model is manifold connected and has holes in the data, some due to scanning limits and some due to the object being hollow.[3] ...
The model was originally available in .ply (polygons) file format with 4 different resolutions, 69,451 polygons being the highest.
Alpha value of the canvas' background color: [0.85, 0.60, 0.60, 0.00]
0.0 1.0
Overlapping Canvas Elements¶
A canvas element can be overlaid on top of other canvas elements. For example, the layout of a game might desire a small “world map” in the corner of a larger “game play” window. The CSS definitions for overlapping canvas elements might look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #overlapping_canvas { /* The "container" div. */
position: relative;
height: 400px;
width: 400px;
}
#large_canvas { /* The "main" canvas */
position: absolute;
top: 0px;
left: 0px;
width: 400px;
height: 400px;
z-index: 0;
background: lightgray;
}
#small_canvas { /* The upper-right corner canvas. */
position: absolute;
top: 10px;
right: 10px;
width: 100px;
height: 100px;
z-index: 1;
background: lightgreen;
}
|
Example:¶
Full Screen Rendering¶
HTML elements can be rendered in full screen mode, but as of early 2018,
the interface to the functionality has not been standardized.
Each browser uses different naming conventions. To make full screen mode
function correctly for all browsers, the code must include all
possible naming conventions – which makes the code seem more complex than
it really is. (As of early 2018, jQuery
has not standardized
full screen mode functionality either.)
The proposed standard for full screen mode can be found at Fullscreen API.
Any HTML element can be requested to enter full screen mode. For 3D graphics,
a canvas
element would typically request full screen mode.
Fullscreen requests must be called from within an event handler. If they are called anywhere else they will be denied. This means that a user must initiate fullscreen mode by some user action. A user can always exit from fullscreen mode by hitting the escape (ESC) key.
When full screen mode is initiated or exited, the size of the canvas element
must be updated accordingly. A callback function must be registered for any
fullscreenchange
events to make the needed size changes. Note
that in the following code example only one of the on
function calls
will succeed based on which browser the code is executing on.
$( '#' + canvas_id ).on( 'fullscreenchange', self.onFullScreenChange )
.on( 'webkitfullscreenchange', self.onFullScreenChange )
.on( 'mozfullscreenchange', self.onFullScreenChange )
.on( 'MSFullscreenChange', self.onFullScreenChange );
The event handler must recognize the current screen mode and then take appropriate actions. Here is an example event handler:
/** ---------------------------------------------------------------------
* Process "fullscreenchange" events.
* @param event {x.Event} event that triggered a "fullscreenchange" event.
*/
self.onFullScreenChange = function (event) {
if (document.fullscreenElement ||
document.webkitIsFullScreen ||
document.mozFullScreen ||
document.msFullscreenElement) {
// The document is in full screen mode.
self.updateCanvasSize( screen.width, screen.height );
} else {
// The document is NOT in full screen mode.
self.updateCanvasSize(400, 400);
}
scene.render();
};
To enter full screen mode a user event must initiate the action. Here is a typical function that starts full screen mode:
/** ---------------------------------------------------------------------
* Initiate full screen mode.
* @param id {string} The ID of the element that will be made full screen.
*/
self.startFullScreenMode = function (id) {
// Get the element that will take up the entire screen
let element = document.getElementById(id);
// Make sure the element is allowed to go full screen.
if (!element.fullscreenElement &&
!element.mozFullScreenElement &&
!element.webkitFullscreenElement &&
!element.msFullscreenElement) {
// Enter full screen mode
if (element.requestFullscreen) {
element.requestFullscreen();
} else if (element.msRequestFullscreen) {
element.msRequestFullscreen();
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen();
} else if (element.webkitRequestFullscreen) {
element.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
}
} else {
window.console.log("The element " + id + " can't go into full screen mode.");
}
};
The startFullScreenMode
function will become much simpler and cleaner
when all of the browsers standardize on a single naming convention (or jQuery
adds support for
full screen mode.)
Canvas Element Size¶
A canvas element has two different sizes:
- a HTML size, defined by an element’s
width
andheight
properties, and - a CSS (cascading style sheets) size, defined by an element’s
width
andheight
style properties.
Here is an example canvas that has two different sizes:
<canvas width="100" height="100" style="width:200px; height:200px;"> </canvas>
If the CSS properties, width
and height
, are not specified,
the HTML properties determine the element’s size. However, the CSS properties
always override the HTML properties. Therefore, the example canvas will have a size of
200x200 pixels on the screen. WebGL always creates its draw buffer using
a canvas’ HTML properties. In the example above, the canvas on the screen will
be 200x200 pixels, but the WebGL draw buffer will be 100x100 pixels. When the
draw buffer is copied to the screen it will be stretched to fill the canvas.
The stretching causes the image to be blurry because each pixel in the draw buffer will
be used to color multiple pixels in the canvas.
To change the size of a
canvas the CSS properties should be changed and then copied into
the canvas’ HTML properties. The CSS properties are called clientWidth
and
clientHeight
. The following function updates the size of
a canvas element whose ID is W4_canvas
:
/** ---------------------------------------------------------------------
* Reset the size of a canvas after a full screen mode event.
* @param new_width {Number} The new width for the canvas element.
* @param new_height {Number} The new height for the canvas element.
*/
self.updateCanvasSize = function (new_width, new_height) {
// Change the CSS size of the canvas.
$('#W4_canvas').css('width', new_width).css('height', new_height);
// Re-size the WebGL draw buffer for the canvas.
let canvas = document.getElementById('W4_canvas');
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
};
A Fullscreen Example¶
Experiment with Full Screen Mode
Experiments concerning full screen mode:
- Don’t resize the canvas when a
fullscreenchange
event occurs. (Comment out lines 145 and 148 ofbunny_events.js
.) Notice that the canvas has not changed size and full screen mode simply blacked-out the surrounding screen area. - Initially the
gl
context sets the rendering viewport to the size of the canvas (and the draw buffer.) Changing the size of the canvas does not update the viewport. Therefore, when the size of the canvas changes, the viewport must be updated appropriately. (See line 85 inbunny_scene.js
.) Try commenting out line 85. (Close the browser’s development environment if you have it open while you are experimenting.) - If the aspect ratio of the canvas changes, the projection transformation
must be updated. (See lines 82-83 in
bunny_scene.js
.) Move the lines that create of the projection matrix to the constructor ofBunnyScene
so that it only happens once. Notice that the rendering in full screen mode is stretched either horizontally or vertically based on the aspect ratio of the screen. - If the dimensions of the canvas are not modified to match the size of the
screen when full screen mode is entered, the rendering will be blurry.
To see this, comment out lines 134-135 in
bunny_events.js
. Do you understand why the rendering is blurry? Also notice that this makes the rendering stretched either horizontally or vertically. This is because the draw buffer is initially square (300x300), while the rendering in full screen mode is being mapped to a rectangular viewport.
Glossary¶
- overlay
- The rendering of more than one element in the same location on a web page.
- stack ordering
- The back-to-front ordering of a set of overlaid HTML elements.
- z-index
- A value that specifies the position of an element in a “stack ordering”. The ordering is from smallest to largest. The element with the largest z-index is rendered last.
- full screen mode
- Render an HTML element (and all of its children) to a window that covers the entire screen. All window borders and title bars disappear. You can exit full screen mode by hitting the ESC key.
Self Assessment¶
position
andz-index
-
Correct.
position
allows them to be in the same place, whilez-index
determines which one is in front. position
andwidth/height
-
Incorrect. The
position
mode is critical, but width and height are not critical because they only determine the amount of overlap. location
andsize
- Incorrect. Neither of these are CSS properties.
position
andtop
-
Incorrect. The
position
mode is critical, buttop
is not critical because it only determines the amount of overlap.
Q-439: What are the two critical CSS properties that allow HTML elements to overlap each other on a web page?
element1
-
Correct. Because it has a greater
z-index
. element2
-
Incorrect.
element2
will be belowelement1
because it has a smallerz-index
.
Q-440: Given the following CSS definitions, which HTML element will be rendered in front of the other one?
#element1 {
position: absolute;
z-index: 5;
}
#element2 {
position: absolute;
z-index: 3;
}
- HTML properties: control the size of the WebGL draw buffers.
CSS properties: control the size of the canvas on the web page. - Correct.
- HTML properties: control the size of the canvas on the web page.
CSS properties: control the size of the WebGL draw buffers. - Incorrect. It’s backwards!
- HTML properties: are totally ignored if the CSS properties are defined.
CSS properties: control the size of the canvas on the web page. - Incorrect.
- HTML properties: control the size of the canvas on the web page.
CSS properties: are totally ignored if the HTML properties are defined. - Incorrect.
Q-441: A HTML canvas element has HTML properties of width
and height
. It can also have
CSS properties called width
and height
. This can be very confusing
because the properties control different things! Which
of the following correctly describes how these properties differ.
- Different browsers use different function calls, which will hopefully be standardized in the near future.
- Correct.
- The code is complex because implementing “fullscreen mode” is a complex task that requires complex logic. In the future the task will become simpler due to better technology.
- Incorrect.
- The code will become simpler because somebody will discover a simpler way to implement “fullscreen mode”.
- Incorrect.
- Programming code always becomes simpler over time because of better technology.
- Incorrect.
Q-442: Why is the “fullscreen mode” code more complex than it will need to be in the future?