Skip to content

Commit 63b9ad0

Browse files
authored
Fixed gradient brush offset for rectangle geometry (#497)
1 parent 3c1e744 commit 63b9ad0

File tree

4 files changed

+42
-13
lines changed

4 files changed

+42
-13
lines changed

source/LottieToWinComp/Brushes.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,11 @@ static CompositionColorBrush TranslateBoundSolidColor(
439439
// so that its value can be used in expression animation of property itself.
440440
string sourcePropertyName = propertyName + "Source";
441441
obj.Properties.InsertVector2(sourcePropertyName, ConvertTo.Vector2(value.InitialValue));
442-
Animate.Vector2(context, value, obj, sourcePropertyName);
442+
443+
if (value.IsAnimated)
444+
{
445+
Animate.Vector2(context, value, obj, sourcePropertyName);
446+
}
443447

444448
// Create expression that offsets source property by origin offset.
445449
WinCompData.Expressions.Vector2 expression = offset.IsAnimated ?
@@ -518,10 +522,13 @@ static CompositionColorBrush TranslateBoundSolidColor(
518522
var startPoint = Optimizer.TrimAnimatable(context, gradient.StartPoint);
519523
var endPoint = Optimizer.TrimAnimatable(context, gradient.EndPoint);
520524

521-
var startPointValue = AnimateVector2WithOriginOffsetOrGetValue(context, result, nameof(result.EllipseCenter), startPoint);
522-
if (startPointValue is not null)
525+
if (startPoint.IsAnimated)
526+
{
527+
Animate.Vector2(context, startPoint, result, nameof(result.EllipseCenter));
528+
}
529+
else
523530
{
524-
result.EllipseCenter = startPointValue!;
531+
result.EllipseCenter = ConvertTo.Vector2(startPoint.InitialValue);
525532
}
526533

527534
if (endPoint.IsAnimated)

source/LottieToWinComp/ExpressionFactory.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ static class ExpressionFactory
3434
internal static readonly Scalar MaxTStartTEnd = Max(MyTStart, MyTEnd);
3535
internal static readonly Scalar MinTStartTEnd = Min(MyTStart, MyTEnd);
3636
internal static readonly Vector2 HalfMySize = MySize / Vector2(2, 2);
37-
internal static readonly Vector2 GeometryHalfSize = NamedVector2("geometry", "Size") / Vector2(2, 2);
37+
internal static readonly Vector2 GeometryOffset = NamedVector2("geometry", "Offset");
38+
internal static readonly Vector2 GeometryPosition = NamedVector2("geometry", "Position");
3839
internal static readonly Color AnimatedColorWithAnimatedOpacity =
3940
ColorAsVector4MultipliedByOpacities(MyColor, new[] { MyOpacity });
4041

source/LottieToWinComp/Rectangles.cs

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -319,10 +319,7 @@ static void ApplyRectangleContentCommon(
319319
var height = size.InitialValue.Y;
320320
var trimOffsetDegrees = (width / (2 * (width + height))) * 360;
321321

322-
// If offset is not animated then other computations for fill brush can be optimized.
323-
context.LayerContext.OriginOffset = size.IsAnimated ?
324-
new OriginOffsetContainer(geometry, ExpressionFactory.GeometryHalfSize) :
325-
new OriginOffsetContainer(geometry, ConvertTo.Vector2(size.InitialValue / 2));
322+
context.LayerContext.OriginOffset = GetOriginOffsetContainer(geometry, size, position);
326323

327324
Shapes.TranslateAndApplyShapeContextWithTrimOffset(
328325
context,
@@ -414,10 +411,7 @@ static void ApplyRectangleContentCommonXY(
414411
var initialHeight = height.InitialValue;
415412
var trimOffsetDegrees = (initialWidth / (2 * (initialWidth + initialHeight))) * 360;
416413

417-
// If offset is not animated then other computations for fill brush can be optimized.
418-
context.LayerContext.OriginOffset = width.IsAnimated || height.IsAnimated ?
419-
new OriginOffsetContainer(geometry, ExpressionFactory.GeometryHalfSize) :
420-
new OriginOffsetContainer(geometry, ConvertTo.Vector2(width.InitialValue / 2, height.InitialValue / 2));
414+
context.LayerContext.OriginOffset = GetOriginOffsetContainerXY(geometry, width, height, position);
421415

422416
Shapes.TranslateAndApplyShapeContextWithTrimOffset(
423417
context,
@@ -429,6 +423,31 @@ static void ApplyRectangleContentCommonXY(
429423
compositionRectangle.Geometry.SetDescription(context, () => $"{rectangle.Name}.RectangleGeometry");
430424
}
431425

426+
static OriginOffsetContainer GetOriginOffsetContainer(
427+
RectangleOrRoundedRectangleGeometry geometry,
428+
in TrimmedAnimatable<Vector3> size,
429+
in TrimmedAnimatable<Vector3> position)
430+
{
431+
// Note: Current implementation of Windows Composition API behaves differently for Rounded Rectangle and regular Rectangle geometry.
432+
// In first case we need to offset the inner content (e.g. gradient) by position only, and in second case by position and half the size (total offset).
433+
return size.IsAnimated || position.IsAnimated ?
434+
new OriginOffsetContainer(geometry, -(geometry.IsRoundedRectangle ? ExpressionFactory.GeometryPosition : ExpressionFactory.GeometryOffset)) :
435+
new OriginOffsetContainer(geometry, -(geometry.IsRoundedRectangle ? ConvertTo.Vector2(position.InitialValue) : InitialOffset(size, position)));
436+
}
437+
438+
static OriginOffsetContainer GetOriginOffsetContainerXY(
439+
RectangleOrRoundedRectangleGeometry geometry,
440+
in TrimmedAnimatable<double> width,
441+
in TrimmedAnimatable<double> height,
442+
in TrimmedAnimatable<Vector3> position)
443+
{
444+
// Note: Current implementation of Windows Composition API behaves differently for Rounded Rectangle and regular Rectangle geometry.
445+
// In first case we need to offset the inner content (e.g. gradient) by position only, and in second case by position and half the size (total offset).
446+
return width.IsAnimated || height.IsAnimated || position.IsAnimated ?
447+
new OriginOffsetContainer(geometry, -(geometry.IsRoundedRectangle ? ExpressionFactory.GeometryPosition : ExpressionFactory.GeometryOffset)) :
448+
new OriginOffsetContainer(geometry, -(geometry.IsRoundedRectangle ? ConvertTo.Vector2(position.InitialValue) : InitialOffset(width, height, position)));
449+
}
450+
432451
public static CanvasGeometry CreateWin2dRectangleGeometry(
433452
ShapeContext context,
434453
Rectangle rectangle)

source/WinCompData/Expressions/Vector2.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ protected Vector2()
2121

2222
public static Vector2 operator -(Vector2 left, Vector2 right) => new Subtract(left, right);
2323

24+
public static Vector2 operator -(Vector2 value) => new Subtract(Vector2(0, 0), value);
25+
2426
public static Vector2 operator +(Vector2 left, Vector2 right) => new Add(left, right);
2527

2628
public static Vector2 operator *(Scalar left, Vector2 right) => new ScalarMultiply(left, right);

0 commit comments

Comments
 (0)