23
\$\begingroup\$

In honor of Star Wars day, write a program to display the following text, scrolling like the Star Wars opening crawl:

It  is  a  period  of  civil war.  Rebel
spaceships,   striking  from   a  hidden
base,  have   won  their  first  victory
against the evil Galactic Empire.

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.

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...

You may output an animated GIF or have your program display it. The output must show the following:

  • The text must start from the bottom of the image/display
  • It must scroll upwards until it reaches the top. It must take at least 30 seconds for a piece of text to reach the top. The animation must continue until all the text reaches the top.
  • In this distance, the text must get smaller until it is less than 1/3 the size (length and font)
  • The text must be slanted to follow this angle.
  • The text must be left and right justified. The text given is already justified for monospaced fonts, however, you may remove the extra spaces (not newlines) and justify it yourself.
  • The text must be yellow
  • The background must be black

This video shows the opening crawl.

Good luck, and May the fourth be with you!

\$\endgroup\$
8
  • 5
    \$\begingroup\$ What about "May the forth be with you"? \$\endgroup\$
    – TheDoctor
    Commented May 4, 2014 at 22:38
  • \$\begingroup\$ @TheDoctor That's what it was, but I fixed the typo. You seriously think that I should go for the double pun? \$\endgroup\$
    – Justin
    Commented May 4, 2014 at 22:40
  • 3
    \$\begingroup\$ Forth would be difficult to do this in. \$\endgroup\$
    – TheDoctor
    Commented May 4, 2014 at 22:42
  • 5
    \$\begingroup\$ @TheDoctor "To do in Forth, difficult this would be" - Yoda'd that for you. \$\endgroup\$ Commented May 5, 2014 at 13:44
  • \$\begingroup\$ One fun thing about this question: before posting, the system warned me that this might be closed as "too subjective". \$\endgroup\$
    – Justin
    Commented May 5, 2014 at 18:20

4 Answers 4

36
\$\begingroup\$

HTML/CSS, 1047

I could golf this a lot more by deleting the -webkit prefixes etc., but this will do for the time being:

<html><head><style>body{font-family:sans-serif;background:#000;margin:0
auto;height:400px;width:800px;text-align:justify;position:relative;perspective:
150px;-webkit-perspective:150px;}div{font-size:63px;line-height:63px;color:#ee6;
position:absolute;-webkit-transform:rotateX(70deg);transform:rotateX(70deg);}p{
position:relative;-webkit-animation:s 90s linear forwards;animation:s 90s linear
forwards;}@-webkit-keyframes s{from{top:800px;}to{top:-2000px;}}@keyframes
s{from{top:800px;}to{top:-2000px;}}</style><body><div><p>It is a period of civil
war. Rebel spaceships, striking from a hidden base, have won their first victory
against the evil Galactic Empire.</p><p>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.</p><p>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>

Live demo

