[英]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.