Esempio n. 1
0
        /// <summary>
        /// Creation of an expression to manage modulo (positive and negative value)
        /// </summary>
        /// <param name="scrollViewer">The ScrollViewer to synchronized. A null value is valid</param>
        /// <param name="imageWidth">Width of the image</param>
        /// <param name="imageHeight">Height of the image</param>
        /// <param name="scrollOrientation">The ScrollOrientation</param>
        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";

            if (_containerVisual == null)
            {
                return;
            }

            var compositor = _containerVisual.Compositor;

            // Setup the expression
            ExpressionNode expressionX = null;
            ExpressionNode expressionY = null;
            ExpressionNode expressionXVal;
            ExpressionNode expressionYVal;

            var propertySetModulo = compositor.CreatePropertySet();

            propertySetModulo.InsertScalar(imageWidthParam, (float)imageWidth);
            propertySetModulo.InsertScalar(offsetXParam, (float)OffsetX);
            propertySetModulo.InsertScalar(imageHeightParam, (float)imageHeight);
            propertySetModulo.InsertScalar(offsetYParam, (float)OffsetY);
            propertySetModulo.InsertScalar(speedParam, (float)ParallaxSpeedRatio);

            var propertySetNodeModulo = propertySetModulo.GetReference();

            var imageHeightNode = propertySetNodeModulo.GetScalarProperty(imageHeightParam);
            var imageWidthNode  = propertySetNodeModulo.GetScalarProperty(imageWidthParam);

            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))));
            }
            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 <ManipulationPropertySetReferenceNode>();

                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))));
            }

            if (scrollOrientation == ScrollOrientation.Horizontal || scrollOrientation == ScrollOrientation.Both)
            {
                expressionX = expressionXVal;

                if (scrollOrientation == ScrollOrientation.Horizontal)
                {
                    // In horizontal mode we never move the offset y
                    expressionY             = (ScalarNode)0.0f;
                    _containerVisual.Offset = new Vector3((float)OffsetY, 0, 0);
                }
            }

            if (scrollOrientation == ScrollOrientation.Vertical || scrollOrientation == ScrollOrientation.Both)
            {
                expressionY = expressionYVal;

                if (scrollOrientation == ScrollOrientation.Vertical)
                {
                    // In vertical mode we never move the offset x
                    expressionX             = (ScalarNode)0.0f;
                    _containerVisual.Offset = new Vector3(0, (float)OffsetX, 0);
                }
            }

            _containerVisual.StopAnimation("Offset.X");
            _containerVisual.StopAnimation("Offset.Y");

            _containerVisual.StartAnimation("Offset.X", expressionX);
            _containerVisual.StartAnimation("Offset.Y", expressionY);

            _propertySetModulo = propertySetModulo;
        }