\$\endgroup\$
13
  • 1
    \$\begingroup\$ Doesn't this break the rule "however, you may remove the extra spaces (not newlines)" @Quincunx? \$\endgroup\$
    – Doorknob
    Commented May 4, 2014 at 23:09
  • 2
    \$\begingroup\$ @PaulDraper works for me (in Chrome) \$\endgroup\$ Commented May 5, 2014 at 0:47
  • 1
    \$\begingroup\$ @m.buettner, weird. Chrome 34 on Ubuntu 12.04. Perhaps I'll file a Chrome bug because of this... \$\endgroup\$ Commented May 5, 2014 at 0:54
  • 6
    \$\begingroup\$ Not sure why, but it doesn't work in FireFox 29.0 on Ubuntu 13.10. Not related to @PaulDraper's problem (I'm just seeing a completely black screen, with some occasional flittering and thin yellow streak in the middle of the screen) \$\endgroup\$
    – IQAndreas
    Commented May 5, 2014 at 4:34
  • 1
    \$\begingroup\$ -1 that isn't a valid HTML file. If you purposefully wanted to make this only work with a specific browser version then you should include the name and version of the browser in the language specification. \$\endgroup\$
    – Bakuriu
    Commented May 5, 2014 at 15:57
19
\$\begingroup\$

HTML+CSS+SVG 1614 1625

I wanted to be visually correct, too. SVG used for masking and animation. HTML+CSS used for transforms. I didn't check if the text gets to exactly 1/3 size.

Recommended viewing in Chrome due to -webkit- prefix. Requires CSS 3D transforms to work; you may need to open chrome://flags and pick 'Override software rendering list'.

Included in bytecount are newlines and blanks.

Update 1: Adding support for Firefox and other browsers that don't need prefixes. Added 11 bytes even after further cleanup. Cleanup was possible because browsers luckily interpret SVG using HTML-crunching parsers as opposed to XML-compilant parsers.

Live

<div id=a>                                                                      
<div id=b>                                                                      
<svg width=760 height=1000>                                                     
<g mask=url(#m)>                                                                
<g transform=translate(0,0)>                                                    
<animateTransform attributeName=transform type=translate dur=50 fill=freeze from=0,700 to=0,-450 />
<foreignObject width=760 height=800>                                            
<div style=width:740; >                                                         
<p>It is a period of civil war. Rebel                                           
spaceships, striking from a hidden                                              
base, have won their first victory                                              
against the evil Galactic Empire.</p>                                           
<p>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.</p>                                          
</div>                                                                          
<p>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>                                                    
</foreignObject>                                                                
</g>                                                                            
</g>                                                                            
<defs>                                                                          
<linearGradient id=g x1=0 y1=0% x2=0 y2=100%>                                   
<stop offset=0% />                                                              
<stop offset=25% />                                                             
<stop offset=35% stop-color=#fff />                                             
<stop offset=100% stop-color=#fff />                                            
</linearGradient>                                                               
<mask id=m>                                                                     
<rect width=100% height=100% fill=url(#g) />                                    
</mask>                                                                         
</defs>                                                                         
</svg>                                                                          
</div>                                                                          
</div>                                                                          
<style>                                                                         
body {                                                                          
margin: 0;                                                                      
width: 100%; height: 100%;                                                      
perspective: 700px;                                                             
-webkit-perspective: 700px;                                                     
background: url(http://vucica.net/s.php);                                       
}                                                                               
#a {                                                                            
position: absolute;                                                             
width: 100%;                                                                    
height: 700px;                                                                  
bottom: 0;                                                                      
transform-style: preserve-3d;                                                   
}                                                                               
#b {                                                                            
margin: auto auto auto auto;                                                    
width: 760px; height: 100%;                                                     
font-family: Courier; font-weight: bold; text-align: justify; font-size: 24pt;  
color: yellow;                                                                  
overflow: hidden;                                                               
transform: rotateX(45deg);                                                      
-webkit-transform: rotateX(45deg);                                              
}                                                                               
svg {                                                                           
position: absolute;                                                             
width: 760px;                                                                   
height: 100%;                                                                   
}                                                                               
\$\endgroup\$
3
  • 1
    \$\begingroup\$ Any chance you can get it to work in firefox? \$\endgroup\$
    – rooby
    Commented May 6, 2014 at 12:01
  • \$\begingroup\$ I would presume a s/-webkit/-moz/ would do (and shave off a few more characters!) but I'll look. \$\endgroup\$ Commented May 6, 2014 at 19:03
  • \$\begingroup\$ Done. (And I'm not even a particularly big fan of Star Wars...) \$\endgroup\$ Commented May 6, 2014 at 19:41
8
\$\begingroup\$

HTML, 762

<div><pre>It  is  a  period  of  civil war.  Rebel
spaceships,   striking  from   a  hidden
base,  have   won  their  first  victory
against   the   evil   Galactic  Empire.

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.

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...</pre></div><style>pre{transform:perspective(300px)rotateX(25deg);position:absolute;left:99px;color:yellow;animation:a 30s linear}@keyframes a{100%{font-size:0px}}body{background:black}</style>

Kind of choppy (read: extremely choppy :P).

Here's a JSFiddle (with -webkit- vendor prefixes added so it works in Chrome).

\$\endgroup\$
8
  • \$\begingroup\$ I just realized that I was overzealous in my justification. The first two paragraphs don't need extra spaces on the last line. \$\endgroup\$
    – Justin
    Commented May 5, 2014 at 1:36
  • 1
    \$\begingroup\$ Also, I don't know about this; the crawl slides to the left, not just up. I don't accept that. The choppiness: okay, but the sliding not just up: not okay. \$\endgroup\$
    – Justin
    Commented May 5, 2014 at 1:38
  • 3
    \$\begingroup\$ It is so slight to you? It is very apparent to me. Possibly, it is more visible in Chrome. For me, the leftmost edge stays at the same left-ness, even with very small text, so the rightmost moves very noticeably to the left. In that case, I'm fine with it. I wonder what it really looks like.... \$\endgroup\$
    – Justin
    Commented May 5, 2014 at 2:42
  • 1
    \$\begingroup\$ Is it supposed to work on firefox? \$\endgroup\$ Commented May 5, 2014 at 13:14
  • 1
    \$\begingroup\$ Any chance you can get it to work in firefox? \$\endgroup\$
    – rooby
    Commented May 6, 2014 at 12:01
4
\$\begingroup\$

PerlMagick, 661 program + 547 text file = 1208

Too late for the anniversary, but OP said 'animated GIF', so...

TL;DR: a link to animated GIF (5 Mb, 480*240, 1360 frames) (there's a false start each time I try this link now - it's not in the file, maybe try to download it first. And some slight flickering... maybe I'll explain it later, - not a piece of cake, the whole IM and GIF idea ;) ).

With newlines and indentation for readability:

use Image::Magick;
$i=Image::Magick->new(
    depth=>8,
    page=>'480x440+20+0',
    background=>'#000',
    fill=>'#ff0',
    font=>'UbuntuMono-R.ttf',
    pointsize=>22
);
$i->Read('text:-');
$j=$i->Clone;
$i->Extent(y=>-440);
for(1..680){
    ($i->[2*$_]=$j->Clone)->Extent(y=>$_-440);
    ($i->[2*$_-1]=$i->[2*$_]->Clone)
        ->Composite(image=>$i->[2*$_-2],compose=>'Blend',blend=>50)
}
$i->Distort(method=>'Perspective','virtual-pixel'=>'Background',
    points=>[0,0,180,180,480,0,300,180,0,420,0,420,480,420,480,420]);
$i->Extent(geometry=>'480x240+0+200');
$g=Image::Magick->new(size=>'480x150');
$g->Read('gradient:#000-#fff');
$i->Composite(image=>$g,compose=>'Multiply');
$i->Set(delay=>10,loop=>0);
$i->Animate()

It reads text from STDIN, but geometry is hard-coded, so probably any other text would not be a good idea. It could be shorter, but I added fading to the text as it gets to the top, and, moving up by single pixel resulted in a choppy animation, so I did some interpolation. It eats 2.2 Gb of RAM and takes 2-3 minutes on a 8 y.o. desktop (and probably won't work for Windows folks), so here's how to get a GIF: replace (or add to) the last line (creates 200+ Mb file):

$i->Write('out.miff')

And then run

convert -size 8x1 gradient:black-yellow palette8.png
convert +dither out.miff -remap palette8.png out+.gif
convert +dither out+.gif -layers optimize out++.gif

Trade-offs between quality (palette size etc.) and final GIF size are obvious. Calling $i->Remap from PerlMagick directly doesn't work, there's probably a bug, it takes hours long as it (I think) tries +remap first. Actually, reasonable (only slightly bigger) GIF size can be achieved without global palette but using $i->Quantize which reduces each frame local palette to required size. Oh, and without any palette optimizations i.e. saving GIF from above script 'as is' produces about 9 Mb GIF file.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.