mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Nodes - Added color gradient easing node
Color ramp node - Fixed 1 and multiples of 1 being treated as 0
This commit is contained in:
parent
147e050e69
commit
cbf2cd1736
@ -468,6 +468,8 @@ public class ColorGradient : IList<ColorGradientStop>, IList, INotifyCollectionC
|
||||
{
|
||||
_stops.Add(item);
|
||||
item.ColorGradient = this;
|
||||
// Update the position, reapplying the overlap-check in Position's setter
|
||||
item.Position = item.Position;
|
||||
item.PropertyChanged += ItemOnPropertyChanged;
|
||||
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, _stops.IndexOf(item)));
|
||||
@ -624,4 +626,36 @@ public class ColorGradient : IList<ColorGradientStop>, IList, INotifyCollectionC
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public ColorGradient Interpolate(ColorGradient targetValue, float progress)
|
||||
{
|
||||
ColorGradient interpolated = new(this);
|
||||
|
||||
// Add new stops
|
||||
if (targetValue.Count > interpolated.Count)
|
||||
{
|
||||
// Prefer the stops on a vacant position
|
||||
foreach (ColorGradientStop stop in targetValue.Take(targetValue.Count - interpolated.Count))
|
||||
interpolated.Add(new ColorGradientStop(GetColor(stop.Position), stop.Position));
|
||||
}
|
||||
// Interpolate stops
|
||||
int index = 0;
|
||||
foreach (ColorGradientStop stop in interpolated.ToList())
|
||||
{
|
||||
if (index < targetValue.Count)
|
||||
{
|
||||
ColorGradientStop targetStop = targetValue[index];
|
||||
stop.Interpolate(targetStop, progress);
|
||||
}
|
||||
// Interpolate stops not on the target gradient
|
||||
else
|
||||
{
|
||||
stop.Color = stop.Color.Interpolate(targetValue.GetColor(stop.Position), progress);
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
return interpolated;
|
||||
}
|
||||
}
|
||||
@ -95,4 +95,10 @@ public class ColorGradientStop : CorePropertyChanged
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void Interpolate(ColorGradientStop targetValue, float progress)
|
||||
{
|
||||
Color = Color.Interpolate(targetValue.Color, progress);
|
||||
Position = Position + ((targetValue.Position - Position) * progress);
|
||||
}
|
||||
}
|
||||
@ -237,7 +237,7 @@ public class LayerProperty<T> : CorePropertyChanged, ILayerProperty
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the base value of this layer property without any keyframes applied
|
||||
/// Gets or sets the base value of this layer property without any keyframes or data bindings applied
|
||||
/// </summary>
|
||||
public T BaseValue
|
||||
{
|
||||
|
||||
@ -22,7 +22,13 @@ public class RampSKColorNode : Node<ColorGradient, RampSKColorNodeCustomViewMode
|
||||
|
||||
public override void Evaluate()
|
||||
{
|
||||
Output.Value = Storage?.GetColor(Input.Value % 1.0) ?? SKColor.Empty;
|
||||
// Wrap the input between 0 and 1
|
||||
// 1 % 1 = 0, 2 % 1 = 0 etc. but we want that to be 1 but 0 should stay 0, call me stupid but this works and makes sense
|
||||
float value = Input.Value % 1;
|
||||
if (value == 0 && Input.Value != 0)
|
||||
value = 1;
|
||||
|
||||
Output.Value = Storage?.GetColor(value) ?? SKColor.Empty;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@ -0,0 +1,71 @@
|
||||
using Artemis.Core;
|
||||
|
||||
namespace Artemis.VisualScripting.Nodes.Easing;
|
||||
|
||||
[Node("Color Gradient Easing", "Outputs an eased color gradient value", "Easing", InputType = typeof(ColorGradient), OutputType = typeof(ColorGradient))]
|
||||
public class ColorGradientEasingNode : Node
|
||||
{
|
||||
private DateTime _lastEvaluate = DateTime.MinValue;
|
||||
private float _progress;
|
||||
private ColorGradient? _currentValue;
|
||||
private ColorGradient? _sourceValue;
|
||||
private ColorGradient? _targetValue;
|
||||
|
||||
public ColorGradientEasingNode()
|
||||
{
|
||||
Input = CreateInputPin<ColorGradient>();
|
||||
EasingTime = CreateInputPin<Numeric>("delay");
|
||||
EasingFunction = CreateInputPin<Easings.Functions>("function");
|
||||
|
||||
Output = CreateOutputPin<ColorGradient>();
|
||||
}
|
||||
|
||||
public InputPin<ColorGradient> Input { get; set; }
|
||||
public InputPin<Numeric> EasingTime { get; set; }
|
||||
public InputPin<Easings.Functions> EasingFunction { get; set; }
|
||||
|
||||
public OutputPin<ColorGradient> Output { get; set; }
|
||||
|
||||
public override void Evaluate()
|
||||
{
|
||||
DateTime now = DateTime.Now;
|
||||
|
||||
if (Input.Value == null)
|
||||
return;
|
||||
|
||||
// If the value changed reset progress
|
||||
if (!Equals(_targetValue, Input.Value))
|
||||
{
|
||||
_sourceValue = _currentValue ?? new ColorGradient(Input.Value);
|
||||
_targetValue = new ColorGradient(Input.Value);
|
||||
_progress = 0f;
|
||||
}
|
||||
|
||||
// Update until finished
|
||||
if (_progress < 1f)
|
||||
{
|
||||
Update();
|
||||
Output.Value = _currentValue;
|
||||
}
|
||||
// Stop updating past 1 and use the target value
|
||||
else
|
||||
{
|
||||
Output.Value = _targetValue;
|
||||
}
|
||||
|
||||
_lastEvaluate = now;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (_sourceValue == null || _targetValue == null)
|
||||
return;
|
||||
|
||||
float easingTime = EasingTime.Value != 0f ? EasingTime.Value : 1f;
|
||||
TimeSpan delta = DateTime.Now - _lastEvaluate;
|
||||
|
||||
// In case of odd delta's, keep progress between 0f and 1f
|
||||
_progress = Math.Clamp(_progress + (float) delta.TotalMilliseconds / easingTime, 0f, 1f);
|
||||
_currentValue = _sourceValue.Interpolate(_targetValue, (float) Easings.Interpolate(_progress, EasingFunction.Value));
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user