Made some changes + comments cleanup as discussed
This commit is contained in:
Родитель
e27c69f60f
Коммит
04cd5fe11a
|
@ -168,7 +168,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.LottieToWinComp
|
|||
ApplyCommonStrokeProperties(
|
||||
context,
|
||||
shapeStroke,
|
||||
TranslateLinearGradient(context, shapeStroke, contextOpacity, null),
|
||||
TranslateLinearGradient(context, shapeStroke, contextOpacity),
|
||||
sprite);
|
||||
}
|
||||
|
||||
|
@ -181,7 +181,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.LottieToWinComp
|
|||
ApplyCommonStrokeProperties(
|
||||
context,
|
||||
shapeStroke,
|
||||
TranslateRadialGradient(context, shapeStroke, contextOpacity, null),
|
||||
TranslateRadialGradient(context, shapeStroke, contextOpacity),
|
||||
sprite);
|
||||
}
|
||||
|
||||
|
@ -258,7 +258,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.LottieToWinComp
|
|||
LayerContext context,
|
||||
ShapeFill? shapeFill,
|
||||
CompositeOpacity opacity,
|
||||
Rectangles.InternalOffset? internalOffset)
|
||||
Rectangles.OriginOffset? originOffset)
|
||||
{
|
||||
if (shapeFill is null)
|
||||
{
|
||||
|
@ -267,9 +267,12 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.LottieToWinComp
|
|||
|
||||
return shapeFill.FillKind switch
|
||||
{
|
||||
ShapeFill.ShapeFillKind.SolidColor => TranslateSolidColorFill(context, (SolidColorFill)shapeFill, opacity),
|
||||
ShapeFill.ShapeFillKind.LinearGradient => TranslateLinearGradient(context, (LinearGradientFill)shapeFill, opacity, internalOffset),
|
||||
ShapeFill.ShapeFillKind.RadialGradient => TranslateRadialGradient(context, (RadialGradientFill)shapeFill, opacity, internalOffset),
|
||||
ShapeFill.ShapeFillKind.SolidColor =>
|
||||
TranslateSolidColorFill(context, (SolidColorFill)shapeFill, opacity),
|
||||
ShapeFill.ShapeFillKind.LinearGradient =>
|
||||
TranslateLinearGradient(context, (LinearGradientFill)shapeFill, opacity, originOffset),
|
||||
ShapeFill.ShapeFillKind.RadialGradient =>
|
||||
TranslateRadialGradient(context, (RadialGradientFill)shapeFill, opacity, originOffset),
|
||||
_ => throw new InvalidOperationException(),
|
||||
};
|
||||
}
|
||||
|
@ -410,40 +413,64 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.LottieToWinComp
|
|||
return result;
|
||||
}
|
||||
|
||||
static void TranslateVector2AnimatableWithInternalOffset(
|
||||
// Animate Vector2 property of object with TrimmedAnimatable while applying OriginOffset to it.
|
||||
// Returns non-null Sn.Vector2 value if no animation is needed (and no animation was applied).
|
||||
static Sn.Vector2? AnimateVector2WithOriginOffsetOrGetValue(
|
||||
LayerContext context,
|
||||
CompositionObject obj,
|
||||
string propertyName,
|
||||
TrimmedAnimatable<Vector2> value,
|
||||
Rectangles.InternalOffset offset)
|
||||
Rectangles.OriginOffset? offset)
|
||||
{
|
||||
// anomate source property first
|
||||
if (offset is null)
|
||||
{
|
||||
if (value.IsAnimated)
|
||||
{
|
||||
Animate.Vector2(context, value, obj, propertyName);
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ConvertTo.Vector2(value.InitialValue);
|
||||
}
|
||||
}
|
||||
|
||||
if (!offset.IsAnimated && !value.IsAnimated)
|
||||
{
|
||||
return ConvertTo.Vector2(value.InitialValue) + offset.OffsetValue!;
|
||||
}
|
||||
|
||||
// Animate source property first.
|
||||
// We are using this auxiliary property to store original animation,
|
||||
// so that its value can be used in expression animation of property itself.
|
||||
string sourcePropertyName = propertyName + "Source";
|
||||
obj.Properties.InsertVector2(sourcePropertyName, ConvertTo.Vector2(value.InitialValue));
|
||||
Animate.Vector2(context, value, obj, sourcePropertyName);
|
||||
|
||||
// create expression that offsets source property by internal offset
|
||||
// Create expression that offsets source property by origin offset.
|
||||
WinCompData.Expressions.Vector2 expression = offset.IsAnimated ?
|
||||
ExpressionFactory.InternalOffsetExressionAdded(sourcePropertyName, offset.OffsetExpression!) :
|
||||
ExpressionFactory.InternalOffsetValueAdded(sourcePropertyName, (Sn.Vector2)offset.OffsetValue!);
|
||||
ExpressionFactory.OriginOffsetExressionAdded(sourcePropertyName, offset.OffsetExpression!) :
|
||||
ExpressionFactory.OriginOffsetValueAdded(sourcePropertyName, (Sn.Vector2)offset.OffsetValue!);
|
||||
|
||||
var expressionAnimation = context.ObjectFactory.CreateExpressionAnimation(expression);
|
||||
expressionAnimation.SetReferenceParameter("my", obj);
|
||||
if (offset.IsAnimated)
|
||||
{
|
||||
// expression can use geometry
|
||||
// Expression can use geometry.
|
||||
expressionAnimation.SetReferenceParameter("geometry", offset.Geometry);
|
||||
}
|
||||
|
||||
// animate original property with expression that applies internal offset to it
|
||||
// Animate original property with expression that applies origin offset to it.
|
||||
Animate.WithExpression(obj, expressionAnimation, propertyName);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static CompositionLinearGradientBrush? TranslateLinearGradient(
|
||||
LayerContext context,
|
||||
IGradient linearGradient,
|
||||
CompositeOpacity opacity,
|
||||
Rectangles.InternalOffset? internalOffset)
|
||||
Rectangles.OriginOffset? originOffset = null)
|
||||
{
|
||||
var result = context.ObjectFactory.CreateLinearGradientBrush();
|
||||
|
||||
|
@ -453,30 +480,16 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.LottieToWinComp
|
|||
var startPoint = Optimizer.TrimAnimatable(context, linearGradient.StartPoint);
|
||||
var endPoint = Optimizer.TrimAnimatable(context, linearGradient.EndPoint);
|
||||
|
||||
if (internalOffset is not null)
|
||||
var startPointValue = AnimateVector2WithOriginOffsetOrGetValue(context, result, nameof(result.StartPoint), startPoint, originOffset);
|
||||
if (startPointValue is not null)
|
||||
{
|
||||
TranslateVector2AnimatableWithInternalOffset(context, result, nameof(result.StartPoint), startPoint, internalOffset);
|
||||
}
|
||||
else if (startPoint.IsAnimated)
|
||||
{
|
||||
Animate.Vector2(context, startPoint, result, nameof(result.StartPoint));
|
||||
}
|
||||
else
|
||||
{
|
||||
result.StartPoint = ConvertTo.Vector2(startPoint.InitialValue);
|
||||
result.StartPoint = startPointValue!;
|
||||
}
|
||||
|
||||
if (internalOffset is not null)
|
||||
var endPointValue = AnimateVector2WithOriginOffsetOrGetValue(context, result, nameof(result.EndPoint), endPoint, originOffset);
|
||||
if (endPointValue is not null)
|
||||
{
|
||||
TranslateVector2AnimatableWithInternalOffset(context, result, nameof(result.EndPoint), endPoint, internalOffset);
|
||||
}
|
||||
else if (endPoint.IsAnimated)
|
||||
{
|
||||
Animate.Vector2(context, endPoint, result, nameof(result.EndPoint));
|
||||
}
|
||||
else
|
||||
{
|
||||
result.EndPoint = ConvertTo.Vector2(endPoint.InitialValue);
|
||||
result.EndPoint = endPointValue!;
|
||||
}
|
||||
|
||||
var gradientStops = Optimizer.TrimAnimatable(context, linearGradient.GradientStops);
|
||||
|
@ -496,13 +509,13 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.LottieToWinComp
|
|||
LayerContext context,
|
||||
IRadialGradient gradient,
|
||||
CompositeOpacity opacity,
|
||||
Rectangles.InternalOffset? internalOffset)
|
||||
Rectangles.OriginOffset? originOffset = null)
|
||||
{
|
||||
if (!context.ObjectFactory.IsUapApiAvailable(nameof(CompositionRadialGradientBrush), versionDependentFeatureDescription: "Radial gradient fill"))
|
||||
{
|
||||
// CompositionRadialGradientBrush didn't exist until UAP v8. If the target OS doesn't support
|
||||
// UAP v8 then fall back to linear gradients as a compromise.
|
||||
return TranslateLinearGradient(context, gradient, opacity, internalOffset);
|
||||
return TranslateLinearGradient(context, gradient, opacity, originOffset);
|
||||
}
|
||||
|
||||
var result = context.ObjectFactory.CreateRadialGradientBrush();
|
||||
|
@ -513,17 +526,10 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.LottieToWinComp
|
|||
var startPoint = Optimizer.TrimAnimatable(context, gradient.StartPoint);
|
||||
var endPoint = Optimizer.TrimAnimatable(context, gradient.EndPoint);
|
||||
|
||||
if (internalOffset is not null)
|
||||
var startPointValue = AnimateVector2WithOriginOffsetOrGetValue(context, result, nameof(result.EllipseCenter), startPoint, originOffset);
|
||||
if (startPointValue is not null)
|
||||
{
|
||||
TranslateVector2AnimatableWithInternalOffset(context, result, nameof(result.EllipseCenter), startPoint, internalOffset);
|
||||
}
|
||||
else if (startPoint.IsAnimated)
|
||||
{
|
||||
Animate.Vector2(context, startPoint, result, nameof(result.EllipseCenter));
|
||||
}
|
||||
else
|
||||
{
|
||||
result.EllipseCenter = ConvertTo.Vector2(startPoint.InitialValue);
|
||||
result.EllipseCenter = startPointValue!;
|
||||
}
|
||||
|
||||
if (endPoint.IsAnimated)
|
||||
|
|
|
@ -47,9 +47,9 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.LottieToWinComp
|
|||
MyPosition.Y - MyAnchor.Y,
|
||||
0);
|
||||
|
||||
internal static Vector2 InternalOffsetExressionAdded(string property, Vector2 offsetExpression) => MyVector2(property) + offsetExpression;
|
||||
internal static Vector2 OriginOffsetExressionAdded(string property, Vector2 offsetExpression) => MyVector2(property) + offsetExpression;
|
||||
|
||||
internal static Vector2 InternalOffsetValueAdded(string property, Sn.Vector2 offsetValue) => MyVector2(property) + Vector2(offsetValue);
|
||||
internal static Vector2 OriginOffsetValueAdded(string property, Sn.Vector2 offsetValue) => MyVector2(property) + Vector2(offsetValue);
|
||||
|
||||
internal static Color ThemedColorMultipliedByOpacity(string bindingName, Animatables.Opacity opacity)
|
||||
=> ColorAsVector4MultipliedByOpacity(ThemedColor4Property(bindingName), opacity.Value);
|
||||
|
|
|
@ -21,31 +21,29 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.LottieToWinComp
|
|||
// Rectangles are implemented differently in WinComp API
|
||||
// and Lottie. In WinComp API coordinates inside rectangle start in
|
||||
// top left corner and in Lottie they start in the middle
|
||||
// To account for this we need to offset all the internal points
|
||||
// for (Rectangle.Size / 2)
|
||||
// To account for this we need to offset all the points inside
|
||||
// the rectangle for (Rectangle.Size / 2).
|
||||
// This class represents this offset (static or animated)
|
||||
public class InternalOffset
|
||||
public class OriginOffset
|
||||
{
|
||||
public RectangleOrRoundedRectangleGeometry Geometry { get; }
|
||||
|
||||
// Use expression if size is animated
|
||||
#nullable enable
|
||||
public Expressions.Vector2? OffsetExpression { get; }
|
||||
#nullable disable
|
||||
|
||||
// Use constant value if size if static
|
||||
public Sn.Vector2? OffsetValue { get; }
|
||||
|
||||
public bool IsAnimated => OffsetExpression is not null;
|
||||
public bool IsAnimated => OffsetValue is null;
|
||||
|
||||
public InternalOffset(RectangleOrRoundedRectangleGeometry geometry, Expressions.Vector2 expression)
|
||||
public OriginOffset(RectangleOrRoundedRectangleGeometry geometry, Expressions.Vector2 expression)
|
||||
{
|
||||
Geometry = geometry;
|
||||
OffsetExpression = expression;
|
||||
OffsetValue = null;
|
||||
}
|
||||
|
||||
public InternalOffset(RectangleOrRoundedRectangleGeometry geometry, Sn.Vector2 value)
|
||||
public OriginOffset(RectangleOrRoundedRectangleGeometry geometry, Sn.Vector2 value)
|
||||
{
|
||||
Geometry = geometry;
|
||||
OffsetExpression = null;
|
||||
|
@ -353,15 +351,16 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.LottieToWinComp
|
|||
var height = size.InitialValue.Y;
|
||||
var trimOffsetDegrees = (width / (2 * (width + height))) * 360;
|
||||
|
||||
InternalOffset internalOffset = size.IsAnimated ?
|
||||
new InternalOffset(geometry, ExpressionFactory.GeometryHalfSize) :
|
||||
new InternalOffset(geometry, ConvertTo.Vector2(size.InitialValue / 2));
|
||||
// If offset is not animated then other computations for fill brush can be optimized.
|
||||
OriginOffset originOffset = size.IsAnimated ?
|
||||
new OriginOffset(geometry, ExpressionFactory.GeometryHalfSize) :
|
||||
new OriginOffset(geometry, ConvertTo.Vector2(size.InitialValue / 2));
|
||||
|
||||
Shapes.TranslateAndApplyShapeContextWithTrimOffset(
|
||||
context,
|
||||
compositionRectangle,
|
||||
rectangle.DrawingDirection == DrawingDirection.Reverse,
|
||||
internalOffset,
|
||||
originOffset,
|
||||
trimOffsetDegrees: trimOffsetDegrees);
|
||||
|
||||
compositionRectangle.SetDescription(context, () => rectangle.Name);
|
||||
|
@ -448,15 +447,16 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.LottieToWinComp
|
|||
var initialHeight = height.InitialValue;
|
||||
var trimOffsetDegrees = (initialWidth / (2 * (initialWidth + initialHeight))) * 360;
|
||||
|
||||
InternalOffset internalOffset = width.IsAnimated || height.IsAnimated ?
|
||||
new InternalOffset(geometry, ExpressionFactory.GeometryHalfSize) :
|
||||
new InternalOffset(geometry, ConvertTo.Vector2(width.InitialValue / 2, height.InitialValue / 2));
|
||||
// If offset is not animated then other computations for fill brush can be optimized.
|
||||
OriginOffset originOffset = width.IsAnimated || height.IsAnimated ?
|
||||
new OriginOffset(geometry, ExpressionFactory.GeometryHalfSize) :
|
||||
new OriginOffset(geometry, ConvertTo.Vector2(width.InitialValue / 2, height.InitialValue / 2));
|
||||
|
||||
Shapes.TranslateAndApplyShapeContextWithTrimOffset(
|
||||
context,
|
||||
compositionRectangle,
|
||||
rectangle.DrawingDirection == DrawingDirection.Reverse,
|
||||
internalOffset,
|
||||
originOffset,
|
||||
trimOffsetDegrees: trimOffsetDegrees);
|
||||
|
||||
compositionRectangle.SetDescription(context, () => rectangle.Name);
|
||||
|
|
|
@ -34,18 +34,23 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.LottieToWinComp
|
|||
ShapeContext context,
|
||||
CompositionSpriteShape shape,
|
||||
bool reverseDirection) =>
|
||||
TranslateAndApplyShapeContextWithTrimOffset(context, shape, reverseDirection, null, 0);
|
||||
TranslateAndApplyShapeContextWithTrimOffset(
|
||||
context,
|
||||
shape,
|
||||
reverseDirection,
|
||||
originOffset: null,
|
||||
trimOffsetDegrees: 0);
|
||||
|
||||
public static void TranslateAndApplyShapeContextWithTrimOffset(
|
||||
ShapeContext context,
|
||||
CompositionSpriteShape shape,
|
||||
bool reverseDirection,
|
||||
Rectangles.InternalOffset? internalOffset,
|
||||
Rectangles.OriginOffset? originOffset,
|
||||
double trimOffsetDegrees)
|
||||
{
|
||||
Debug.Assert(shape.Geometry is not null, "Precondition");
|
||||
|
||||
shape.FillBrush = Brushes.TranslateShapeFill(context, context.Fill, context.Opacity, internalOffset);
|
||||
shape.FillBrush = Brushes.TranslateShapeFill(context, context.Fill, context.Opacity, originOffset);
|
||||
Brushes.TranslateAndApplyStroke(context, context.Stroke, shape, context.Opacity);
|
||||
|
||||
TranslateAndApplyTrimPath(
|
||||
|
|
Загрузка…
Ссылка в новой задаче