8
8
using System . Numerics ;
9
9
using System . Threading ;
10
10
using System . Threading . Tasks ;
11
- using Microsoft . Toolkit . Uwp . UI . Animations . Expressions ;
12
11
using Microsoft . Toolkit . Uwp . UI . Extensions ;
13
12
using Windows . Foundation ;
14
13
using Windows . UI . Composition ;
@@ -439,11 +438,16 @@ private async Task CreateModuloExpression(ScrollViewer scrollViewer = null)
439
438
/// <param name="scrollOrientation">The ScrollOrientation</param>
440
439
private void CreateModuloExpression ( ScrollViewer scrollViewer , double imageWidth , double imageHeight , ScrollOrientation scrollOrientation )
441
440
{
442
- const string offsetXParam = "offsetX" ;
443
- const string offsetYParam = "offsetY" ;
444
- const string imageWidthParam = "imageWidth" ;
445
- const string imageHeightParam = "imageHeight" ;
446
- const string speedParam = "speed" ;
441
+ const string propSetParam = "p" ;
442
+ const string offsetXParam = nameof ( OffsetX ) ;
443
+ const string qualifiedOffsetXParam = propSetParam + "." + offsetXParam ;
444
+ const string offsetYParam = nameof ( OffsetY ) ;
445
+ const string qualifiedOffsetYParam = propSetParam + "." + offsetYParam ;
446
+ const string imageWidthParam = nameof ( imageWidth ) ;
447
+ const string qualifiedImageWidthParam = propSetParam + "." + imageWidthParam ;
448
+ const string imageHeightParam = nameof ( imageHeight ) ;
449
+ const string qualifiedImageHeightParam = propSetParam + "." + imageHeightParam ;
450
+ const string speedParam = nameof ( ParallaxSpeedRatio ) ;
447
451
448
452
if ( _containerVisual == null )
449
453
{
@@ -453,10 +457,8 @@ private void CreateModuloExpression(ScrollViewer scrollViewer, double imageWidth
453
457
var compositor = _containerVisual . Compositor ;
454
458
455
459
// Setup the expression
456
- ExpressionNode expressionX = null ;
457
- ExpressionNode expressionY = null ;
458
- ExpressionNode expressionXVal ;
459
- ExpressionNode expressionYVal ;
460
+ var expressionX = compositor . CreateExpressionAnimation ( ) ;
461
+ var expressionY = compositor . CreateExpressionAnimation ( ) ;
460
462
461
463
var propertySetModulo = compositor . CreatePropertySet ( ) ;
462
464
propertySetModulo . InsertScalar ( imageWidthParam , ( float ) imageWidth ) ;
@@ -465,78 +467,67 @@ private void CreateModuloExpression(ScrollViewer scrollViewer, double imageWidth
465
467
propertySetModulo . InsertScalar ( offsetYParam , ( float ) OffsetY ) ;
466
468
propertySetModulo . InsertScalar ( speedParam , ( float ) ParallaxSpeedRatio ) ;
467
469
468
- var propertySetNodeModulo = propertySetModulo . GetReference ( ) ;
469
-
470
- var imageHeightNode = propertySetNodeModulo . GetScalarProperty ( imageHeightParam ) ;
471
- var imageWidthNode = propertySetNodeModulo . GetScalarProperty ( imageWidthParam ) ;
470
+ expressionX . SetReferenceParameter ( propSetParam , propertySetModulo ) ;
471
+ expressionY . SetReferenceParameter ( propSetParam , propertySetModulo ) ;
472
+
473
+ string GenerateFormula ( string common , string dimension )
474
+ => string . Format (
475
+ "{0} == 0 " +
476
+ "? 0 " +
477
+ ": {0} < 0 " +
478
+ "? -(Abs({0} - (Ceil({0} / {1}) * {1})) % {1}) " +
479
+ ": -({1} - ({0} % {1}))" ,
480
+ common ,
481
+ dimension ) ;
482
+
483
+ string expressionXVal ;
484
+ string expressionYVal ;
472
485
if ( scrollViewer == null )
473
486
{
474
- var offsetXNode = ExpressionFunctions . Ceil ( propertySetNodeModulo . GetScalarProperty ( offsetXParam ) ) ;
475
- var offsetYNode = ExpressionFunctions . Ceil ( propertySetNodeModulo . GetScalarProperty ( offsetYParam ) ) ;
476
-
477
487
// expressions are created to simulate a positive and negative modulo with the size of the image and the offset
478
- expressionXVal = ExpressionFunctions . Conditional (
479
- offsetXNode == 0 ,
480
- 0 ,
481
- ExpressionFunctions . Conditional (
482
- offsetXNode < 0 ,
483
- - ( ExpressionFunctions . Abs ( offsetXNode - ( ExpressionFunctions . Ceil ( offsetXNode / imageWidthNode ) * imageWidthNode ) ) % imageWidthNode ) ,
484
- - ( imageWidthNode - ( offsetXNode % imageWidthNode ) ) ) ) ;
485
-
486
- expressionYVal = ExpressionFunctions . Conditional (
487
- offsetYNode == 0 ,
488
- 0 ,
489
- ExpressionFunctions . Conditional (
490
- offsetYNode < 0 ,
491
- - ( ExpressionFunctions . Abs ( offsetYNode - ( ExpressionFunctions . Ceil ( offsetYNode / imageHeightNode ) * imageHeightNode ) ) % imageHeightNode ) ,
492
- - ( imageHeightNode - ( offsetYNode % imageHeightNode ) ) ) ) ;
488
+ expressionXVal = GenerateFormula ( "Ceil(" + qualifiedOffsetXParam + ")" , qualifiedImageHeightParam ) ;
489
+
490
+ expressionYVal = GenerateFormula ( "Ceil(" + qualifiedOffsetYParam + ")" , qualifiedImageWidthParam ) ;
493
491
}
494
492
else
495
493
{
496
494
// expressions are created to simulate a positive and negative modulo with the size of the image and the offset and the ScrollViewer offset (Translation)
497
495
var scrollProperties = ElementCompositionPreview . GetScrollViewerManipulationPropertySet ( scrollViewer ) ;
498
- var scrollPropSet = scrollProperties . GetSpecializedReference < ManipulationPropertySetReferenceNode > ( ) ;
499
-
500
- var speed = propertySetNodeModulo . GetScalarProperty ( speedParam ) ;
501
- var xCommon = ExpressionFunctions . Ceil ( ( scrollPropSet . Translation . X * speed ) + propertySetNodeModulo . GetScalarProperty ( offsetXParam ) ) ;
502
- expressionXVal = ExpressionFunctions . Conditional (
503
- xCommon == 0 ,
504
- 0 ,
505
- ExpressionFunctions . Conditional (
506
- xCommon < 0 ,
507
- - ( ExpressionFunctions . Abs ( xCommon - ( ExpressionFunctions . Ceil ( xCommon / imageWidthNode ) * imageWidthNode ) ) % imageWidthNode ) ,
508
- - ( imageWidthNode - ( xCommon % imageWidthNode ) ) ) ) ;
509
-
510
- var yCommon = ExpressionFunctions . Ceil ( ( scrollPropSet . Translation . Y * speed ) + propertySetNodeModulo . GetScalarProperty ( offsetYParam ) ) ;
511
- expressionYVal = ExpressionFunctions . Conditional (
512
- yCommon == 0 ,
513
- 0 ,
514
- ExpressionFunctions . Conditional (
515
- yCommon < 0 ,
516
- - ( ExpressionFunctions . Abs ( yCommon - ( ExpressionFunctions . Ceil ( yCommon / imageHeightNode ) * imageHeightNode ) ) % imageHeightNode ) ,
517
- - ( imageHeightNode - ( yCommon % imageHeightNode ) ) ) ) ;
496
+ const string scrollParam = "s" ;
497
+ const string translationParam = scrollParam + "." + nameof ( scrollViewer . Translation ) ;
498
+ const string qualifiedSpeedParam = propSetParam + "." + speedParam ;
499
+
500
+ expressionX . SetReferenceParameter ( scrollParam , scrollProperties ) ;
501
+ expressionY . SetReferenceParameter ( scrollParam , scrollProperties ) ;
502
+
503
+ string GenerateParallaxFormula ( string scrollTranslation , string speed , string offset , string dimension )
504
+ => GenerateFormula ( string . Format ( "Ceil(({0} * {1}) + {2})" , scrollTranslation , speed , offset ) , dimension ) ;
505
+
506
+ expressionXVal = GenerateParallaxFormula ( translationParam + "." + nameof ( scrollViewer . Translation . X ) , qualifiedSpeedParam , qualifiedOffsetXParam , qualifiedImageWidthParam ) ;
507
+
508
+ expressionYVal = GenerateParallaxFormula ( translationParam + "." + nameof ( scrollViewer . Translation . Y ) , qualifiedSpeedParam , qualifiedOffsetYParam , qualifiedImageHeightParam ) ;
518
509
}
519
510
520
511
if ( scrollOrientation == ScrollOrientation . Horizontal || scrollOrientation == ScrollOrientation . Both )
521
512
{
522
- expressionX = expressionXVal ;
513
+ expressionX . Expression = expressionXVal ;
523
514
524
515
if ( scrollOrientation == ScrollOrientation . Horizontal )
525
516
{
526
517
// In horizontal mode we never move the offset y
527
- expressionY = ( ScalarNode ) 0.0f ;
518
+ expressionY . Expression = "0" ;
528
519
_containerVisual . Offset = new Vector3 ( ( float ) OffsetY , 0 , 0 ) ;
529
520
}
530
521
}
531
522
532
523
if ( scrollOrientation == ScrollOrientation . Vertical || scrollOrientation == ScrollOrientation . Both )
533
524
{
534
- expressionY = expressionYVal ;
525
+ expressionY . Expression = expressionYVal ;
535
526
536
527
if ( scrollOrientation == ScrollOrientation . Vertical )
537
528
{
538
529
// In vertical mode we never move the offset x
539
- expressionX = ( ScalarNode ) 0.0f ;
530
+ expressionX . Expression = "0" ;
540
531
_containerVisual . Offset = new Vector3 ( 0 , ( float ) OffsetX , 0 ) ;
541
532
}
542
533
}
0 commit comments