@@ -168,7 +168,7 @@ static void TranslateAndApplyLinearGradientStroke(
168168 ApplyCommonStrokeProperties (
169169 context ,
170170 shapeStroke ,
171- TranslateLinearGradient ( context , shapeStroke , contextOpacity , null ) ,
171+ TranslateLinearGradient ( context , shapeStroke , contextOpacity ) ,
172172 sprite ) ;
173173 }
174174
@@ -181,7 +181,7 @@ static void TranslateAndApplyRadialGradientStroke(
181181 ApplyCommonStrokeProperties (
182182 context ,
183183 shapeStroke ,
184- TranslateRadialGradient ( context , shapeStroke , contextOpacity , null ) ,
184+ TranslateRadialGradient ( context , shapeStroke , contextOpacity ) ,
185185 sprite ) ;
186186 }
187187
@@ -258,7 +258,7 @@ static void ApplyCommonStrokeProperties(
258258 LayerContext context ,
259259 ShapeFill ? shapeFill ,
260260 CompositeOpacity opacity ,
261- Rectangles . InternalOffset ? internalOffset )
261+ Rectangles . OriginOffset ? originOffset )
262262 {
263263 if ( shapeFill is null )
264264 {
@@ -267,9 +267,12 @@ static void ApplyCommonStrokeProperties(
267267
268268 return shapeFill . FillKind switch
269269 {
270- ShapeFill . ShapeFillKind . SolidColor => TranslateSolidColorFill ( context , ( SolidColorFill ) shapeFill , opacity ) ,
271- ShapeFill . ShapeFillKind . LinearGradient => TranslateLinearGradient ( context , ( LinearGradientFill ) shapeFill , opacity , internalOffset ) ,
272- ShapeFill . ShapeFillKind . RadialGradient => TranslateRadialGradient ( context , ( RadialGradientFill ) shapeFill , opacity , internalOffset ) ,
270+ ShapeFill . ShapeFillKind . SolidColor =>
271+ TranslateSolidColorFill ( context , ( SolidColorFill ) shapeFill , opacity ) ,
272+ ShapeFill . ShapeFillKind . LinearGradient =>
273+ TranslateLinearGradient ( context , ( LinearGradientFill ) shapeFill , opacity , originOffset ) ,
274+ ShapeFill . ShapeFillKind . RadialGradient =>
275+ TranslateRadialGradient ( context , ( RadialGradientFill ) shapeFill , opacity , originOffset ) ,
273276 _ => throw new InvalidOperationException ( ) ,
274277 } ;
275278 }
@@ -410,40 +413,64 @@ static CompositionColorBrush TranslateBoundSolidColor(
410413 return result ;
411414 }
412415
413- static void TranslateVector2AnimatableWithInternalOffset (
416+ // Animate Vector2 property of object with TrimmedAnimatable while applying OriginOffset to it.
417+ // Returns non-null Sn.Vector2 value if no animation is needed (and no animation was applied).
418+ static Sn . Vector2 ? AnimateVector2WithOriginOffsetOrGetValue (
414419 LayerContext context ,
415420 CompositionObject obj ,
416421 string propertyName ,
417422 TrimmedAnimatable < Vector2 > value ,
418- Rectangles . InternalOffset offset )
423+ Rectangles . OriginOffset ? offset )
419424 {
420- // anomate source property first
425+ if ( offset is null )
426+ {
427+ if ( value . IsAnimated )
428+ {
429+ Animate . Vector2 ( context , value , obj , propertyName ) ;
430+ return null ;
431+ }
432+ else
433+ {
434+ return ConvertTo . Vector2 ( value . InitialValue ) ;
435+ }
436+ }
437+
438+ if ( ! offset . IsAnimated && ! value . IsAnimated )
439+ {
440+ return ConvertTo . Vector2 ( value . InitialValue ) + offset . OffsetValue ! ;
441+ }
442+
443+ // Animate source property first.
444+ // We are using this auxiliary property to store original animation,
445+ // so that its value can be used in expression animation of property itself.
421446 string sourcePropertyName = propertyName + "Source" ;
422447 obj . Properties . InsertVector2 ( sourcePropertyName , ConvertTo . Vector2 ( value . InitialValue ) ) ;
423448 Animate . Vector2 ( context , value , obj , sourcePropertyName ) ;
424449
425- // create expression that offsets source property by internal offset
450+ // Create expression that offsets source property by origin offset.
426451 WinCompData . Expressions . Vector2 expression = offset . IsAnimated ?
427- ExpressionFactory . InternalOffsetExressionAdded ( sourcePropertyName , offset . OffsetExpression ! ) :
428- ExpressionFactory . InternalOffsetValueAdded ( sourcePropertyName , ( Sn . Vector2 ) offset . OffsetValue ! ) ;
452+ ExpressionFactory . OriginOffsetExressionAdded ( sourcePropertyName , offset . OffsetExpression ! ) :
453+ ExpressionFactory . OriginOffsetValueAdded ( sourcePropertyName , ( Sn . Vector2 ) offset . OffsetValue ! ) ;
429454
430455 var expressionAnimation = context . ObjectFactory . CreateExpressionAnimation ( expression ) ;
431456 expressionAnimation . SetReferenceParameter ( "my" , obj ) ;
432457 if ( offset . IsAnimated )
433458 {
434- // expression can use geometry
459+ // Expression can use geometry.
435460 expressionAnimation . SetReferenceParameter ( "geometry" , offset . Geometry ) ;
436461 }
437462
438- // animate original property with expression that applies internal offset to it
463+ // Animate original property with expression that applies origin offset to it.
439464 Animate . WithExpression ( obj , expressionAnimation , propertyName ) ;
465+
466+ return null ;
440467 }
441468
442469 static CompositionLinearGradientBrush ? TranslateLinearGradient (
443470 LayerContext context ,
444471 IGradient linearGradient ,
445472 CompositeOpacity opacity ,
446- Rectangles . InternalOffset ? internalOffset )
473+ Rectangles . OriginOffset ? originOffset = null )
447474 {
448475 var result = context . ObjectFactory . CreateLinearGradientBrush ( ) ;
449476
@@ -453,30 +480,16 @@ static void TranslateVector2AnimatableWithInternalOffset(
453480 var startPoint = Optimizer . TrimAnimatable ( context , linearGradient . StartPoint ) ;
454481 var endPoint = Optimizer . TrimAnimatable ( context , linearGradient . EndPoint ) ;
455482
456- if ( internalOffset is not null )
457- {
458- TranslateVector2AnimatableWithInternalOffset ( context , result , nameof ( result . StartPoint ) , startPoint , internalOffset ) ;
459- }
460- else if ( startPoint . IsAnimated )
483+ var startPointValue = AnimateVector2WithOriginOffsetOrGetValue ( context , result , nameof ( result . StartPoint ) , startPoint , originOffset ) ;
484+ if ( startPointValue is not null )
461485 {
462- Animate . Vector2 ( context , startPoint , result , nameof ( result . StartPoint ) ) ;
463- }
464- else
465- {
466- result . StartPoint = ConvertTo . Vector2 ( startPoint . InitialValue ) ;
486+ result . StartPoint = startPointValue ! ;
467487 }
468488
469- if ( internalOffset is not null )
489+ var endPointValue = AnimateVector2WithOriginOffsetOrGetValue ( context , result , nameof ( result . EndPoint ) , endPoint , originOffset ) ;
490+ if ( endPointValue is not null )
470491 {
471- TranslateVector2AnimatableWithInternalOffset ( context , result , nameof ( result . EndPoint ) , endPoint , internalOffset ) ;
472- }
473- else if ( endPoint . IsAnimated )
474- {
475- Animate . Vector2 ( context , endPoint , result , nameof ( result . EndPoint ) ) ;
476- }
477- else
478- {
479- result . EndPoint = ConvertTo . Vector2 ( endPoint . InitialValue ) ;
492+ result . EndPoint = endPointValue ! ;
480493 }
481494
482495 var gradientStops = Optimizer . TrimAnimatable ( context , linearGradient . GradientStops ) ;
@@ -496,13 +509,13 @@ static void TranslateVector2AnimatableWithInternalOffset(
496509 LayerContext context ,
497510 IRadialGradient gradient ,
498511 CompositeOpacity opacity ,
499- Rectangles . InternalOffset ? internalOffset )
512+ Rectangles . OriginOffset ? originOffset = null )
500513 {
501514 if ( ! context . ObjectFactory . IsUapApiAvailable ( nameof ( CompositionRadialGradientBrush ) , versionDependentFeatureDescription : "Radial gradient fill" ) )
502515 {
503516 // CompositionRadialGradientBrush didn't exist until UAP v8. If the target OS doesn't support
504517 // UAP v8 then fall back to linear gradients as a compromise.
505- return TranslateLinearGradient ( context , gradient , opacity , internalOffset ) ;
518+ return TranslateLinearGradient ( context , gradient , opacity , originOffset ) ;
506519 }
507520
508521 var result = context . ObjectFactory . CreateRadialGradientBrush ( ) ;
@@ -513,17 +526,10 @@ static void TranslateVector2AnimatableWithInternalOffset(
513526 var startPoint = Optimizer . TrimAnimatable ( context , gradient . StartPoint ) ;
514527 var endPoint = Optimizer . TrimAnimatable ( context , gradient . EndPoint ) ;
515528
516- if ( internalOffset is not null )
517- {
518- TranslateVector2AnimatableWithInternalOffset ( context , result , nameof ( result . EllipseCenter ) , startPoint , internalOffset ) ;
519- }
520- else if ( startPoint . IsAnimated )
521- {
522- Animate . Vector2 ( context , startPoint , result , nameof ( result . EllipseCenter ) ) ;
523- }
524- else
529+ var startPointValue = AnimateVector2WithOriginOffsetOrGetValue ( context , result , nameof ( result . EllipseCenter ) , startPoint , originOffset ) ;
530+ if ( startPointValue is not null )
525531 {
526- result . EllipseCenter = ConvertTo . Vector2 ( startPoint . InitialValue ) ;
532+ result . EllipseCenter = startPointValue ! ;
527533 }
528534
529535 if ( endPoint . IsAnimated )
0 commit comments