private void OnTilePointerPressed(object sender, PointerRoutedEventArgs e) { var tileGrid = (Grid)sender; var colorElement = (Rectangle)tileGrid.FindName("ColorElement"); // Set the CenterPoint of the backing Visual, so the rotation axis will defined from the middle. colorElement.Visual().CenterPoint = new Vector3(tileGrid.RenderSize.ToVector2() / 2, 0.0f); // Calculate distance from corner of quadrant to Center _center = colorElement.Visual().CenterPoint; var xSquared = Math.Pow(tileGrid.ActualWidth / 2, 2); var ySquared = Math.Pow(tileGrid.ActualHeight / 2, 2); _distanceToCenter = (float)Math.Sqrt(xSquared + ySquared); // || DEFINE THE EXPRESSION FOR THE ROTATION ANGLE || // We calculate the Rotation Angle such that it increases from 0 to 3 as the cursor position moves away from the center. // Combined with animating the Rotation Axis, the image is "push down" on the point at which the cursor is located. var pointerPositionProperties = ElementCompositionPreview.GetPointerPositionPropertySet(tileGrid); var pointerPosition = pointerPositionProperties.GetSpecializedReference <PointerPositionPropertySetReferenceNode>().Position; var angleExpressionNode = 3 * (EF.Clamp(EF.Distance(_center, pointerPosition), 0, _distanceToCenter) % _distanceToCenter / _distanceToCenter); var rotationAngleAnimation = _compositor.CreateScalarKeyFrameAnimation(); rotationAngleAnimation.Duration = TimeSpan.FromMilliseconds(600); rotationAngleAnimation.InsertExpressionKeyFrame(0.4f, angleExpressionNode); rotationAngleAnimation.InsertKeyFrame(1.0f, 0.0f); colorElement.Visual().StartAnimation("RotationAngleInDegrees", rotationAngleAnimation); // || DEFINE THE EXPRESSION FOR THE ROTATION AXIS || // The RotationAxis will be defined as the axis perpendicular to vector position of the hover pointer (vector from center to hover position). // The axis is a vector calculated by first converting the pointer position into the coordinate space where the center point (0, 0) is in the middle. // The perpendicular axis is then calculated by transposing the cartesian x, y components and negating one (e.g. Vector3(-y,x,0) ) var axisAngleExpressionNode = EF.Floor((pointerPosition.X - _center.X) * EF.Conditional(pointerPosition.X == _center.X, 0, 1)); var rotationAxisAnimation = _compositor.CreateScalarKeyFrameAnimation(); rotationAxisAnimation.Duration = TimeSpan.FromMilliseconds(600); rotationAxisAnimation.InsertExpressionKeyFrame(0.4f, axisAngleExpressionNode); rotationAxisAnimation.InsertKeyFrame(1.0f, 0.0f); colorElement.Visual().StartAnimation("RotationAxis.Y", rotationAxisAnimation); }
private void TiltUIElement() { // Grab the backing Visual for the UIElement image _tiltVisual = ElementCompositionPreview.GetElementVisual(tiltImage); // Set the CenterPoint of the backing Visual, so the rotation axis will defined from the middle _tiltVisual.CenterPoint = new Vector3((float)tiltImage.Width / 2, (float)tiltImage.Height / 2, 0f); // Grab the PropertySet containing the hover pointer data that will be used to drive the rotations // Note: We have a second UIElement we will grab the pointer data against and the other we will animate _hoverPositionPropertySet = ElementCompositionPreview.GetPointerPositionPropertySet(HitTestRect); // Calculate distance from corner of quadrant to Center var center = new Vector3((float)tiltImage.Width / 2, (float)tiltImage.Height / 2, 0); var xSquared = Math.Pow(tiltImage.Width / 2, 2); var ySquared = Math.Pow(tiltImage.Height / 2, 2); var distanceToCenter = (float)Math.Sqrt(xSquared + ySquared); // || DEFINE THE EXPRESSION FOR THE ROTATION ANGLE || // We calculate the Rotation Angle such that it increases from 0 to 35 as the cursor position moves away from the center. // Combined with animating the Rotation Axis, the image is "push down" on the point at which the cursor is located. // Note: We special case when the hover position is (0,0,0) as this is the starting hover position and and we want the image to be flat (rotationAngle = 0) at startup. var hoverPosition = _hoverPositionPropertySet.GetSpecializedReference <PointerPositionPropertySetReferenceNode>().Position; var angleExpressionNode = EF.Conditional( hoverPosition == new Vector3(0, 0, 0), ExpressionValues.CurrentValue.CreateScalarCurrentValue(), 35 * ((EF.Clamp(EF.Distance(center, hoverPosition), 0, distanceToCenter) % distanceToCenter) / distanceToCenter)); _tiltVisual.StartAnimation("RotationAngleInDegrees", angleExpressionNode); // || DEFINE THE EXPRESSION FOR THE ROTATION AXIS || // The RotationAxis will be defined as the axis perpendicular to vector position of the hover pointer (vector from center to hover position). // The axis is a vector calculated by first converting the pointer position into the coordinate space where the center point (0, 0) is in the middle. // The perpendicular axis is then calculated by transposing the cartesian x, y components and negating one (e.g. Vector3(-y,x,0) ) var axisAngleExpressionNode = EF.Vector3( -(hoverPosition.Y - center.Y) * EF.Conditional(hoverPosition.Y == center.Y, 0, 1), (hoverPosition.X - center.X) * EF.Conditional(hoverPosition.X == center.X, 0, 1), 0); _tiltVisual.StartAnimation("RotationAxis", axisAngleExpressionNode); }