the firmament

1 motivation

The firmament is the scenery whose purpose is to help establish a sense of space, in particular with respect to the entryway.

Scheme_of_things-woodcut-1475@fullscreen.jpg
Figure 1: 1475 woodcut of the firmament

Yes, Shakespeare tends to use the term “firmament” only to mean the “place where the stars live.” I’m using the “erroneous” sense that includes the entire expanse from the ground to the heavens.

firmament (n.)
mid-13c., from Old French firmament or directly from Latin firmamentum “firmament,” literally “a support, a strengthening,” from firmus “strong, steadfast, enduring” (see firm (adj.)). Used in Late Latin in the Vulgate to translate Greek stereoma “firm or solid structure,” which translated Hebrew raqia, a word used of both the vault of the sky and the floor of the earth in the Old Testament, probably literally “expanse,” from raqa “to spread out,” but in Syriac meaning “to make firm or solid,” hence the erroneous translation.1

One day, willshake and other dynamic media will actually integrate with the space, and the space you’re actually in will be the canvas. At that point, artificial measures such as this won’t be necessary—or at least will have a different motivation Until then, we’ll do what we can to give people the right idea.

The ground and sky work together to create a sense of being somewhere.

body <append>
	<div id="the-firmament">
		<div id="the-sky" />
		<<the ground>>
	</div>
</append>

In practice, the firmament is more or less fixed, as you might expect.

@import order-of-main-layers
@import docking
@import colors
#the-firmament
	hug-parent(position: fixed)
	overflow hidden     // Prevent reflows when transform transitioning children (Gecko).
	z-index $firmamentLayer        // The ground layer is behind space/time.
	transform translateZ(0)     // HACK for Chrome: Without this, Chrome repaints on every scroll.
	background $skyColor

2 the ground

2.1 the Procession of Shakespeare’s Characters

The sense of a “ground” is created using the painting Procession of Shakespeare’s Characters, which shows a number of notable personalities from the plays milling about in a kind of abstract space.

Procession_of_Characters@fullscreen.jpg
Figure 2: The ground: the “Procession of Characters” image

This painting has several fortuitous properties for this purpose, although in theory there are other candidates that might also work if a large enough version were in the public domain. Sylvia Morris presents a good summary of such group portraits2. I also experimented with The Plays of William Shakespeare by John Gilbert, but I prefer the Procession because it is more elliptical—I mean, you can do more with less—and unlike the Gilbert, it creates a sense of open space.

2.2 building the set

Now to set the scene.

<div id="the-ground">
	<div id="the-ground-image" />
</div>

This is already not the structure that you might expect. Why is an <img/> element (or even a <picture/> element) not used for this image? Because the ground image—and the firmament generally—belong to the spatial semantics of the site, not its document semantics. Using stylesheets to present these effects means that they will be completely invisible to viewers that don’t support stylesheets (as they should be).

Being agnostic about what may end up on the ground, I’ll give it the full viewport.

@import docking
#the-ground
	hug-parent()

But what is on the ground? For now, just the Procession image.

#the-ground-image
	background url("/static/images/Procession_of_Characters@fullscreen.jpg") no-repeat
	background-size 100%
	<<ground image rules>>

This would be a place to serve a smaller ground image for smaller screens.

The ground is bottom-aligned, naturally. The docking container is the firmament itself—which is fixed in place—so the ground will not move when the user scrolls.

position absolute
bottom 0

But how should it be positioned horizontally? And how wide should it be? The image itself is short and wide, with an aspect ratio of 4.5:1.

width = 6816
height = 1509

Certainly the image should never be narrower than the viewport. It ends abruptly on both sides, and seeing those edges would destroy the illusion. But if it were always flush to both sides (so that you can see the whole thing), then it would end up very short on narrow screens. In such cases it would be preferable to let the image be wider than the viewport, cutting off the sides, rather than letting it shrink to something ridiculous.

