Как нарисовать анимированный текст в C#
Обратите внимание, что результат в исполняемом файле лучше, чем результат, предоставляемый GIF справа. GIF немного отрывистый, потому что он использует только 20 кадров вместо 200, используемых программой.
В этом примере показано, как нарисовать анимированный текст, чтобы буквы в слове двигались медленно, эффект, иногда используемый в фильмах. Программа рисует текст в PictureBox. Когда он запускается, программа использует следующий код для записи некоторой информации о текущих и конечных размерах элементов управления PictureBox.
// Текущий размер PictureBox. private float StartWidth; private int StartHeight; private float EndWidth = 260; private float Dx, CurrentWidth; private int TicksToGo, TotalTicks; // Информация о строке для рисования. private const string LabelText = "C# Programming"; private Font TextFont; private float[] CharacterWidths; private float TotalCharacterWidth; private void Form1_Load(object sender, EventArgs e) { // Установите начальный размер. StartWidth = picTitle2.Size.Width; StartHeight = picTitle2.Size.Height; CurrentWidth = StartWidth; // Протянем на 2 секунды. TotalTicks = 2 * 1000 / tmrResizePictureBox.Interval; Dx = (EndWidth - StartWidth) / TotalTicks; // Создаем шрифт и измеряем символы. CharacterWidths = new float[LabelText.Length]; TextFont = new Font("Times New Roman", 16); using (Graphics gr = this.CreateGraphics()) { for (int i = 0; i < LabelText.Length; i++) { SizeF ch_size = gr.MeasureString( LabelText.Substring(i, 1), TextFont); CharacterWidths[i] = ch_size.Width; } } TotalCharacterWidth = CharacterWidths.Sum(); }
Код сохраняет начальную высоту элемента управления PictureBox и ширину начала и окончания.
Затем он подсчитывает количество срабатываний tm> tmrResizePictureBox Timer элемента управления Tick в течение 2 секунд. Он использует это число для вычисления суммы Dx, с помощью которой программа должна увеличивать PictureBox во время каждого события Tick, чтобы контролировать конечную ширину элемента управления . р>
Обработчик события Load формы заканчивается с помощью метода MeasureString класса Graphics для измерения каждого из символов в строке, которую программа будет дисплей. р>
Когда вы нажимаете кнопку Анимация, программа использует следующий код для запуска перемещения анимированного текста.
// Изменение размера PictureBox. private void btnAnimate_Click(object sender, EventArgs e) { btnAnimate.Enabled = false; CurrentWidth = StartWidth; picTitle2.Size = new Size((int)StartWidth, picTitle2.Size.Height); picTitle2.Refresh(); TicksToGo = TotalTicks; tmrResizePictureBox.Enabled = true; }
Этот код отключает кнопку и сбрасывает ширину элемента управления PictureBox до его начального значения. Он устанавливает TicksToGo = TotalTicks, чтобы отслеживать количество раз, когда выполняется обработчик событий Tick.
В следующем коде показан обработчик события Tick таймера, который заставляет анимированный текст перемещаться.
// Изменение размера PictureBox. private void tmrResizePictureBox_Tick(object sender, EventArgs e) { CurrentWidth += Dx; picTitle2.Size = new Size((int)CurrentWidth, StartHeight); picTitle2.Refresh(); // Если мы закончили движение, отключите Таймер. if (--TicksToGo <= 0) { tmrResizePictureBox.Enabled = false; btnAnimate.Enabled = true; } }
Этот код добавляет Dx к ширине элемента управления PictureBox и соответственно изменяет размер PictureBox. Затем он уменьшает TicksToGo, и если новое значение равно 0, оно отключает таймер и включает кнопку Animate.
Программа рисует анимированный текст в обработчике событий PictureBox управления Paint. В следующем коде показан обработчик события и метод SpaceTextToFit, который он вызывает.
// Нарисуем текст в элементе управления. private void picTitle2_Paint(object sender, PaintEventArgs e) { // Используйте AntiAlias для получения наилучшего результата. e.Graphics.TextRenderingHint = TextRenderingHint.AntiAlias; e.Graphics.Clear(picTitle2.BackColor); SpaceTextToFit(e.Graphics, picTitle2.ClientRectangle, TextFont, Brushes.Red, LabelText); } // Вставка текста, вставляющего пробел между символами // чтобы заполнить указанную ширину. private void SpaceTextToFit(Graphics gr, Rectangle rect, Font font, Brush brush, string text) { using (StringFormat string_format = new StringFormat()) { string_format.Alignment = StringAlignment.Near; string_format.LineAlignment = StringAlignment.Near; // Вычислить интервал. float space = (rect.Width - TotalCharacterWidth) / (text.Length - 1); // Рисуем символы. PointF point = new PointF(rect.X, rect.Y); for (int i = 0; i < text.Length; i++) { gr.DrawString(text[i].ToString(), font, brush, point); point.X += CharacterWidths[i] + space; } } }
Обработчик событий Paint просто вызывает метод SpaceTextToFit, чтобы выполнить всю интересную работу. Единственный трюк - установить свойство TextRenderHint объекта Graphics объекта AntiAlias. Значения «grid fit» (один из них используется по умолчанию) обычно дают лучшую производительность, но беспорядок выравнивания символов в этом примере дает результат резкий внешний вид.
Метод SpaceTextToFit рисует текст, добавляя дополнительное пространство между символами для заполнения требуемой ширины. Это не делает ничего необычного с высотой текста.
Код вычитает полную ширину символов из ширины целевой области и делит ее на части для вставки между символами.