Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

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!

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

4 Answers 4

up vote 7 down vote accepted

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

share|improve this answer
    
I just realized that I was overzealous in my justification. The first two paragraphs don't need extra spaces on the last line. –  Quincunx May 5 at 1:36
1  
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. –  Quincunx May 5 at 1:38
2  
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.... –  Quincunx May 5 at 2:42
1  
Is it supposed to work on firefox? –  Pierre Arlaud May 5 at 13:14
1  
Any chance you can get it to work in firefox? –  rooby May 6 at 12:01

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

share|improve this answer
1  
Doesn't this break the rule "however, you may remove the extra spaces (not newlines)" @Quincunx? –  Doorknob May 4 at 23:09
2  
@PaulDraper works for me (in Chrome) –  Martin Büttner May 5 at 0:47
1  
@m.buettner, weird. Chrome 34 on Ubuntu 12.04. Perhaps I'll file a Chrome bug because of this... –  Paul Draper May 5 at 0:54
6  
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) –  IQAndreas May 5 at 4:34
1  
-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. –  Bakuriu May 5 at 15:57

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%;                                                                   
}                                                                               
share|improve this answer
1  
Any chance you can get it to work in firefox? –  rooby May 6 at 12:01
    
I would presume a s/-webkit/-moz/ would do (and shave off a few more characters!) but I'll look. –  Ivan Vučica May 6 at 19:03
    
Done. (And I'm not even a particularly big fan of Star Wars...) –  Ivan Vučica May 6 at 19:41

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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