Introduction
You know those cool graphics in the Star Wars intro? Well here's something similar. Just throw some text at it and tell it to go. It's a picture box TextCrawler
and a maid all in one! (You may have to pick up a few things yourself and she doesn't do windows... well ok. Not a maid, but still pretty cool.)
Background
I've been away from any computer that wasn't a glorified type-writer for over seven years (where there's a toilet near my lumpy bunk, the windows are crowded over with concrete or unsightly iron and my only door has a window... ok, I was in prison, sue me!) So now, after seven years of hurting, itching to code, I've finally got a laptop and the freedom to get at it.
Sorry, though. No, there were no prison riots, no high-profile breakouts or anything, only a few days before I started working as a cook in one joint, some guy got himself stabbed so badly on a Tuesday in the kitchen there that he died in hospital while I was frying eggs over-easy on a sunny Saturday morning.
But anyway, here's a prison joke:
How do you know the food is bad in prison? Look at all the guards in the kitchen!
In any case, I've been hurting to write code for all this time and I finally have a laptop and here I am. I read a book on 3D graphics that was written in the 80s and now I'm raring to go!
Using the Code
Here are the main functions of the TextCrawler
class:
public void ScrollText(string str, Font fnt, double dblAngle, Color clrText)
public List<classTextCrawl.classScrollLine>
textToTiltScrollBmpArray(string strText,
Font fnt,
Color clrForeColor,
Color clrBackGroundColor,
bool bolTransparent,
double dblAngle,
int intMaxCharPerLine)
public classScrollLine tiltImageBack(Bitmap bmpSource, double dblAngle)
The only function any one could ever need to just throw something on the screen is the ScrollText()
function because it does everything for you. ScrollText()
uses the other two functions. It parses out the text into individual lines in a way similar to a 'word wrap' function of a word processor, so that the lines end without cutting a word in two or drawing a comma at the start of a new line. Then it sends those text strings to TextToTiltScrollBmpArray()
which converts the array of string
s into an array of 'tilted' image bitmaps of each line of text.
Here's the sample call from this demonstration application:
private void btnGo_Click(object sender, EventArgs e)
{
go();
}
void go()
{
cTextCrawl.ScrollText(strText, fnt, ((double)intAngle / 180.0 * Math.PI), clrText);
}
Damn, that's neat!
It's like valet parking in an empty lot!
The only thing you need to do to set it up is to copy the source file TextCrawl.cs into the same directory as the rest of your .cs files and instantiate the class in your code as if it were a picturebox
.
classTextCrawl cTextCrawl = new classTextCrawl();
public formTextCrawlDemonstration()
{
InitializeComponent();
Controls.Add(cTextCrawl);
cTextCrawl.Dock = DockStyle.Fill;
cTextCrawl.BackgroundImage = Properties.Resources.starry_night;
cTextCrawl.BackgroundImageLayout = ImageLayout.Center;
initCmb();
resetControls();
}
It uses just one class:
public class classScrollLine
which holds the data pertaining to each line of graphic text put to the screen. The 'tilted' stuff.
The only things the developer can control while it's scrolling without having to rebuild the images are the size of the output picture box the class inherits and the interval of the timer that runs it. Other than that, you'll have to stop the scroll and start over. Which is what this demonstration application shows. You have scroll bars for the angle and the timer's delay interval, font and color buttons that call up their respective dialogs, and one combobox which lists a choice of selected texts from some of my published novels (not much else to do in prison besides watching TV, going to the gym and eating junk-food). The combo-box also lets you either load a .txt file and use it as a source string or it can offer you a textbox
to write what the Muses may. If you set the font size too big, then it tries to draw one character per line and I'm not wasting time getting that to work, so the dialog boxes in the demonstration limit the sizes from 20-50. Strange results ensue if you go below 14. The TextCrawler
class, however, leaves it up to you to mess it up. If you want a smaller font all crowded together and blotchy or a giant problem, you go ahead and do that. But I recommend you stick between 14 and 48. As for the choice of color, if you try to draw foreground in the same color you've selected to be transparent, then obviously you won't see much of nothing but the reveries of projects gone by. You'll get a lot of very little to see, actually. Nothing really. Try it, if you like to meditate, just remember to hum the sacred word, 'oooooohmmm'.
Even though the user interface in this demonstration shows the angle you select in degrees and not in radians, the class itself uses radians. Anything between 15 and 135 degrees is good (.261799 and 2.356194 radians) gives decent results.
So no white foreground the same as the background, keep the font sizes between 14 and 48 and you're all set.
If you select one of the four texts from the combo box, the scroll will start right away but otherwise you'll have to press that famous 'go' button I mentioned above.
How It Works
I did talk earlier about the TextCrawl
class taking a string
of text, then converting it to an array of string
s that are then each made into graphics. What happens between the time the application uses the:
TextRenderer.DrawText(g,
strTextLine,
fnt,
new Point(recDestination.X,
recDestination.Y),
clrForeColor,
clrBackGroundColor,
TextFormatFlags.Default | TextFormatFlags.NoPrefix);
System.Windows.Forms
function to convert the string
s into graphics and the time that the scrolling text rolls up your screen is really quite a simple concept. It takes those graphic 2D pictures that look as flat as a prairie highway, and redraws them. Redrawing them is not that complicated. The idea struck me like a school marm with a yard stick and I went at it for two days non-stop (almost) because it's such a simple algorithm. It takes every line of the original graphic text and redraws them onto another bitmap of the same size but only gradually increasing the width of each line of pixels as it goes from top to bottom (although this is true for angles between 0-90, the opposite happens with angles between 90 and 180). So that the resultant 'tilted' image looks like the image below:
And that's all it has to do to generate the images that crawl up your screen.
The next thing it needs to do is actually place them on the screen. Originally I thought any Joe out of Backscratch, Kansas could do it in two minutes so why include it in the app... No. No, it took me a while. I'd done something similar. A textcrawl
that used radian coordinates to define my own blocky font that it then radially coordinated each and every individual line of every character on the screen to tiltify them like these ones! It was extremely slow and produced less than professional results but I was proud of myself for having implemented the only algorithm I could think of at a time when I had no internet and didn't know how to manipulate bitmaps the little I do today.
In any case, it's my first week out of prison and I haven't seen my beautiful IDE in seven years and eager as I was, it was like being a lizard with a leg torn off hobbling about painfully waiting for it to grow back as I struggled with the syntax and the changes that happened between C#2010 and C#2017. But nevertheless, I got it done in only two days.
The concept involved in moving these images of lines of tilted text up the screen is similar to the tilting of the text images I just mentioned above. All you have to do is pretend the lines of text (graphic images) are lines of pixels. Resizing their width is a function of their vertical position on the screen and their height is a matter of aspect ratio (I was kicking myself for struggling with this... hours! and then and flash of light! of course, aspect ratio!) So that's it, really. Nothing to it. A simple solution and pretty cool results after 7 years in and 7 days out.
I've Got an Idea
I thought about something really cool today. Using this TextCrawler
concept, I think I may create a leaping text motion thing where the text springs out from the distance at the bottom of the screen upside down and mirrored-like so that it looks like you're seeing the letters leaping towards you and then as they gradually move up the screen, they all shrink in height but grow in width until they're only one pixel tall at which point they cascade down towards you like cannon fire from the enemy ramparts, or your high school English teacher.
It's just two transparent TextCrawler
s superimposed on top of each other... Anyways, I have seven years of project ideas to implement, some of my old code to bring back to life and way too many ideas for now to settle on that one at the moment.
Any questions, just send me a kite.