[英]Infinite scrolling gradient background
我已经搜索过,但没有在 SO 上找到这个问题的答案,所以我直接在这里问。
有没有人有一个干净的方法来创建一个无限滚动的渐变背景? (渐变变化,因此您可以从一侧/角落到另一侧跟随颜色)
我在 15 年前就用 VB 做过这个,但是我已经很久没有接触 VB 了,它对我来说都是希腊语。
假设以前有人在 C# 中做过类似的事情——想想演示场景类的动画。
VB 代码片段来自我多年前做的一个工作表单背景,它不会滚动太多,而是从一个边缘到另一个边缘来回弹跳。
Private Sub picCanvas_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Panel1.Paint
Dim rect As New Rectangle(-10, -10, Me.ClientSize.Width + 20, Me.ClientSize.Height + 20)
Dim halfw As Integer = CType(Me.ClientSize.Width, Integer)
Dim br As New LinearGradientBrush(New Point(-120, 500), New Point(Me.ClientSize.Width + 120, 0), Color.Red, Color.Blue)
Dim color_blend As New ColorBlend
color_blend.Colors = New Color() {Color.Black, Color.Purple, Color.Teal, Color.Purple, Color.Black}
m_Theta += m_Delta
color_blend.Positions = New Single() {0, 0.01, m_Theta, 0.99, 1}
br.InterpolationColors = color_blend
e.Graphics.FillRectangle(br, rect)
br.Dispose()
If (m_Theta > 0.75) Or (m_Theta < 0.25) Then m_Delta = -m_Delta
End Sub
我将不胜感激任何帮助让这种东西在 WinForms 中工作只使用 GDI 和画笔,没有 XML 或任何东西请 ^^/
我不太确定这是你想要做的,无论如何,从此处提供的半伪代码来看,你似乎想要沿轴移动渐变填充的位置。
看起来填充是倾斜的,所以我添加了确定旋转角度的方法。
我保留了 LinearGradientBrush 来生成混合填充,尽管 GraphicsPath 和PathGradientBrush的组合可能更灵活。
为了移动渐变填充,我使用了标准的System.Windows.Forms.Timer
。 它用于平移填充,递增一个值,然后在用作画布的双缓冲 Form 的 OnPaint 覆盖中设置为Matrix的平移组件(当然,您可以改用 PictureBox)
Matrix 还用于旋转填充,以备不时之需
计时器的Tick
处理程序还验证可用于更改填充的其他条件(bool 字段):
useThetaShift
启用混合间隔的半动态运动( Position
属性)useTriangular
启用和交替混合功能,由SetBlendTriangularShape()方法生成,它仅考虑 LinearGradientBrush 的起始和结束颜色,并定义颜色衰减的中心点此处显示的示例窗体也可以设置为自动滚动,混合扩展到 DisplayRectangle
当显示模态对话框时,混合也会动画化(你提到了一个关于窗口......)
internal class SomeForm : Form {
private System.Windows.Forms.Timer gradientTimer = null;
public SomeForm() {
InitializeComponent();
if (components is null) components = new Container();
ResizeRedraw = true;
startColor = blendColors[0];
meanColor = blendColors[1];
endColor = blendColors[blendColors.Length - 1];
gradientTimer = new System.Windows.Forms.Timer(components) { Interval = 100 };
gradientTimer.Tick += GradientTimer_Tick;
gradientTimer.Start();
}
float theta = .0f;
float delta = .005f;
float tringularShift = .25f;
float tringularShiftDelta = .015f;
float speed = 7.5f;
float rotation = 0f;
private Color[] blendColors = new[]{
Color.Black, Color.Purple, Color.Teal, Color.Purple, Color.Black
};
Color startColor = Color.Empty;
Color endColor = Color.Empty;
Color meanColor = Color.Empty;
PointF translateMx = PointF.Empty;
bool useThetaShift = false;
bool useTriangular = false;
private void GradientTimer_Tick(object sender, EventArgs e)
{
if (useTriangular) {
tringularShift += tringularShiftDelta;
tringularShift = Math.Max(Math.Min(tringularShift, 1.0f), .35f);
if ((tringularShift >= 1.0f) | (tringularShift <= .35f)) tringularShiftDelta*= -1;
}
if (useThetaShift) {
theta += delta;
theta = Math.Max(Math.Min(theta, .15f), 0f);
if ((theta >= .15f) | (theta <= 0f)) delta*= -1;
}
translateMx = PointF.Add(translateMx, new SizeF(speed, speed));
if (Math.Abs(translateMx.X) >= short.MaxValue) translateMx = PointF.Empty;
Invalidate();
}
protected override void OnPaint(PaintEventArgs e)
{
var display = DisplayRectangle;
using (var mx = new Matrix(1f, 0f, 0f, 1f, translateMx.X, translateMx.Y))
using (var brush = new LinearGradientBrush(display, startColor, endColor, rotation)) {
var colorBlend = new ColorBlend(blendColors.Length) {
Colors = blendColors,
Positions = new float[] { .0f, .25f + theta, .5f + theta, .75f + theta, 1.0f },
};
brush.InterpolationColors = colorBlend;
mx.Rotate(rotation);
brush.Transform = mx;
if (useTriangular) brush.SetBlendTriangularShape(.5f, tringularShift);
e.Graphics.FillRectangle(brush, display);
}
base.OnPaint(e);
}
protected override void OnFormClosing(FormClosingEventArgs e) {
// Move to OnFormClosed() if this action can be canceled
gradientTimer.Stop();
base.OnFormClosing(e);
}
}
由于尺寸原因,我无法在此处发布动画。 你可以直接在 Imgur 上看到它是如何工作的:
动画线性渐变路径
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.