标签:orb void center lse phi 特效 决定 char user
控件可以添加文本段列表,每段文本可以设置出现动画和文字渐变颜色,还可以让指定某一段文本重复播放指定的次数。
/// <summary> /// 文本跑马灯特效控件 /// </summary> [ToolboxItem(true)] [DefaultProperty("Items")] [Description("文本跑马灯特效控件")] public partial class TextCarouselExt : Control { public delegate void IndexEventHandler(object sender, IndexEventArgs e); #region private event IndexEventHandler indexChanged; /// <summary> /// 当前正在播放文本选项索引更改事件 /// </summary> [Description("当前正在播放文本选项索引更改事件")] public event IndexEventHandler IndexChanged { add { this.indexChanged += value; } remove { this.indexChanged -= value; } } private bool active = false; /// <summary> /// 文本轮播激活状态 /// </summary> [DefaultValue(false)] [Description("文本轮播激活状态")] public bool Active { get { return this.active; } set { if (this.active == value) return; this.active = value; this.intervalTimer.Enabled = value; } } private int intervalTime = 100; /// <summary> /// 文本选项轮播的时间间隔 /// </summary> [DefaultValue(100)] [Description("文本选项轮播的时间间隔(默认100毫秒)")] public int IntervalTime { get { return this.intervalTime; } set { if (this.intervalTime == value) return; this.intervalTime = value; } } int currentIndex = -1; /// <summary> ///当前正在播放文本选项索引 /// </summary> [Browsable(false)] [DefaultValue(-1)] [Description("当前正在播放文本选项索引")] public int CurrentIndex { get { return this.currentIndex; } set { if (this.currentIndex == value) return; this.currentIndex = value; if (this.indexChanged != null) this.indexChanged(this, new IndexEventArgs() { Index = this.currentIndex, Item = this.Items[this.currentIndex] }); } } private TextItemCollection textItemCollection; /// <summary> /// 文本选项集合 /// </summary> [DefaultValue(null)] [Description("文本选项集合")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public TextItemCollection Items { get { if (this.textItemCollection == null) this.textItemCollection = new TextItemCollection(this); return this.textItemCollection; } } [Editor(typeof(ColorEditorExt), typeof(System.Drawing.Design.UITypeEditor))] public override Color BackColor { get { return base.BackColor; } set { base.BackColor = value; } } protected override Size DefaultSize { get { return new Size(300, 60); } } /// <summary> /// 文本选项轮播的时间间隔累计(-1为动画正在切换中)(-2出现后停留中) /// </summary> private int intervalTimeValue = 0; /// <summary> /// 文本选项播放时间间隔定时器 /// </summary> private Timer intervalTimer; /// <summary> /// 文本选项出现后停留时间累计 /// </summary> private int remainTimeValue = 0; /// <summary> /// 动画播放定时器 /// </summary> private AnimationTimer animationTimer; #endregion public TextCarouselExt() { SetStyle(ControlStyles.UserPaint, true); SetStyle(ControlStyles.AllPaintingInWmPaint, true); SetStyle(ControlStyles.OptimizedDoubleBuffer, true); SetStyle(ControlStyles.ResizeRedraw, true); SetStyle(ControlStyles.SupportsTransparentBackColor, true); InitializeComponent(); this.InitializeTextRectangles(); this.intervalTimer = new Timer(); this.intervalTimer.Interval = 50; this.intervalTimer.Tick += new EventHandler(this.intervalTimer_Tick); this.animationTimer = new AnimationTimer(this, new AnimationOptions()); this.animationTimer.AnimationIng += new AnimationTimer.AnimationHandel(this.animationTimer_AnimationIng); this.animationTimer.AnimationEnding += new AnimationTimer.AnimationHandel(this.animationTimer_AnimationEnding); } #region 重写 protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); if (this.Items.Count < 0 || this.CurrentIndex < 0) return; Graphics g = e.Graphics; TextItem textItem = this.Items[this.CurrentIndex]; #region Scroll if (textItem.Way == AnimationWay.Scroll) { if (textItem.TextColorItems.Count < 1) { SolidBrush text_sb = new SolidBrush(textItem.TextColor); g.DrawString(textItem.Text, textItem.TextFont, text_sb, textItem.current_rectf); text_sb.Dispose(); } else { int len = Math.Max(textItem.TextColorItems.Count, 2); Color[] colors = new Color[len]; float[] interval = new float[len]; for (int i = 0; i < textItem.TextColorItems.Count; i++) { colors[i] = textItem.TextColorItems[i].ShadeColor; interval[i] = textItem.TextColorItems[i].Shade; } if (textItem.TextColorItems.Count == 1) { colors[1] = textItem.TextColorItems[0].ShadeColor; interval[1] = textItem.TextColorItems[0].Shade; } //Positions开始值必须为0,结束值必须为1 interval[0] = 0.0f; interval[textItem.TextColorItems.Count - 1] = 1.0f; LinearGradientBrush text_lgb = new LinearGradientBrush(textItem.current_rectf, Color.Transparent, Color.Transparent, textItem.ShadeAngle); text_lgb.InterpolationColors = new ColorBlend() { Colors = colors, Positions = interval }; g.DrawString(textItem.Text, textItem.TextFont, text_lgb, textItem.current_rectf); text_lgb.Dispose(); } } #endregion #region Speed SpeedSpringback else if (textItem.Way == AnimationWay.Speed || textItem.Way == AnimationWay.SpeedSpringback) { if (textItem.TextColorItems.Count < 1) { SolidBrush text_sb = new SolidBrush(textItem.TextColor); for (int i = 0; i < textItem.TextChar.Length; i++) { g.DrawString(textItem.TextChar[i], textItem.TextFont, text_sb, textItem.current_char_rectf[i]); } text_sb.Dispose(); } else { int len = Math.Max(textItem.TextColorItems.Count, 2); Color[] colors = new Color[len]; float[] interval = new float[len]; RectangleF text_lgb_rectf = new RectangleF(textItem.current_char_rectf[0].X, textItem.current_char_rectf[0].Y, textItem.current_char_rectf[textItem.TextChar.Length - 1].Right, textItem.current_char_rectf[0].Height); LinearGradientBrush text_lgb = new LinearGradientBrush(text_lgb_rectf, Color.Transparent, Color.Transparent, textItem.ShadeAngle); for (int k = 0; k < textItem.TextChar.Length; k++) { for (int i = 0; i < textItem.TextColorItems.Count; i++) { colors[i] = textItem.TextColorItems[i].ShadeColor; interval[i] = textItem.TextColorItems[i].Shade; } if (textItem.TextColorItems.Count == 1) { colors[1] = textItem.TextColorItems[0].ShadeColor; interval[1] = textItem.TextColorItems[0].Shade; } //Positions开始值必须为0,结束值必须为1 interval[0] = 0.0f; interval[textItem.TextColorItems.Count - 1] = 1.0f; text_lgb.InterpolationColors = new ColorBlend() { Colors = colors, Positions = interval }; g.DrawString(textItem.TextChar[k], textItem.TextFont, text_lgb, textItem.current_char_rectf[k]); } text_lgb.Dispose(); } #endregion } } protected override void OnResize(EventArgs e) { base.OnResize(e); this.InitializeTextRectangles(); } #endregion #region 动画 /// <summary> /// 动画开始事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void intervalTimer_Tick(object sender, EventArgs e) { #region 第一步检查动画是否为进行中 if (this.intervalTimeValue == -1)//动画进行中 return; #endregion #region 第二步检查文本是否为动画完成后停留中 if (this.intervalTimeValue == -2)//停留中 { this.remainTimeValue += this.intervalTimer.Interval; if (this.remainTimeValue < this.Items[this.CurrentIndex].RemainTime * 1000) { return; } this.remainTimeValue = 0; this.intervalTimeValue = 0; } #endregion #region 第三步检查是否要进行重复播放 if (this.CurrentIndex > -1) { this.Items[this.CurrentIndex].CurrentRepetition += 1; if (this.Items[this.CurrentIndex].CurrentRepetition <= this.Items[this.CurrentIndex].Repetition) { goto DH; } else { this.Items[this.CurrentIndex].CurrentRepetition = 0; } } #endregion #region 第四步检查下一个文本选项是否禁用,禁用则跳到下下一个文本选项 int index = this.CurrentIndex + 1; if (index > this.Items.Count - 1) { index -= this.Items.Count; } if (!this.Items[index].Enabled) { this.CurrentIndex++; if (this.CurrentIndex > this.Items.Count - 1) { this.CurrentIndex -= this.Items.Count; } } #endregion #region 第五步检查是否是时间进入下一个文本选项动画播放 this.intervalTimeValue += this.intervalTimer.Interval; if (this.intervalTimeValue < this.IntervalTime) { return; } this.intervalTimeValue = -1; this.CurrentIndex++; if (this.CurrentIndex > this.Items.Count - 1) { this.CurrentIndex -= this.Items.Count; } #endregion #region 播放动画 DH: TextItem textItem = this.Items[this.CurrentIndex]; this.animationTimer.Options.Data = textItem; if (textItem.Way == AnimationWay.Scroll) { this.animationTimer.AT = AnimationType.UniformMotion; this.animationTimer.Options.Power = 3; this.animationTimer.Options.AllTime = 100f * (textItem.Orientation == AnimationOrientation.Right ? (float)textItem.prev_rectf.Width : (float)textItem.prev_rectf.Height);//动画时间由文字长度决定,速度为每个像素使用50毫秒 } else if (textItem.Way == AnimationWay.Speed) { this.animationTimer.AT = AnimationType.EaseOut; this.animationTimer.Options.AllTime = textItem.TextChar.Length * 100; this.animationTimer.Options.AllTime = 1000d; } else if (textItem.Way == AnimationWay.SpeedSpringback) { this.animationTimer.AT = AnimationType.BackOut; this.animationTimer.Options.Power = 1; this.animationTimer.Options.AllTime = 1000d; } this.animationTimer.Start(true, 0); #endregion } /// <summary> /// 动画进行中事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void animationTimer_AnimationIng(object sender, AnimationEventArgs e) { TextItem textItem = (TextItem)e.Data; if (textItem.Way == AnimationWay.Scroll) { float x = textItem.prev_rectf.X; float y = textItem.prev_rectf.Y; if (textItem.Orientation == AnimationOrientation.Top || textItem.Orientation == AnimationOrientation.Bottom) { y = textItem.prev_rectf.Y + (float)((textItem.target_rectf.Y - textItem.prev_rectf.Y) * e.progressTime); } else if (textItem.Orientation == AnimationOrientation.Right) { x = textItem.prev_rectf.X + (float)((textItem.target_rectf.X - textItem.prev_rectf.X) * e.progressTime); } textItem.current_rectf = new RectangleF(x, y, textItem.prev_rectf.Width, textItem.prev_rectf.Height); } else if (textItem.Way == AnimationWay.Speed) { for (int i = 0; i < textItem.TextChar.Length; i++) { float x = textItem.prev_char_rectf[i].X; float y = textItem.prev_char_rectf[i].Y; if (textItem.Orientation == AnimationOrientation.Top || textItem.Orientation == AnimationOrientation.Bottom) { y = textItem.prev_char_rectf[i].Y + (float)((textItem.target_char_rectf[i].Y - textItem.prev_char_rectf[i].Y) * e.progressTime); } else if (textItem.Orientation == AnimationOrientation.Right) { x = textItem.prev_char_rectf[i].X + (float)((textItem.target_char_rectf[i].X - textItem.prev_char_rectf[i].X) * e.progressTime); } textItem.current_char_rectf[i] = new RectangleF(x, y, textItem.prev_char_rectf[i].Width, textItem.prev_char_rectf[i].Height); } } else if (textItem.Way == AnimationWay.SpeedSpringback) { for (int i = 0; i < textItem.TextChar.Length; i++) { float x = textItem.prev_char_rectf[i].X; float y = textItem.prev_char_rectf[i].Y; if (textItem.Orientation == AnimationOrientation.Top || textItem.Orientation == AnimationOrientation.Bottom) { y = textItem.prev_char_rectf[i].Y + (float)((textItem.target_char_rectf[i].Y - textItem.prev_char_rectf[i].Y) * e.progressTime); } else if (textItem.Orientation == AnimationOrientation.Right) { x = textItem.prev_char_rectf[i].X + (float)((textItem.target_char_rectf[i].X - textItem.prev_char_rectf[i].X) * e.progressTime); } textItem.current_char_rectf[i] = new RectangleF(x, y, textItem.prev_char_rectf[i].Width, textItem.prev_char_rectf[i].Height); } } this.Invalidate(); } /// <summary> /// 动画结束时事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void animationTimer_AnimationEnding(object sender, AnimationEventArgs e) { this.intervalTimeValue = -2; } #endregion #region 私有 /// <summary> /// 初始化播放前每一段文本rect /// </summary> private void InitializeTextRectangles() { for (int i = 0; i < this.Items.Count; i++) { this.InitializeTextRectangle(this.Items[i]); } } /// <summary> /// 初始化文本rect /// </summary> /// <param name="textItem"></param> private void InitializeTextRectangle(TextItem textItem) { Rectangle rect = this.ClientRectangle; Size text_size = TextRenderer.MeasureText(textItem.Text, textItem.TextFont, new Size(), TextFormatFlags.ExternalLeading); int len = textItem.Text.Length; int avg_w = len == 0 ? 0 : text_size.Width / len; #region Scroll if (textItem.Way == AnimationWay.Scroll) { float x = 0; float y = 0; float target_x = 0; float target_y = 0; if (textItem.Orientation == AnimationOrientation.Top) { x = rect.X; if (textItem.TextCenter) { x = rect.X + (rect.Width - text_size.Width) / 2; if (x < rect.X) x = rect.X; } y = rect.Y - text_size.Height; target_x = x; target_y = rect.Bottom + text_size.Height; } else if (textItem.Orientation == AnimationOrientation.Bottom) { x = rect.X; if (textItem.TextCenter) { x = rect.X + (rect.Width - text_size.Width) / 2; if (x < rect.X) x = rect.X; } y = rect.Bottom; target_x = x; target_y = rect.Y - text_size.Height; } else if (textItem.Orientation == AnimationOrientation.Right) { x = rect.Right; y = (rect.Height - text_size.Height) / 2; target_x = rect.X - text_size.Width; target_y = y; } textItem.prev_rectf = new RectangleF(x, y, text_size.Width, text_size.Height); textItem.current_rectf = textItem.prev_rectf; textItem.target_rectf = new RectangleF(target_x, target_y, text_size.Width, text_size.Height); } #endregion #region Speed else if (textItem.Way == AnimationWay.Speed) { textItem.TextCharAvgWidth = text_size.Width / len; textItem.TextChar = new string[len]; textItem.prev_char_rectf = new RectangleF[len]; textItem.current_char_rectf = new RectangleF[len]; textItem.target_char_rectf = new RectangleF[len]; for (int i = 0; i < len; i++) { float x = 0; float y = 0; float target_x = 0; float target_y = 0; if (textItem.Orientation == AnimationOrientation.Top) { float tmp_x = rect.X + i * avg_w; x = tmp_x; if (textItem.TextCenter) { x = tmp_x + (rect.Width - text_size.Width) / 2; if (x < tmp_x) x = tmp_x; } y = rect.Y - i * text_size.Height; target_x = x; target_y = (rect.Height - text_size.Height) / 2; } else if (textItem.Orientation == AnimationOrientation.Bottom) { float tmp_x = rect.X + i * avg_w; x = tmp_x; if (textItem.TextCenter) { x = tmp_x + (rect.Width - text_size.Width) / 2; if (x < tmp_x) x = tmp_x; } y = rect.Bottom + i * text_size.Height; target_x = x; target_y = (rect.Height - text_size.Height) / 2; } else if (textItem.Orientation == AnimationOrientation.Right) { x = rect.Right + i * rect.Width; y = (rect.Height - text_size.Height) / 2; target_x = rect.X + i * avg_w; target_y = y; } textItem.TextChar[i] = textItem.Text.Substring(i, 1); textItem.prev_char_rectf[i] = new RectangleF(x, y, avg_w, text_size.Height); textItem.current_char_rectf[i] = textItem.prev_char_rectf[i]; textItem.target_char_rectf[i] = new RectangleF(target_x, target_y, avg_w, text_size.Height); } } #endregion #region SpeedSpringback else if (textItem.Way == AnimationWay.SpeedSpringback) { textItem.TextCharAvgWidth = text_size.Width / len; textItem.TextChar = new string[len]; textItem.prev_char_rectf = new RectangleF[len]; textItem.current_char_rectf = new RectangleF[len]; textItem.target_char_rectf = new RectangleF[len]; for (int i = 0; i < len; i++) { float x = 0; float y = 0; float target_x = 0; float target_y = 0; if (textItem.Orientation == AnimationOrientation.Top) { float tmp_x = rect.X + i * avg_w; x = tmp_x; if (textItem.TextCenter) { x = tmp_x + (rect.Width - text_size.Width) / 2; if (x < tmp_x) x = tmp_x; } y = rect.Y - text_size.Height - text_size.Height - text_size.Height / 2; target_x = x; target_y = (rect.Height - text_size.Height) / 2; } else if (textItem.Orientation == AnimationOrientation.Bottom) { float tmp_x = rect.X + i * avg_w; x = tmp_x; if (textItem.TextCenter) { x = tmp_x + (rect.Width - text_size.Width) / 2; if (x < tmp_x) x = tmp_x; } y = rect.Bottom + text_size.Height + text_size.Height / 2; target_x = x; target_y = (rect.Height - text_size.Height) / 2; } else if (textItem.Orientation == AnimationOrientation.Right) { x = rect.Right + i * avg_w * 3; y = (rect.Height - text_size.Height) / 2; target_x = rect.X + i * avg_w; target_y = y; } textItem.TextChar[i] = textItem.Text.Substring(i, 1); textItem.prev_char_rectf[i] = new RectangleF(x, y, avg_w, text_size.Height); textItem.current_char_rectf[i] = textItem.prev_char_rectf[i]; textItem.target_char_rectf[i] = new RectangleF(target_x, target_y, avg_w, text_size.Height); } } #endregion } #endregion protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); if (this.intervalTimer != null) { this.intervalTimer.Dispose(); } if (this.animationTimer != null) { this.animationTimer.Dispose(); } } base.Dispose(disposing); } /// <summary> /// 文本选项集合 /// </summary> [Description("文本选项集合")] [Editor(typeof(CollectionEditorExt), typeof(UITypeEditor))] public sealed class TextItemCollection : IList, ICollection, IEnumerable { private ArrayList textItemList = new ArrayList(); private TextCarouselExt owner; public TextItemCollection(TextCarouselExt owner) { this.owner = owner; } #region IEnumerable public IEnumerator GetEnumerator() { TextItem[] listArray = new TextItem[this.textItemList.Count]; for (int index = 0; index < listArray.Length; ++index) listArray[index] = (TextItem)this.textItemList[index]; return listArray.GetEnumerator(); } #endregion #region ICollection public void CopyTo(Array array, int index) { for (int i = 0; i < this.Count; i++) array.SetValue(this.textItemList[i], i + index); } public int Count { get { return this.textItemList.Count; } } public bool IsSynchronized { get { return false; } } public object SyncRoot { get { return (object)this; } } #endregion #region IList public int Add(object value) { TextItem textItem = (TextItem)value; this.textItemList.Add(textItem); this.owner.InitializeTextRectangle(textItem); this.owner.Invalidate(); return this.Count - 1; } public void Clear() { this.textItemList.Clear(); this.owner.Invalidate(); } public bool Contains(object value) { return this.IndexOf(value) != -1; } public int IndexOf(object value) { return this.textItemList.IndexOf(value); } public void Insert(int index, object value) { throw new NotImplementedException(); } public bool IsFixedSize { get { return false; } } public bool IsReadOnly { get { return false; } } public void Remove(object value) { if (!(value is TextItem)) return; this.textItemList.Remove((TextItem)value); this.owner.Invalidate(); } public void RemoveAt(int index) { this.textItemList.RemoveAt(index); this.owner.Invalidate(); } public TextItem this[int index] { get { return (TextItem)this.textItemList[index]; } set { this.textItemList[index] = (TextItem)value; this.owner.InitializeTextRectangle((TextItem)value); this.owner.Invalidate(); } } object IList.this[int index] { get { return (object)this.textItemList[index]; } set { this.textItemList[index] = (TextItem)value; this.owner.InitializeTextRectangle((TextItem)value); this.owner.Invalidate(); } } #endregion } /// <summary> /// 渐变颜色选项集合 /// </summary> [Description("渐变颜色选项集合")] [Editor(typeof(CollectionEditorExt), typeof(UITypeEditor))] public sealed class ShadeColorItemCollection : IList, ICollection, IEnumerable { private ArrayList shadeColorItemList = new ArrayList(); public ShadeColorItemCollection() { } #region IEnumerable public IEnumerator GetEnumerator() { ShadeColorItem[] listArray = new ShadeColorItem[this.shadeColorItemList.Count]; for (int index = 0; index < listArray.Length; ++index) listArray[index] = (ShadeColorItem)this.shadeColorItemList[index]; return listArray.GetEnumerator(); } #endregion #region ICollection public void CopyTo(Array array, int index) { for (int i = 0; i < this.Count; i++) array.SetValue(this.shadeColorItemList[i], i + index); } public int Count { get { return this.shadeColorItemList.Count; } } public bool IsSynchronized { get { return false; } } public object SyncRoot { get { return (object)this; } } #endregion #region IList public int Add(object value) { ShadeColorItem textItem = (ShadeColorItem)value; this.shadeColorItemList.Add(textItem); return this.Count - 1; } public void Clear() { this.shadeColorItemList.Clear(); } public bool Contains(object value) { return this.IndexOf(value) != -1; } public int IndexOf(object value) { return this.shadeColorItemList.IndexOf(value); } public void Insert(int index, object value) { throw new NotImplementedException(); } public bool IsFixedSize { get { return false; } } public bool IsReadOnly { get { return false; } } public void Remove(object value) { if (!(value is ShadeColorItem)) return; this.shadeColorItemList.Remove((ShadeColorItem)value); } public void RemoveAt(int index) { this.shadeColorItemList.RemoveAt(index); } public ShadeColorItem this[int index] { get { return (ShadeColorItem)this.shadeColorItemList[index]; } set { this.shadeColorItemList[index] = (ShadeColorItem)value; } } object IList.this[int index] { get { return (object)this.shadeColorItemList[index]; } set { this.shadeColorItemList[index] = (ShadeColorItem)value; } } #endregion } /// <summary> /// 文本选项 /// </summary> [Description("文本选项")] public class TextItem { private bool enabled = true; /// <summary> /// 文本选项是否参与轮播 /// </summary> [DefaultValue(true)] [Description("文本选项是否参与轮播")] public bool Enabled { get { return this.enabled; } set { if (this.enabled == value) return; this.enabled = value; } } private AnimationWay way = AnimationWay.Scroll; /// <summary> /// 动画方式 /// </summary> [DefaultValue(AnimationWay.Scroll)] [Description("动画方式")] public AnimationWay Way { get { return this.way; } set { if (this.way == value) return; this.way = value; } } private AnimationOrientation orientation = AnimationOrientation.Right; /// <summary> /// 动画出现方向 /// </summary> [DefaultValue(AnimationOrientation.Right)] [Description("动画出现方向")] public AnimationOrientation Orientation { get { return this.orientation; } set { if (this.orientation == value) return; this.orientation = value; } } private int remainTime = 0; /// <summary> /// 文本选项出现后停留时间(默认0秒) /// </summary> [DefaultValue(0)] [Description("文本选项出现后停留时间(默认0秒)")] public int RemainTime { get { return this.remainTime; } set { if (this.remainTime == value || value < 0) return; this.remainTime = value; } } private int repetition = 1; /// <summary> /// 文本选项在单次循环轮播中重复次数(默认1次) /// </summary> [DefaultValue(1)] [Description("文本选项在单次循环轮播中重复次数(默认1次)")] public int Repetition { get { return this.repetition; } set { if (this.repetition == value || value < 1) return; this.repetition = value; } } private string text = ""; /// <summary> /// 文本 /// </summary> [DefaultValue("")] [Description("文本字体")] public string Text { get { return this.text; } set { if (this.text == value) return; this.text = value; } } private string[] textChar = null; /// <summary> /// 文本每个字符集合 [Browsable(false)] [DefaultValue(null)] [Description("文本每个字符集合")] public string[] TextChar { get { return this.textChar; } set { this.textChar = value; } } private float textCharAvgWidth = 0f; /// <summary> /// 文本每个字符平均宽度 [Browsable(false)] [DefaultValue(0f)] [Description("文本每个字符平均宽度")] public float TextCharAvgWidth { get { return this.textCharAvgWidth; } set { this.textCharAvgWidth = value; } } private bool textCenter = false; /// <summary> /// 文本是否水平居中(仅限垂直动画) /// </summary> [DefaultValue(false)] [Description("文本是否水平居中(仅限垂直动画)")] public bool TextCenter { get { return this.textCenter; } set { this.textCenter = value; } } private Font textFont = new Font("宋体", 20); /// <summary> /// 文本字体 /// </summary> [DefaultValue(typeof(Font), "宋体, 20pt")] [Description("文本字体")] public Font TextFont { get { return this.textFont; } set { if (this.textFont == value) return; this.textFont = value; } } private Color textColor = Color.FromArgb(154, 205, 50); /// <summary> /// 文本颜色 /// </summary> [DefaultValue(typeof(Color), "154, 205, 50")] [Description("文本颜色")] [Editor(typeof(ColorEditorExt), typeof(System.Drawing.Design.UITypeEditor))] public Color TextColor { get { return this.textColor; } set { if (this.textColor == value) return; this.textColor = value; } } private ShadeColorItemCollection shadeColorItemCollection; /// <summary> /// 渐变颜色选项集合 /// </summary> [DefaultValue(null)] [Description("渐变颜色选项集合")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public ShadeColorItemCollection TextColorItems { get { if (this.shadeColorItemCollection == null) this.shadeColorItemCollection = new ShadeColorItemCollection(); return this.shadeColorItemCollection; } } private float shadeAngle = 0f; /// <summary> /// 渐变方向线的角度(从 X 轴以顺时针角度计算) /// </summary> [DefaultValue(0f)] [Description("渐变方向线的角度(从 X 轴以顺时针角度计算)")] public float ShadeAngle { get { return this.shadeAngle; } set { if (this.shadeAngle == value || value < 0f || value > 360f) return; this.shadeAngle = value; } } private int currentRepetition = 0; /// <summary> /// 文本选项在单次循环轮播中当前的重复次数 /// </summary> [Browsable(false)] [DefaultValue(0)] [Description("文本选项在单次循环轮播中当前的重复次数")] public int CurrentRepetition { get { return this.currentRepetition; } set { if (this.currentRepetition == value) return; this.currentRepetition = value; } } /// <summary> /// 运动前rectf /// </summary> [Browsable(false)] [Description("运动前rectf")] public RectangleF prev_rectf { get; set; } /// <summary> /// 目标rectf /// </summary> [Browsable(false)] [Description("目标rectf")] public RectangleF target_rectf { get; set; } /// <summary> /// 当前rectf /// </summary> [Browsable(false)] [Description("当前rectf")] public RectangleF current_rectf { get; set; } /// <summary> /// 运动前每个字的rectf /// </summary> [Browsable(false)] [Description("运动前rectf")] public RectangleF[] prev_char_rectf { get; set; } /// <summary> /// 目标每个字rectf /// </summary> [Browsable(false)] [Description("目标每个字rectf")] public RectangleF[] target_char_rectf { get; set; } /// <summary> /// 当前每个字的rectf /// </summary> [Browsable(false)] [Description("当前rectf")] public RectangleF[] current_char_rectf { get; set; } } /// <summary> /// 渐变颜色选项 /// </summary> [Description("渐变颜色选项")] public class ShadeColorItem { private float shade = 0f; /// <summary> /// 渐变值0-1 /// </summary> [DefaultValue(0f)] [Description("渐变值0-1")] public float Shade { get { return this.shade; } set { if (this.shade == value || value < 0 || value > 1) return; this.shade = value; } } private Color shadeColor = Color.Empty; /// <summary> /// 渐变值对应渐变颜色 /// </summary> [DefaultValue(typeof(Color), "Empty")] [Description("渐变值对应渐变颜色")] [Editor(typeof(ColorEditorExt), typeof(System.Drawing.Design.UITypeEditor))] public Color ShadeColor { get { return this.shadeColor; } set { if (this.shadeColor == value) return; this.shadeColor = value; } } } /// <summary> /// 动画方式 /// </summary> [Description("动画方式")] public enum AnimationWay { /// <summary> /// 普通滚动 /// </summary> Scroll, /// <summary> /// 减速 /// </summary> Speed, /// <summary> /// 减速回弹 /// </summary> SpeedSpringback } /// <summary> /// 动画出现方向 /// </summary> [Description("控件滑块方向位置")] public enum AnimationOrientation { /// <summary> ///从上边出现 /// </summary> Top, /// <summary> /// 从下边出现 /// </summary> Bottom, /// <summary> /// 从右边出现 /// </summary> Right } /// <summary> /// 当前正在播放文本选项索引更改事件参数 /// </summary> [Description("当前正在播放文本选项索引更改事件参数")] public class IndexEventArgs : EventArgs { /// <summary> /// 当前正在播放文本选项索引 /// </summary> [Description("当前正在播放文本选项索引")] public float Index { get; set; } /// <summary> /// 当前正在播放文本选项 /// </summary> [Description("当前正在播放文本选项")] public TextItem Item { get; set; } } }
源码下载:文本跑马灯特效控件.zip
文本跑马灯特效控件----------WinForm控件开发系列
标签:orb void center lse phi 特效 决定 char user
原文地址:https://www.cnblogs.com/tlmbem/p/11436778.html