mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-31 09:43:46 +00:00
Added rotation
This commit is contained in:
parent
296a4f9d8b
commit
f8fc30ace2
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Artemis.Core.Exceptions;
|
using Artemis.Core.Exceptions;
|
||||||
using Artemis.Core.Extensions;
|
using Artemis.Core.Extensions;
|
||||||
@ -148,6 +149,17 @@ namespace Artemis.Core.Models.Profile
|
|||||||
|
|
||||||
public override void Update(double deltaTime)
|
public override void Update(double deltaTime)
|
||||||
{
|
{
|
||||||
|
foreach (var property in Properties)
|
||||||
|
{
|
||||||
|
property.KeyframeEngine?.Update(deltaTime);
|
||||||
|
// This is a placeholder method of repeating the animation until repeat modes are implemented
|
||||||
|
if (property.KeyframeEngine != null && property.IsUsingKeyframes && property.KeyframeEngine.NextKeyframe == null)
|
||||||
|
{
|
||||||
|
Debug.WriteLine($"Reset {property} progress");
|
||||||
|
property.KeyframeEngine.OverrideProgress(TimeSpan.Zero);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LayerBrush?.Update(deltaTime);
|
LayerBrush?.Update(deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,7 +201,7 @@ namespace Artemis.Core.Models.Profile
|
|||||||
}
|
}
|
||||||
|
|
||||||
var shader = SKShader.CreateSweepGradient(new SKPoint(LayerShape.RenderRectangle.MidX, LayerShape.RenderRectangle.MidY), testColors.ToArray());
|
var shader = SKShader.CreateSweepGradient(new SKPoint(LayerShape.RenderRectangle.MidX, LayerShape.RenderRectangle.MidY), testColors.ToArray());
|
||||||
canvas.DrawPath(LayerShape.RenderPath, new SKPaint {Shader = shader, Color = new SKColor(0, 0, 0, (byte) (OpacityProperty.CurrentValue * 2.55f)) });
|
canvas.DrawPath(LayerShape.RenderPath, new SKPaint {Shader = shader, Color = new SKColor(0, 0, 0, (byte) (OpacityProperty.CurrentValue * 2.55f))});
|
||||||
}
|
}
|
||||||
|
|
||||||
LayerBrush?.Render(canvas);
|
LayerBrush?.Render(canvas);
|
||||||
@ -200,7 +212,7 @@ namespace Artemis.Core.Models.Profile
|
|||||||
{
|
{
|
||||||
if (LayerShape == null)
|
if (LayerShape == null)
|
||||||
return SKPoint.Empty;
|
return SKPoint.Empty;
|
||||||
|
|
||||||
if (!absolute)
|
if (!absolute)
|
||||||
{
|
{
|
||||||
var anchor = AnchorPointProperty.CurrentValue;
|
var anchor = AnchorPointProperty.CurrentValue;
|
||||||
|
|||||||
@ -33,7 +33,7 @@ namespace Artemis.Core.Services
|
|||||||
_surfaceService = surfaceService;
|
_surfaceService = surfaceService;
|
||||||
_rgbService.Surface.Updating += SurfaceOnUpdating;
|
_rgbService.Surface.Updating += SurfaceOnUpdating;
|
||||||
_rgbService.Surface.Updated += SurfaceOnUpdated;
|
_rgbService.Surface.Updated += SurfaceOnUpdated;
|
||||||
|
|
||||||
_modules = _pluginService.GetPluginsOfType<Module>();
|
_modules = _pluginService.GetPluginsOfType<Module>();
|
||||||
_pluginService.PluginEnabled += (sender, args) => _modules = _pluginService.GetPluginsOfType<Module>();
|
_pluginService.PluginEnabled += (sender, args) => _modules = _pluginService.GetPluginsOfType<Module>();
|
||||||
_pluginService.PluginDisabled += (sender, args) => _modules = _pluginService.GetPluginsOfType<Module>();
|
_pluginService.PluginDisabled += (sender, args) => _modules = _pluginService.GetPluginsOfType<Module>();
|
||||||
|
|||||||
@ -61,6 +61,12 @@
|
|||||||
<Button Style="{StaticResource MaterialDesignIconForegroundButton}" ToolTip="Next frame" Command="{s:Action GoToNextFrame}" Focusable="False">
|
<Button Style="{StaticResource MaterialDesignIconForegroundButton}" ToolTip="Next frame" Command="{s:Action GoToNextFrame}" Focusable="False">
|
||||||
<materialDesign:PackIcon Kind="SkipNext" />
|
<materialDesign:PackIcon Kind="SkipNext" />
|
||||||
</Button>
|
</Button>
|
||||||
|
<ToggleButton Style="{StaticResource MaterialDesignFlatToggleButton}"
|
||||||
|
ToolTip="Repeat after last keyframe"
|
||||||
|
IsChecked="{Binding RepeatAfterLastKeyframe}"
|
||||||
|
Focusable="False">
|
||||||
|
<materialDesign:PackIcon Kind="Repeat" Height="24" Width="24" />
|
||||||
|
</ToggleButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<StackPanel VerticalAlignment="Center">
|
<StackPanel VerticalAlignment="Center">
|
||||||
<TextBlock Style="{StaticResource MaterialDesignHeadline6TextBlock}" Text="{Binding FormattedCurrentTime}" HorizontalAlignment="Right" Margin="0 0 20 0" />
|
<TextBlock Style="{StaticResource MaterialDesignHeadline6TextBlock}" Text="{Binding FormattedCurrentTime}" HorizontalAlignment="Right" Margin="0 0 20 0" />
|
||||||
|
|||||||
@ -45,7 +45,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
|
|||||||
}
|
}
|
||||||
|
|
||||||
public bool Playing { get; set; }
|
public bool Playing { get; set; }
|
||||||
|
public bool RepeatAfterLastKeyframe { get; set; }
|
||||||
public string FormattedCurrentTime => $"{Math.Floor(_profileEditorService.CurrentTime.TotalSeconds):00}.{_profileEditorService.CurrentTime.Milliseconds:000}";
|
public string FormattedCurrentTime => $"{Math.Floor(_profileEditorService.CurrentTime.TotalSeconds):00}.{_profileEditorService.CurrentTime.Milliseconds:000}";
|
||||||
|
|
||||||
public int PixelsPerSecond
|
public int PixelsPerSecond
|
||||||
@ -173,7 +173,12 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
|
|||||||
Execute.PostToUIThread(() =>
|
Execute.PostToUIThread(() =>
|
||||||
{
|
{
|
||||||
var newTime = _profileEditorService.CurrentTime.Add(TimeSpan.FromSeconds(e.DeltaTime));
|
var newTime = _profileEditorService.CurrentTime.Add(TimeSpan.FromSeconds(e.DeltaTime));
|
||||||
if (newTime > CalculateEndTime())
|
if (RepeatAfterLastKeyframe)
|
||||||
|
{
|
||||||
|
if (newTime > CalculateEndTime().Subtract(TimeSpan.FromSeconds(10)))
|
||||||
|
newTime = TimeSpan.Zero;
|
||||||
|
}
|
||||||
|
else if (newTime > CalculateEndTime())
|
||||||
{
|
{
|
||||||
newTime = CalculateEndTime();
|
newTime = CalculateEndTime();
|
||||||
Pause();
|
Pause();
|
||||||
|
|||||||
@ -19,28 +19,28 @@
|
|||||||
Canvas.Left="{Binding TopLeft.X}"
|
Canvas.Left="{Binding TopLeft.X}"
|
||||||
Canvas.Top="{Binding TopLeft.Y}"
|
Canvas.Top="{Binding TopLeft.Y}"
|
||||||
Fill="Transparent"
|
Fill="Transparent"
|
||||||
MouseDown="{s:Action ShapeEditMouseDown}" MouseUp="{s:Action ShapeEditMouseUp}" MouseMove="{s:Action TopLeftRotate}" Cursor="Cross" />
|
MouseDown="{s:Action ShapeEditMouseDown}" MouseUp="{s:Action ShapeEditMouseUp}" MouseMove="{s:Action Rotate}" Cursor="Cross" />
|
||||||
<Ellipse Width="{Binding RotateSize}"
|
<Ellipse Width="{Binding RotateSize}"
|
||||||
Height="{Binding RotateSize}"
|
Height="{Binding RotateSize}"
|
||||||
Margin="{Binding RotateOffset}"
|
Margin="{Binding RotateOffset}"
|
||||||
Canvas.Left="{Binding TopRight.X}"
|
Canvas.Left="{Binding TopRight.X}"
|
||||||
Canvas.Top="{Binding TopRight.Y}"
|
Canvas.Top="{Binding TopRight.Y}"
|
||||||
Fill="Transparent"
|
Fill="Transparent"
|
||||||
MouseDown="{s:Action ShapeEditMouseDown}" MouseUp="{s:Action ShapeEditMouseUp}" MouseMove="{s:Action TopRightRotate}" Cursor="Cross" />
|
MouseDown="{s:Action ShapeEditMouseDown}" MouseUp="{s:Action ShapeEditMouseUp}" MouseMove="{s:Action Rotate}" Cursor="Cross" />
|
||||||
<Ellipse Width="{Binding RotateSize}"
|
<Ellipse Width="{Binding RotateSize}"
|
||||||
Height="{Binding RotateSize}"
|
Height="{Binding RotateSize}"
|
||||||
Margin="{Binding RotateOffset}"
|
Margin="{Binding RotateOffset}"
|
||||||
Canvas.Left="{Binding BottomRight.X}"
|
Canvas.Left="{Binding BottomRight.X}"
|
||||||
Canvas.Top="{Binding BottomRight.Y}"
|
Canvas.Top="{Binding BottomRight.Y}"
|
||||||
Fill="Transparent"
|
Fill="Transparent"
|
||||||
MouseDown="{s:Action ShapeEditMouseDown}" MouseUp="{s:Action ShapeEditMouseUp}" MouseMove="{s:Action BottomRightRotate}" Cursor="Cross" />
|
MouseDown="{s:Action ShapeEditMouseDown}" MouseUp="{s:Action ShapeEditMouseUp}" MouseMove="{s:Action Rotate}" Cursor="Cross" />
|
||||||
<Ellipse Width="{Binding RotateSize}"
|
<Ellipse Width="{Binding RotateSize}"
|
||||||
Height="{Binding RotateSize}"
|
Height="{Binding RotateSize}"
|
||||||
Margin="{Binding RotateOffset}"
|
Margin="{Binding RotateOffset}"
|
||||||
Canvas.Left="{Binding BottomLeft.X}"
|
Canvas.Left="{Binding BottomLeft.X}"
|
||||||
Canvas.Top="{Binding BottomLeft.Y}"
|
Canvas.Top="{Binding BottomLeft.Y}"
|
||||||
Fill="Transparent"
|
Fill="Transparent"
|
||||||
MouseDown="{s:Action ShapeEditMouseDown}" MouseUp="{s:Action ShapeEditMouseUp}" MouseMove="{s:Action BottomLeftRotate}" Cursor="Cross" />
|
MouseDown="{s:Action ShapeEditMouseDown}" MouseUp="{s:Action ShapeEditMouseUp}" MouseMove="{s:Action Rotate}" Cursor="Cross" />
|
||||||
<!-- The part of the layer's shape that is inside the layer -->
|
<!-- The part of the layer's shape that is inside the layer -->
|
||||||
<Path Data="{Binding ShapeGeometry, Mode=OneWay}"
|
<Path Data="{Binding ShapeGeometry, Mode=OneWay}"
|
||||||
Fill="Transparent"
|
Fill="Transparent"
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
@ -19,6 +20,8 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
|
|||||||
private SKPoint _dragOffset;
|
private SKPoint _dragOffset;
|
||||||
private SKPoint _dragStart;
|
private SKPoint _dragStart;
|
||||||
private SKPoint _dragStartAnchor;
|
private SKPoint _dragStartAnchor;
|
||||||
|
private double _dragStartAngle;
|
||||||
|
private double _dragAngleOffset;
|
||||||
private SKSize _dragStartScale;
|
private SKSize _dragStartScale;
|
||||||
private bool _isDragging;
|
private bool _isDragging;
|
||||||
|
|
||||||
@ -108,7 +111,8 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
|
|||||||
// The path starts at 0,0 so there's no simple way to get the position relative to the top-left of the path
|
// The path starts at 0,0 so there's no simple way to get the position relative to the top-left of the path
|
||||||
_dragStart = GetRelativePosition(sender, e).ToSKPoint();
|
_dragStart = GetRelativePosition(sender, e).ToSKPoint();
|
||||||
_dragStartScale = layer.SizeProperty.CurrentValue;
|
_dragStartScale = layer.SizeProperty.CurrentValue;
|
||||||
|
_dragStartAngle = layer.RotationProperty.CurrentValue;
|
||||||
|
_dragAngleOffset = _dragStartAngle - CalculateAngle(_layerEditorService.GetLayerAnchor(layer, true), _dragStart);
|
||||||
// Store the original position and do a test to figure out the mouse offset
|
// Store the original position and do a test to figure out the mouse offset
|
||||||
var originalPosition = layer.PositionProperty.CurrentValue;
|
var originalPosition = layer.PositionProperty.CurrentValue;
|
||||||
var scaledDragStart = _layerEditorService.GetScaledPoint(layer, _dragStart, true);
|
var scaledDragStart = _layerEditorService.GetScaledPoint(layer, _dragStart, true);
|
||||||
@ -350,10 +354,20 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
|
|||||||
|
|
||||||
#region Rotation
|
#region Rotation
|
||||||
|
|
||||||
public void TopLeftRotate(object sender, MouseEventArgs e)
|
public void Rotate(object sender, MouseEventArgs e)
|
||||||
{
|
{
|
||||||
if (!_isDragging || !(ProfileEditorService.SelectedProfileElement is Layer layer))
|
if (!_isDragging || !(ProfileEditorService.SelectedProfileElement is Layer layer))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
var newRotation = CalculateAngle(_layerEditorService.GetLayerAnchor(layer, true), GetRelativePosition(sender, e).ToSKPoint()) + _dragAngleOffset;
|
||||||
|
if (newRotation < 0)
|
||||||
|
newRotation = 360 + newRotation;
|
||||||
|
|
||||||
|
var current = layer.RotationProperty.CurrentValue;
|
||||||
|
|
||||||
|
layer.RotationProperty.SetCurrentValue((int) Math.Round(newRotation, MidpointRounding.AwayFromZero), ProfileEditorService.CurrentTime);
|
||||||
|
Debug.WriteLine($"New rotation: {layer.RotationProperty.CurrentValue} Difference: {(layer.RotationProperty.CurrentValue - current)}");
|
||||||
|
ProfileEditorService.UpdateProfilePreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TopRightRotate(object sender, MouseEventArgs e)
|
public void TopRightRotate(object sender, MouseEventArgs e)
|
||||||
@ -445,6 +459,16 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
|
|||||||
return Math.Max(0.001f, _dragStartScale.Height + scaleToAdd);
|
return Math.Max(0.001f, _dragStartScale.Height + scaleToAdd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private double CalculateAngle(SKPoint start, SKPoint arrival)
|
||||||
|
{
|
||||||
|
var radian = Math.Atan2(start.Y - arrival.Y, start.X - arrival.X);
|
||||||
|
var angle = radian * (180 / Math.PI);
|
||||||
|
if (angle < 0.0)
|
||||||
|
angle += 360.0;
|
||||||
|
|
||||||
|
return angle;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user