using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Windows.Forms;
namespace App
{
public class rgbshit : Control
{
#region Public Constructors
public rgbshit()
{
SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw | ControlStyles.UserPaint, true);
Speed = 300;
SetColors(_colors);
_timer.Tick += _timerTick;
_timer.Start();
}
#endregion Public Constructors
#region Public Properties
/// <summary>
/// Скорость анимации, пикс/сек
/// </summary>
public float Speed
{
get => _speed;
set
{
if (_speed == value) return;
_speed = value;
if (Width > 0)
{
SetDelta();
}
}
}
#endregion Public Properties
#region Public Methods
public void SetColors(IEnumerable<Color> colors)
{
var ar = colors.ToArray();
_colors = new Color[ar.Length * 2 - 1];
Array.Copy(ar, 0, _colors, ar.Length - 1, ar.Length);
ar = ar.Reverse().ToArray();
Array.Copy(ar, 0, _colors, 0, ar.Length - 1);
_positions = new float[_colors.Length];
var step = 1f / (2 * (ar.Length - 1));
for (int i = 1; i < _positions.Length - 1; i++)
{
_positions[i] = _positions[i - 1] + step;
}
_positions[ar.Length - 1] = 0.5f;
_positions[_positions.Length - 1] = 1f;
Invalidate();
}
/// <summary>
/// Запустить анимацию
/// </summary>
public void StartAmimation()
{
_timer.Start();
}
/// <summary>
/// Остановить анимацию
/// </summary>
public void StopAmimation()
{
_timer.Stop();
}
#endregion Public Methods
#region Protected Properties
protected override bool DoubleBuffered { get => true; set => base.DoubleBuffered = true; }
#endregion Protected Properties
#region Protected Methods
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
var rect = new RectangleF(-ClientRectangle.Width, ClientRectangle.Y, ClientRectangle.Width * 2, ClientRectangle.Height);
rect.Offset(_offset, 0);
using (var brush = new LinearGradientBrush(rect, Color.Transparent, Color.Transparent, 0f))
{
brush.InterpolationColors = new ColorBlend
{
Colors = _colors,
Positions = _positions
};
e.Graphics.FillRectangle(brush, ClientRectangle);
}
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
SetDelta();
}
#endregion Protected Methods
#region Private Fields
private Color[] _colors = new Color[] {
Color.Red,
Color.Green,
Color.Blue
};
private float _delta;
private float _offset;
private float[] _positions = new float[] { 0, 0.25f, 0.5f, 0.75f, 1 };
private float _speed;
private Timer _timer = new Timer() { Interval = 100 };
#endregion Private Fields
#region Private Methods
private void _timerTick(object sender, EventArgs e)
{
_offset += _delta;
if (_offset >= 2 * Width) _offset = 0;
Invalidate();
}
private void SetDelta()
{
_delta = _speed * (_timer.Interval / 1000f);
}
#endregion Private Methods
}
}