In fact, there’s an advantage to letting the image overflow outside of the viewport, even on “normal” sized displays. If there is more image to work with on either side, you can extend the sense of the space by “panning” the ground to the left and right. So I want to guarantee that the image is not visible all at once. Since a very large version of this image is available, this can be done on a wide range of screens.

The prospect of creating a kind of “stage left” and “stage right” suggests that image should be centered horizontally.

@import centering
horizontally-center()

All that aside, the image works best when it’s about half of the height of the screen. But I can’t specify a height constraint directly, for reasons that will be apparent in a moment. That’s no problem, since I know the aspect ratio of the image, and I can express the width in terms of the viewport height.

width (width / height) * 50vh

All of this means that the size of the image will often change if the shape of the viewport changes. When that happens, the adjustment should not be abrupt.

Finally, an implementation detail. Since the ground-image element is empty, it doesn’t have a “natural” height. It has to be assigned a height somehow. Luckily, it’s easy in CSS to make a variable-width maintain a specific aspect ratio. Maybe not in the way that you’d expect, but easy nonetheless.3

&:before
	content ''
	display block
	padding-top (height / width) * 100%

With that, the height of the box will always match the correct height of the image, no matter what its width is set to.

You might be thinking that all that could have been achieved more easily with just CSS background-size and background-position rules. But it will be useful to have a container that is coextensive with the actual image (as opposed to just its visible part). This is also gives a much better prospect for swift panning left and right, since transitioning elements can be hardware accelerated, which I’m assuming that background styles cannot.

2.3 blending with the sky

The ground image appears to sit against a continuous “sky.” A little horizontal strip helps create that effect by blending the top of the image with the background. Using an :after so it is naturally on top.

@import docking
@import colors
&:after
	dock-top()
	content ''
	height 9%
	background-image linear-gradient(rgba($skyColor, 1), rgba($skyColor, 0))

3 the sky

The very rearmost layer, the “sky” is just a gradient that resides behind the Procession image and sets the background color for the space.

// Sky colors are defined in lib/colors.
@import colors
#the-sky
	hug-parent()                            // the parent (the firmament) is already fixed position
	// CHEATING: hardcoding the height of the image
	height calc(100% - 332px)
	background-image linear-gradient($nightSkyColor, $skyColor 66%)

This darkens the top of the sky, in a way that should still blend with the ground image. It adds contrast to the beacon and adds a bit more depth to the space.

4 issues

4.1 BUG ugly gap when browser chrome goes away

Firefox Android, in particular, does this annoying thing where it changes the height when you scroll down. Yes, this gives you full screen, but it wreaks all kinds of havoc on height-dependent things.

And in this case, you get a white gap where there’s suddenly new viewport space.

So shouldn’t the body just have a background to match the sky color?

4.2 TODO serve a smaller ground image for smaller screens

Footnotes:

1

firmament”, Online Etymology Dictionary. ©2001-2015 Douglas Harper

2

See “Picturing Shakespeare’s Characters” from The Shakespeare Blog by Sylvia Morris (January 2014).

3

The trick is that percentages used for vertical rules (such as padding-top and padding-bottom) are based on the width of the element, not (as you might expect) the height. Note that this has to be done with a pseudo element so that the percentage is based on the ground’s width, not its container’s (the viewport).

about willshake

Project “willshake” is an ongoing effort to bring the beauty and pleasure of Shakespeare to new media.

Please report problems on the issue tracker. For anything else, public@gavinpc.com

Willshake is an experiment in literate programming—not because it’s about literature, but because the program is written for a human audience.

Following is a visualization of the system. Each circle represents a document that is responsible for some part of the system. You can open the documents by touching the circles.

Starting with the project philosophy as a foundation, the layers are built up (or down, as it were): the programming system, the platform, the framework, the features, and so on. Everything that you see in the site is put there by these documents—even this message.

Again, this is an experiment. The documents contain a lot of “thinking out loud” and a lot of old thinking. The goal is not to make it perfect, but to maintain a reflective process that supports its own evolution.

graph of the program

about

Shakespeare

An edition of the plays and poems of Shakespeare.

the works