private void _createAnimation(UIElement attachedElement, CompositionObject compositionObject) { _offsetAnimation = Window.Current.Compositor.CreateExpressionAnimation(OFFSET_ANIMATION_EXPRESSION); _offsetAnimation.SetReferenceParameter(OFFSET_ANIMATION_EXPRESSION_REFERENCE_PROPS, _offsetProps); var pointerProps = ElementCompositionPreview.GetPointerPositionPropertySet(attachedElement); _offsetAnimation.SetReferenceParameter(OFFSET_ANIMATION_EXPRESSION_REFERENCE_POINTER, pointerProps); compositionObject.StartAnimation("Offset", _offsetAnimation); }
protected override void OnConnected(UIElement targetElement) { if (targetElement == null) { return; } Compositor compositor = Window.Current.Compositor; // Create SpotLight and set its properties SpotLight spotLight = compositor.CreateSpotLight(); spotLight.InnerConeColor = Colors.FloralWhite; spotLight.OuterConeColor = Colors.FloralWhite; spotLight.InnerConeAngleInDegrees = 0f; spotLight.InnerConeIntensity = 4; //spotLight.OuterConeAngleInDegrees = 3f; spotLight.ConstantAttenuation = 1f; spotLight.LinearAttenuation = 0.253f; spotLight.QuadraticAttenuation = 0.58f; spotLight.Offset = new Vector3(0, 0, 0); // Associate CompositionLight with XamlLight this.CompositionLight = spotLight; // Define resting position Animation Vector3 restingPosition = new Vector3(200, 200, 400); CubicBezierEasingFunction cbEasing = compositor.CreateCubicBezierEasingFunction(new Vector2(0.3f, 0.7f), new Vector2(0.9f, 0.5f)); _offsetAnimation = compositor.CreateVector3KeyFrameAnimation(); _offsetAnimation.InsertKeyFrame(1, restingPosition, cbEasing); _offsetAnimation.Duration = TimeSpan.FromSeconds(0.5f); //spotLight.Offset = restingPosition; // Define expression animation that relates light's offset to pointer position CompositionPropertySet hoverPosition = ElementCompositionPreview.GetPointerPositionPropertySet(targetElement); _lightPositionExpression = compositor.CreateExpressionAnimation("Vector3(hover.Position.X, hover.Position.Y, height)"); _lightPositionExpression.SetReferenceParameter("hover", hoverPosition); _lightPositionExpression.SetScalarParameter("height", 150f); // Configure pointer entered/ exited events targetElement.PointerMoved += TargetElement_PointerMoved; targetElement.PointerExited += TargetElement_PointerExited; // Add UIElement to the Light's Targets HoverLight.AddTargetElement(GetId(), targetElement); //MoveToRestingPosition(); }
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); }
// via the composition api, which doesn't seem to work. void reportPointerPositionRelativeTo_canvas(object sender, PointerRoutedEventArgs args) { var rectPointerState = ElementCompositionPreview.GetPointerPositionPropertySet(canvas); switch (rectPointerState.TryGetVector3("Position", out var val)) { case CompositionGetValueStatus.Succeeded: Debug.WriteLine(val); break; case CompositionGetValueStatus.NotFound: Debug.WriteLine("Nothing"); break; case CompositionGetValueStatus.TypeMismatch: Debug.WriteLine("type mismatch"); break; } }
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); }
private void MainPage_Loaded(object sender, RoutedEventArgs e) { var container = Compositor.CreateContainerVisual(); var colors = typeof(Colors).GetProperties(BindingFlags.Public | BindingFlags.Static | BindingFlags.GetProperty) .Select(c => c.GetValue(null)) .OfType <Color>() .ToList(); ExpressionAnimation exp = null; for (int i = 1; i < 20; i++) { var c = colors[i % colors.Count]; var t = new TranslationFastVisual( compositor: Compositor, size: new Vector2(50, 50), offset: Vector3.Zero, color: c, dampingRatio: 0.3f); if (exp == null) { var prop = ElementCompositionPreview.GetPointerPositionPropertySet(this); exp = Compositor.CreateExpressionAnimation("Vector3(prop.Position.X, prop.Position.Y, 0f)"); exp.SetReferenceParameter("prop", prop); } t.Translation.StartExpression(exp); exp = Compositor.CreateExpressionAnimation("prop.Value"); exp.SetReferenceParameter("prop", t.Translation.Properties); translationVisuals.Add(t); container.Children.InsertAtBottom(t.Visual); } ElementCompositionPreview.SetElementChildVisual(this, container); }
private async void OnPageLoaded(object sender, RoutedEventArgs e) { _compositor = Window.Current.Compositor; _generator = _compositor.CreateCompositionGenerator(); var gridSize = new Vector2((float)RootGrid.ActualWidth, (float)RootGrid.ActualHeight); var anim = _compositor.CreatePathKeyFrameAnimation(); _rootVisual = _compositor.CreateSpriteVisual(); _rootVisual.Size = gridSize; // Create the surface brush from the image var imageSurface = await _generator.CreateImageSurfaceAsync( new Uri("ms-appx:///Assets/Images/Cat.png"), new Size(400, 400), ImageSurfaceOptions.Default); var imageBrush = _compositor.CreateSurfaceBrush(imageSurface); // Create the clipped visuals for (var i = 0; i < 145; i++) { var visual = _compositor.CreateSpriteVisual(); visual.Offset = new Vector3(400, 400, 0); visual.Size = new Vector2(400, 400); visual.Brush = imageBrush; visual.AnchorPoint = new Vector2(0.5f); var radius = 290 - (i * 2); // Create the GeometricClip for this visual var clipGeometry = CanvasGeometry.CreateCircle(null, new Vector2(200, 200), radius); visual.Clip = _compositor.CreateGeometricClip(clipGeometry); _rootVisual.Children.InsertAtTop(visual); _visuals.Add(visual); } // Display the rootVisual ElementCompositionPreview.SetElementChildVisual(RootGrid, _rootVisual); // Reverse the visuals list so that the items in the list are now sorted // in z-order from top to bottom _visuals.Reverse(); // The topmost visual would track the pointer position _dragVisual = _visuals.First(); // Get the CompositionPropertySet which tracks the pointer position on the RootGrid _pointerTrackerSet = ElementCompositionPreview.GetPointerPositionPropertySet(RootGrid); // Animate the topmost visual so that it tracks and follows the pointer position _pointerTrackerAnimation = _compositor.GenerateVector3KeyFrameAnimation() .HavingDuration(PointerTrackerAnimationDuration) .RepeatsForever(); _pointerTrackerAnimation.InsertExpressionKeyFrame(0f, c => new VisualTarget().Offset); _pointerTrackerAnimation.InsertExpressionKeyFrame( 1f, c => c.Lerp(new VisualTarget().Offset, _pointerTrackerSet.Get <Vector3>("Position"), DefaultLerpAmount), _compositor.CreateEaseOutQuinticEasingFunction()); // Animate the remaining visuals in such a way that each visual tracks and follows the // position of the visual above it. var prevChild = _dragVisual; foreach (var child in _visuals.Skip(1)) { var offsetAnimation = _compositor.GenerateVector3KeyFrameAnimation() .HavingDuration(ChildOffsetAnimationDuration) .RepeatsForever(); offsetAnimation.InsertExpressionKeyFrame(0f, c => new VisualTarget().Offset); offsetAnimation.InsertExpressionKeyFrame( 1f, c => c.Lerp(new VisualTarget().Offset, prevChild.Offset, DefaultLerpAmount), _compositor.CreateEaseOutQuinticEasingFunction()); child.StartAnimation(() => child.Offset, offsetAnimation); prevChild = child; } }
public static CompositionPropertySet GetPointerPositionProperties(this UIElement element) => ElementCompositionPreview.GetPointerPositionPropertySet(element);
private void Page_Loaded(object sender, RoutedEventArgs e) { // create the compositor _compositor = ElementCompositionPreview.GetElementVisual(this).Compositor; // create what captures the pointer position _hoverPositionPropertySet = ElementCompositionPreview.GetPointerPositionPropertySet(r2); // create the two visuals _vis = _compositor.CreateSpriteVisual(); _pulseVis = _compositor.CreateSpriteVisual(); // create the main brush with warm colors _mainBrush = _compositor.CreateRadialGradientBrush(); _mainBrush.EllipseCenter = new Vector2(.5f, .5f); _mainBrush.EllipseRadius = new Vector2(.5f, .5f); _MBGradientStop1 = _compositor.CreateColorGradientStop(); _MBGradientStop1.Offset = 0; _MBGradientStop1.Color = _warmColor1; _MBGradientStop2 = _compositor.CreateColorGradientStop(); _MBGradientStop2.Offset = .1f; _MBGradientStop2.Color = _warmColor2; _MBGradientStop3 = _compositor.CreateColorGradientStop(); _MBGradientStop3.Offset = 1; _MBGradientStop3.Color = _warmColor3; _mainBrush.ColorStops.Add(_MBGradientStop1); _mainBrush.ColorStops.Add(_MBGradientStop2); _mainBrush.ColorStops.Add(_MBGradientStop3); // create the brush for the pulse visual _pulseBrush = _compositor.CreateRadialGradientBrush(); _pulseBrush.EllipseCenter = new Vector2(.5f, .5f); _pulseBrush.EllipseRadius = new Vector2(.5f, .5f); _PBGradientStop1 = _compositor.CreateColorGradientStop(); _PBGradientStop1.Offset = 0; _PBGradientStop1.Color = _innerPulseColor; _PBGradientStop2 = _compositor.CreateColorGradientStop(); _PBGradientStop2.Offset = 1; _PBGradientStop2.Color = _innerPulseColor; _pulseBrush.ColorStops.Add(_PBGradientStop1); _pulseBrush.ColorStops.Add(_PBGradientStop2); // finish setting properties of the first visual _vis.Size = new Vector2(300, 300); _vis.Offset = new Vector3(((float)r2.ActualWidth / 2), ((float)r2.ActualHeight / 2), 0); _vis.AnchorPoint = new Vector2(.5f, .5f); _vis.Brush = _mainBrush; // finish setting properties of the pulsing visual _pulseVis.Size = new Vector2(500, 500); _pulseVis.Offset = new Vector3(((float)r1.ActualWidth / 2), ((float)r1.ActualHeight / 2), 0); _pulseVis.AnchorPoint = new Vector2(.5f, .5f); _pulseVis.Brush = _pulseBrush; // create the clip that makes the visuals circular CompositionGeometricClip gClip = _compositor.CreateGeometricClip(); CompositionEllipseGeometry circle = _compositor.CreateEllipseGeometry(); circle.Radius = new Vector2(_vis.Size.X / 2, _vis.Size.Y / 2); circle.Center = new Vector2(_vis.Size.X / 2, _vis.Size.Y / 2); gClip.Geometry = circle; _vis.Clip = gClip; CompositionGeometricClip gClip2 = _compositor.CreateGeometricClip(); CompositionEllipseGeometry circle2 = _compositor.CreateEllipseGeometry(); circle2.Radius = new Vector2(_pulseVis.Size.X / 2, _pulseVis.Size.Y / 2); circle2.Center = new Vector2(_pulseVis.Size.X / 2, _pulseVis.Size.Y / 2); gClip2.Geometry = circle2; _pulseVis.Clip = gClip2; // set the pointer my_pointer = new Vector3(((float)r1.ActualWidth / 2), ((float)r1.ActualHeight / 2), 0); // set the visuals in the tree ElementCompositionPreview.SetElementChildVisual(r2, _vis); ElementCompositionPreview.SetElementChildVisual(r1, _pulseVis); // ellipse center follows mouse _ellipseCenterAnim = _compositor.CreateExpressionAnimation("Vector2(p.Position.X / 500.0f, p.Position.Y / 500.0f)"); _ellipseCenterAnim.SetReferenceParameter("p", _hoverPositionPropertySet); _mainBrush.StartAnimation("EllipseCenter", _ellipseCenterAnim); // second stop is animated for "pulsing" effect within the first visual that runs constantly _offsetAnim = _compositor.CreateScalarKeyFrameAnimation(); _offsetAnim.InsertKeyFrame(0, 0); _offsetAnim.InsertKeyFrame(1f, 1f); _offsetAnim.Duration = TimeSpan.FromSeconds(2); _offsetAnim.IterationCount = 50; _MBGradientStop2.StartAnimation("Offset", _offsetAnim); // set up the animation for the backing pulse visual // animate the color _pulseColorAnim = _compositor.CreateColorKeyFrameAnimation(); _pulseColorAnim.InsertKeyFrame(0, _innerPulseColor); _pulseColorAnim.InsertKeyFrame(.99f, _outerPulseColor); _pulseColorAnim.InsertKeyFrame(1, _innerPulseColor); _pulseColorAnim.Duration = TimeSpan.FromSeconds(1); _pulseColorAnim.IterationBehavior = AnimationIterationBehavior.Forever; _PBGradientStop1.StartAnimation("Color", _pulseColorAnim); // animate offset of first stop _pulseStop1OffsetAnim = _compositor.CreateScalarKeyFrameAnimation(); _pulseStop1OffsetAnim.InsertKeyFrame(0, 0); _pulseStop1OffsetAnim.InsertKeyFrame(1f, 1f); _pulseStop1OffsetAnim.Duration = TimeSpan.FromSeconds(1); _pulseStop1OffsetAnim.IterationBehavior = AnimationIterationBehavior.Forever; _PBGradientStop1.StartAnimation("Offset", _pulseStop1OffsetAnim); // animate offset of second stop _pulseStop2OffsetAnim = _compositor.CreateScalarKeyFrameAnimation(); _pulseStop2OffsetAnim.InsertKeyFrame(0, 0); _pulseStop2OffsetAnim.InsertKeyFrame(1f, 1f); _pulseStop2OffsetAnim.Duration = TimeSpan.FromSeconds(1); _pulseStop2OffsetAnim.IterationBehavior = AnimationIterationBehavior.Forever; _pulseStop2OffsetAnim.DelayTime = TimeSpan.FromSeconds(.25f); _PBGradientStop2.StartAnimation("Offset", _pulseStop2OffsetAnim); _pulseScaleAnim = _compositor.CreateVector3KeyFrameAnimation(); _pulseScaleAnim.InsertKeyFrame(0, Vector3.Zero); _pulseScaleAnim.InsertKeyFrame(1, Vector3.One); _pulseScaleAnim.Duration = TimeSpan.FromSeconds(1); _pulseScaleAnim.IterationBehavior = AnimationIterationBehavior.Forever; _pulseVis.StartAnimation("Scale", _pulseScaleAnim); }