diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/TileControl/TileControl.cs b/Microsoft.Toolkit.Uwp.UI.Controls/TileControl/TileControl.cs
index dea441e074f..b537ffebf6c 100644
--- a/Microsoft.Toolkit.Uwp.UI.Controls/TileControl/TileControl.cs
+++ b/Microsoft.Toolkit.Uwp.UI.Controls/TileControl/TileControl.cs
@@ -8,7 +8,6 @@
using System.Numerics;
using System.Threading;
using System.Threading.Tasks;
-using Microsoft.Toolkit.Uwp.UI.Animations.Expressions;
using Microsoft.Toolkit.Uwp.UI.Extensions;
using Windows.Foundation;
using Windows.UI.Composition;
@@ -439,11 +438,16 @@ private async Task CreateModuloExpression(ScrollViewer scrollViewer = null)
/// The ScrollOrientation
private void CreateModuloExpression(ScrollViewer scrollViewer, double imageWidth, double imageHeight, ScrollOrientation scrollOrientation)
{
- const string offsetXParam = "offsetX";
- const string offsetYParam = "offsetY";
- const string imageWidthParam = "imageWidth";
- const string imageHeightParam = "imageHeight";
- const string speedParam = "speed";
+ const string propSetParam = "p";
+ const string offsetXParam = nameof(OffsetX);
+ const string qualifiedOffsetXParam = propSetParam + "." + offsetXParam;
+ const string offsetYParam = nameof(OffsetY);
+ const string qualifiedOffsetYParam = propSetParam + "." + offsetYParam;
+ const string imageWidthParam = nameof(imageWidth);
+ const string qualifiedImageWidthParam = propSetParam + "." + imageWidthParam;
+ const string imageHeightParam = nameof(imageHeight);
+ const string qualifiedImageHeightParam = propSetParam + "." + imageHeightParam;
+ const string speedParam = nameof(ParallaxSpeedRatio);
if (_containerVisual == null)
{
@@ -453,10 +457,8 @@ private void CreateModuloExpression(ScrollViewer scrollViewer, double imageWidth
var compositor = _containerVisual.Compositor;
// Setup the expression
- ExpressionNode expressionX = null;
- ExpressionNode expressionY = null;
- ExpressionNode expressionXVal;
- ExpressionNode expressionYVal;
+ var expressionX = compositor.CreateExpressionAnimation();
+ var expressionY = compositor.CreateExpressionAnimation();
var propertySetModulo = compositor.CreatePropertySet();
propertySetModulo.InsertScalar(imageWidthParam, (float)imageWidth);
@@ -465,78 +467,67 @@ private void CreateModuloExpression(ScrollViewer scrollViewer, double imageWidth
propertySetModulo.InsertScalar(offsetYParam, (float)OffsetY);
propertySetModulo.InsertScalar(speedParam, (float)ParallaxSpeedRatio);
- var propertySetNodeModulo = propertySetModulo.GetReference();
-
- var imageHeightNode = propertySetNodeModulo.GetScalarProperty(imageHeightParam);
- var imageWidthNode = propertySetNodeModulo.GetScalarProperty(imageWidthParam);
+ expressionX.SetReferenceParameter(propSetParam, propertySetModulo);
+ expressionY.SetReferenceParameter(propSetParam, propertySetModulo);
+
+ string GenerateFormula(string common, string dimension)
+ => string.Format(
+ "{0} == 0 " +
+ "? 0 " +
+ ": {0} < 0 " +
+ "? -(Abs({0} - (Ceil({0} / {1}) * {1})) % {1}) " +
+ ": -({1} - ({0} % {1}))",
+ common,
+ dimension);
+
+ string expressionXVal;
+ string expressionYVal;
if (scrollViewer == null)
{
- var offsetXNode = ExpressionFunctions.Ceil(propertySetNodeModulo.GetScalarProperty(offsetXParam));
- var offsetYNode = ExpressionFunctions.Ceil(propertySetNodeModulo.GetScalarProperty(offsetYParam));
-
// expressions are created to simulate a positive and negative modulo with the size of the image and the offset
- expressionXVal = ExpressionFunctions.Conditional(
- offsetXNode == 0,
- 0,
- ExpressionFunctions.Conditional(
- offsetXNode < 0,
- -(ExpressionFunctions.Abs(offsetXNode - (ExpressionFunctions.Ceil(offsetXNode / imageWidthNode) * imageWidthNode)) % imageWidthNode),
- -(imageWidthNode - (offsetXNode % imageWidthNode))));
-
- expressionYVal = ExpressionFunctions.Conditional(
- offsetYNode == 0,
- 0,
- ExpressionFunctions.Conditional(
- offsetYNode < 0,
- -(ExpressionFunctions.Abs(offsetYNode - (ExpressionFunctions.Ceil(offsetYNode / imageHeightNode) * imageHeightNode)) % imageHeightNode),
- -(imageHeightNode - (offsetYNode % imageHeightNode))));
+ expressionXVal = GenerateFormula("Ceil(" + qualifiedOffsetXParam + ")", qualifiedImageHeightParam);
+
+ expressionYVal = GenerateFormula("Ceil(" + qualifiedOffsetYParam + ")", qualifiedImageWidthParam);
}
else
{
// expressions are created to simulate a positive and negative modulo with the size of the image and the offset and the ScrollViewer offset (Translation)
var scrollProperties = ElementCompositionPreview.GetScrollViewerManipulationPropertySet(scrollViewer);
- var scrollPropSet = scrollProperties.GetSpecializedReference();
-
- var speed = propertySetNodeModulo.GetScalarProperty(speedParam);
- var xCommon = ExpressionFunctions.Ceil((scrollPropSet.Translation.X * speed) + propertySetNodeModulo.GetScalarProperty(offsetXParam));
- expressionXVal = ExpressionFunctions.Conditional(
- xCommon == 0,
- 0,
- ExpressionFunctions.Conditional(
- xCommon < 0,
- -(ExpressionFunctions.Abs(xCommon - (ExpressionFunctions.Ceil(xCommon / imageWidthNode) * imageWidthNode)) % imageWidthNode),
- -(imageWidthNode - (xCommon % imageWidthNode))));
-
- var yCommon = ExpressionFunctions.Ceil((scrollPropSet.Translation.Y * speed) + propertySetNodeModulo.GetScalarProperty(offsetYParam));
- expressionYVal = ExpressionFunctions.Conditional(
- yCommon == 0,
- 0,
- ExpressionFunctions.Conditional(
- yCommon < 0,
- -(ExpressionFunctions.Abs(yCommon - (ExpressionFunctions.Ceil(yCommon / imageHeightNode) * imageHeightNode)) % imageHeightNode),
- -(imageHeightNode - (yCommon % imageHeightNode))));
+ const string scrollParam = "s";
+ const string translationParam = scrollParam + "." + nameof(scrollViewer.Translation);
+ const string qualifiedSpeedParam = propSetParam + "." + speedParam;
+
+ expressionX.SetReferenceParameter(scrollParam, scrollProperties);
+ expressionY.SetReferenceParameter(scrollParam, scrollProperties);
+
+ string GenerateParallaxFormula(string scrollTranslation, string speed, string offset, string dimension)
+ => GenerateFormula(string.Format("Ceil(({0} * {1}) + {2})", scrollTranslation, speed, offset), dimension);
+
+ expressionXVal = GenerateParallaxFormula(translationParam + "." + nameof(scrollViewer.Translation.X), qualifiedSpeedParam, qualifiedOffsetXParam, qualifiedImageWidthParam);
+
+ expressionYVal = GenerateParallaxFormula(translationParam + "." + nameof(scrollViewer.Translation.Y), qualifiedSpeedParam, qualifiedOffsetYParam, qualifiedImageHeightParam);
}
if (scrollOrientation == ScrollOrientation.Horizontal || scrollOrientation == ScrollOrientation.Both)
{
- expressionX = expressionXVal;
+ expressionX.Expression = expressionXVal;
if (scrollOrientation == ScrollOrientation.Horizontal)
{
// In horizontal mode we never move the offset y
- expressionY = (ScalarNode)0.0f;
+ expressionY.Expression = "0";
_containerVisual.Offset = new Vector3((float)OffsetY, 0, 0);
}
}
if (scrollOrientation == ScrollOrientation.Vertical || scrollOrientation == ScrollOrientation.Both)
{
- expressionY = expressionYVal;
+ expressionY.Expression = expressionYVal;
if (scrollOrientation == ScrollOrientation.Vertical)
{
// In vertical mode we never move the offset x
- expressionX = (ScalarNode)0.0f;
+ expressionX.Expression = "0";
_containerVisual.Offset = new Vector3(0, (float)OffsetX, 0);
}
}