If you're a web developer (or want to be), then you're probably a geek and you like Star Wars. Well, how would you like to have the Star Wars opening crawl as a background for your next website? 😁
The answer, of course, is YAAAAAS! Read on....
I tried many iterations of this (because I really really wanted it). First I tried using a stock video of traveling through space, but the file size was too large and Google Lighthouse complained. I tried compressing to webm
format but that only works on some devices (not iOS) and looks terrible and pixelated.
After hours of playing around, I decided to use the HTML5 canvas element and JavaScript to render the stars and CSS keyframes to render the 3D crawling text. As for the font, I downloaded a mock-Star Wars font called "Deathstar". You can find those here.
Check out this working example.
And now for the code:
// stars.js
// Get canvas element by its ID
var field = document.getElementById("field");
// Make sure field canvas exists
var f = (typeof field.getContext === 'function') ? field.getContext("2d") : null;
// Config
var stars = {};
var starIndex = 0;
var numStars = 0;
var acceleration = 1;
var starsToDraw = (field.width * field.height) / 200;
function Star() {
this.X = field.width / 2;
this.Y = field.height / 2;
this.SX = Math.random() * 10 - 5;
this.SY = Math.random() * 10 - 5;
var start = 0;
if (field.width > field.height)
start = field.width;
else
start = field.height;
this.X += this.SX * start / 10;
this.Y += this.SY * start / 10;
this.W = 1;
this.H = 1;
this.age = 0;
this.dies = 500;
starIndex++;
stars[starIndex] = this;
this.ID = starIndex;
this.C = "#ffffff";
}
Star.prototype.Draw = function () {
if (!f) {
console.log('Could not load canvas element');
return;
}
this.X += this.SX;
this.Y += this.SY
this.SX += this.SX / (50 / acceleration);
this.SY += this.SY / (50 / acceleration);
this.age++;
if (this.age == Math.floor(50 / acceleration) | this.age == Math.floor(150 / acceleration) | this.age == Math.floor(300 / acceleration)) {
this.W++;
this.H++;
}
if (this.X + this.W < 0 | this.X > field.width |
this.Y + this.H < 0 | this.Y > field.height) {
delete stars[this.ID];
numStars--;
}
f.fillStyle = this.C;
f.fillRect(this.X, this.Y, this.W, this.H);
}
field.width = window.innerWidth;
field.height = window.innerHeight;
function draw() {
if (!f) {
console.log('Could not load canvas element');
return;
}
if (field.width != window.innerWidth)
field.width = window.innerWidth;
if (field.height != window.innerHeight)
field.height = window.innerHeight;
// The alpha value can be adjusted to create a stream effect
f.fillStyle = "rgba(0, 0, 0, 0.6)";
f.fillRect(0, 0, field.width, field.height);
for (var i = numStars; i < starsToDraw; i++) {
new Star();
numStars++;
}
for (var star in stars) {
stars[star].Draw();
}
}
// Modify interval to adjust speed
if (f) setInterval(draw, 40);
And the CSS:
/* global.css */
body {
margin: 0;
padding: 0;
background-color: black;
}
main {
width: 100vw;
height: 100vh;
}
#field {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: -3;
}
#crawl {
position: fixed;
top: 0;
bottom: 0;
z-index: -2;
font-family: Deathstar, Verdana, Geneva, Tahoma, sans-serif;
text-align: center;
color: white;
font-size: 4rem;
perspective: 200px;
}
#crawl p {
transform: rotateX(20deg);
animation: starwars 30s ease-in;
animation-iteration-count: infinite;
margin: 0 auto;
}
#crawl p span {
font-size: 150%;
}
#overlay {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: -1;
background-color: rgba(0, 0, 0, 0.4);
}
@keyframes starwars {
0% {
transform: rotateX(20deg) translateY(750px);
}
100% {
transform: rotateX(20deg) translateY(-1500px);
}
}
@keyframes starwars1200 {
0% {
transform: rotateX(20deg) translateY(565px);
}
100% {
transform: rotateX(20deg) translateY(-1500px);
}
}
@media only screen and (max-width: 1200px) {
#crawl {
font-size: 1rem;
}
#crawl p {
animation: starwars1200 30s ease-in;
}
}
@font-face {
font-family: 'Deathstar';
font-style: normal;
font-weight: 100;
font-display: swap;
src: url('https://cdn.designly.biz/fonts/deathstar/death_star-webfont.eot');
src: local(''),
url('https://cdn.designly.biz/fonts/deathstar/death_star-webfont.eot?#iefix') format('embedded-opentype'),
url('https://cdn.designly.biz/fonts/deathstar/death_star-webfont.woff2') format('woff2'),
url('https://cdn.designly.biz/fonts/deathstar/death_star-webfont.woff') format('woff'),
url('https://cdn.designly.biz/fonts/deathstar/deathstar.otf') format('opentype'),
url('https://cdn.designly.biz/fonts/deathstar/death_star-webfont.svg') format('svg');
}
The CSS could definitely use some fine tuning, including additional breakpoints. The downside to this code is that you have to adjust the CSS if you change the length of the text. But if your text is static then this should work nicely.
And last but not least, the HTML:
<html lang="en">
<head>
<meta name="robots" content="index, follow" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=yes" />
<link rel="stylesheet" href="css/global.css" />
</head>
<body>
<main>
<canvas id="field"></canvas>
<div id="crawl">
<p>
<span>Episode IV</span>
<br /><br />
A New Hope
<br /><br />
It is a period of civil war.
Rebel spaceships, striking
from a hidden base, have won
their first victory against
the evil Galactic Empire.
<br /><br />
During the battle, Rebel
spies managed to steal secret
plans to the Empire's
ultimate weapon, the DEATH
STAR, an armored space
station with enough power to
destroy an entire planet.
<br /> <br />
Pursued by the Empire's
sinister agents, Princess
Leia races home aboard her
starship, custodian of the
stolen plans that can save
her people and restore
freedom to the galaxy....
</p>
</div>
<div id="overlay"></div>
</main>
</body>
<script src="js/stars.js"></script>
</html>
I hope you found this article helpful. You're welcome to use my copy of the Deathstar font from my CDN for non-commercial purposes only. Otherwise, please download and host your own. If you're not sure how to do that, check out this article.
You can find the code for this example on GitHub. Feel free to download or clone it.
For more great information about web dev and systems administration, please read the Designly Blog. 🙏
Top comments (0)