private void StartGearMotor(double secondsPerRotation) { // Start the first gear (the red one) if (_gearMotionScalarAnimation == null) { _gearMotionScalarAnimation = _compositor.CreateScalarKeyFrameAnimation(); var linear = _compositor.CreateLinearEasingFunction(); var startingValue = ExpressionValues.StartingValue.CreateScalarStartingValue(); _gearMotionScalarAnimation.InsertExpressionKeyFrame(0.0f, startingValue); _gearMotionScalarAnimation.InsertExpressionKeyFrame(1.0f, startingValue + 360f, linear); _gearMotionScalarAnimation.IterationBehavior = AnimationIterationBehavior.Forever; } _gearMotionScalarAnimation.Duration = TimeSpan.FromSeconds(secondsPerRotation); _gearVisuals.First().StartAnimation("RotationAngleInDegrees", _gearMotionScalarAnimation); }
protected override void OnConnected(UIElement element) { host = ElementCompositionPreview.GetElementVisual(element); propset = host.Compositor.CreatePropertySet(); propset.InsertScalar("offsetx", 0f); propset.InsertScalar("offsety", 0f); propset.InsertScalar("degress", 0f); propset.InsertVector3("axis", Vector3.UnitZ); UpdateTo(); var group = host.Compositor.CreateAnimationGroup(); var step = host.Compositor.CreateStepEasingFunction(); offset = host.Compositor.CreateVector3KeyFrameAnimation(); offset.InsertExpressionKeyFrame(0f, "this.StartingValue"); offset.InsertExpressionKeyFrame(0.99f, "Vector3(this.FinalValue.X + prop.offsetx,this.FinalValue.Y + prop.offsety,this.FinalValue.Z)"); offset.InsertExpressionKeyFrame(1f, "this.FinalValue", step); offset.SetReferenceParameter("host", host); offset.SetReferenceParameter("prop", propset); offset.Duration = Duration; offset.Target = "Offset"; axis = host.Compositor.CreateVector3KeyFrameAnimation(); axis.InsertExpressionKeyFrame(0f, "prop.axis", step); axis.InsertExpressionKeyFrame(1f, "prop.axis", step); axis.SetReferenceParameter("prop", propset); axis.Duration = Duration; axis.Target = "RotationAxis"; degress = host.Compositor.CreateScalarKeyFrameAnimation(); degress.InsertExpressionKeyFrame(0f, "this.StartingValue"); degress.InsertExpressionKeyFrame(0.99f, "this.FinalValue + prop.degress"); degress.InsertExpressionKeyFrame(1f, "this.FinalValue", step); degress.SetReferenceParameter("host", host); degress.SetReferenceParameter("prop", propset); degress.Duration = Duration; degress.Target = "RotationAngleInDegrees"; opacity = host.Compositor.CreateScalarKeyFrameAnimation(); opacity.InsertExpressionKeyFrame(0f, "this.StartingValue"); opacity.InsertKeyFrame(1f, 0f); opacity.Duration = Duration; opacity.Target = "Opacity"; group.Add(offset); group.Add(axis); group.Add(degress); group.Add(opacity); Animation = group; }
ScalarKeyFrameAnimation imageFlipAnimation, textFlipAnimation; //MediaTransport Image, Textbox animations void setupAnimations() { visual = ElementCompositionPreview.GetElementVisual(this); compositor = visual.Compositor; blurredVisual = compositor.CreateSpriteVisual(); imageFactory = CompositionImageFactory.CreateCompositionImageFactory(compositor); var graphicsEffect = new BlendEffect { Mode = BlendEffectMode.HardLight, Background = new ColorSourceEffect() { Name = "Tint", Color = Color.FromArgb(200, 0, 0, 0), }, Foreground = new GaussianBlurEffect() { Name = "Blur", Source = new CompositionEffectSourceParameter("source"), BlurAmount = 20.0f, Optimization = EffectOptimization.Balanced, BorderMode = EffectBorderMode.Hard, } }; effectFactory = compositor.CreateEffectFactory(graphicsEffect, new[] { "Blur.BlurAmount", "Tint.Color" }); fadeOutAnimation = compositor.CreateScalarKeyFrameAnimation(); fadeOutAnimation.InsertExpressionKeyFrame(0.0f, "1"); fadeOutAnimation.InsertExpressionKeyFrame(1f, "0"); fadeOutAnimation.Duration = TimeSpan.FromMilliseconds(500); fadeInAnimation = compositor.CreateScalarKeyFrameAnimation(); fadeInAnimation.InsertExpressionKeyFrame(0.0f, "0"); fadeInAnimation.InsertExpressionKeyFrame(1f, "1"); fadeInAnimation.Duration = TimeSpan.FromMilliseconds(500); imageFlipAnimation = compositor.CreateScalarKeyFrameAnimation(); imageFlipAnimation.InsertExpressionKeyFrame(0.0f, "-60"); imageFlipAnimation.InsertExpressionKeyFrame(1f, "0"); imageFlipAnimation.Duration = TimeSpan.FromMilliseconds(500); textFlipAnimation = compositor.CreateScalarKeyFrameAnimation(); textFlipAnimation.InsertExpressionKeyFrame(0.0f, "-90"); textFlipAnimation.InsertExpressionKeyFrame(1f, "0"); textFlipAnimation.Duration = TimeSpan.FromMilliseconds(300); }
protected override void OnConnected(UIElement element) { var host = ElementCompositionPreview.GetElementVisual(element); var group = host.Compositor.CreateAnimationGroup(); var step = host.Compositor.CreateStepEasingFunction(); scale = host.Compositor.CreateVector3KeyFrameAnimation(); scale.InsertExpressionKeyFrame(0f, "this.StartingValue"); scale.InsertExpressionKeyFrame(0.99f, "Vector3(scalex,scaley,1f)"); scale.InsertExpressionKeyFrame(1f, "this.FinalValue", step); scale.SetReferenceParameter("host", host); scale.SetScalarParameter("scalex", (float)ScaleX); scale.SetScalarParameter("scaley", (float)ScaleY); scale.Duration = Duration; scale.Target = "Scale"; opacity = host.Compositor.CreateScalarKeyFrameAnimation(); opacity.InsertExpressionKeyFrame(0f, "this.StartingValue"); opacity.InsertKeyFrame(0.99f, 0f); opacity.InsertKeyFrame(1f, 0f, step); opacity.Duration = Duration; opacity.Target = "Opacity"; group.Add(scale); group.Add(opacity); Animation = group; }
private void SetUpAnimationBehavior() { //setup Implicit Animation for BlurAmount change and Color Change. var implicitAnimations = _compositor.CreateImplicitAnimationCollection(); //Define animations to animate blur and color change. ScalarKeyFrameAnimation blurAnimation = _compositor.CreateScalarKeyFrameAnimation(); blurAnimation.InsertExpressionKeyFrame(1.0f, "this.FinalValue"); blurAnimation.Duration = TimeSpan.FromSeconds(1); blurAnimation.Target = "Blur.BlurAmount"; ColorKeyFrameAnimation tintAnimation = _compositor.CreateColorKeyFrameAnimation(); tintAnimation.InsertExpressionKeyFrame(1.0f, "this.FinalValue"); tintAnimation.Duration = TimeSpan.FromSeconds(1); tintAnimation.Target = "Tint.Color"; implicitAnimations["Blur.BlurAmount"] = blurAnimation; implicitAnimations["Tint.Color"] = tintAnimation; //Associate implicit animations to property sets. _brush.Properties.ImplicitAnimations = implicitAnimations; }
protected override void OnConnected(UIElement element) { var host = ElementCompositionPreview.GetElementVisual(element); var group = host.Compositor.CreateAnimationGroup(); var step = host.Compositor.CreateStepEasingFunction(); var offset = host.Compositor.CreateVector3KeyFrameAnimation(); offset.InsertExpressionKeyFrame(0f, "this.StartingValue"); offset.InsertExpressionKeyFrame(0.99f, "Vector3(this.FinalValue.X + offsetx,this.FinalValue.Y + offsety,this.FinalValue.Z)"); offset.InsertExpressionKeyFrame(1f, "this.FinalValue", step); offset.SetReferenceParameter("host", host); offset.SetScalarParameter("offsetx", (float)OffsetX); offset.SetScalarParameter("offsety", (float)OffsetY); offset.Duration = Duration; offset.Target = "Offset"; opacity = host.Compositor.CreateScalarKeyFrameAnimation(); opacity.InsertExpressionKeyFrame(0f, "this.FinalValue"); opacity.InsertKeyFrame(0.99f, 0f); opacity.InsertKeyFrame(1f, 0f, step); opacity.Duration = Duration; opacity.Target = "Opacity"; group.Add(offset); group.Add(opacity); Animation = group; }
public static KeyFrameAnimation CreateOpacityAnimation(Compositor compositor, TimeSpan duration) { ScalarKeyFrameAnimation kf = compositor.CreateScalarKeyFrameAnimation(); kf.InsertExpressionKeyFrame(1.0f, "this.FinalValue"); kf.Duration = duration; kf.Target = "Opacity"; return(kf); }
private void SetupAnimatingRefreshPanel() { Visual loadingVisual = ElementCompositionPreview.GetElementVisual(FirstGear); loadingVisual.Size = new Vector2((float)FirstGear.ActualWidth, (float)FirstGear.ActualHeight); loadingVisual.AnchorPoint = new Vector2(0.5f, 0.5f); // Animate the refresh panel icon using a simple rotating key frame animation ScalarKeyFrameAnimation _loadingMotionScalarAnimation = _compositor.CreateScalarKeyFrameAnimation(); var linear = _compositor.CreateLinearEasingFunction(); _loadingMotionScalarAnimation.InsertExpressionKeyFrame(0.0f, "this.StartingValue"); _loadingMotionScalarAnimation.InsertExpressionKeyFrame(1.0f, "this.StartingValue + 360", linear); _loadingMotionScalarAnimation.IterationBehavior = AnimationIterationBehavior.Forever; _loadingMotionScalarAnimation.Duration = TimeSpan.FromSeconds(2); loadingVisual.StartAnimation("RotationAngleInDegrees", _loadingMotionScalarAnimation); }
void TouchArea_ManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e) { // reset the animation // todo: wonder if there should be a method to remove a certain key frame? // so I'd only need to remove the keyframe (_animation.InsertKeyFrame(1.0f, new Vector3());) // rather than create a new animation instance _x = 0.0f; _animation = _compositor.CreateScalarKeyFrameAnimation(); _animation.InsertExpressionKeyFrame(0.0f, "touch.Offset.X"); _animation.SetReferenceParameter("touch", _touchAreaVisual); }
protected override void OnConnected(UIElement element) { var host = ElementCompositionPreview.GetElementVisual(element); opacity = host.Compositor.CreateScalarKeyFrameAnimation(); opacity.InsertKeyFrame(0f, 0f); opacity.InsertExpressionKeyFrame(1f, "this.FinalValue"); opacity.Duration = Duration; opacity.Target = "Opacity"; Animation = opacity; }
/// <summary> /// Creates a <see cref="ScalarKeyFrameAnimation"/> instance with the given parameters to on a target element, using an expression animation /// </summary> /// <param name="compositor">The current <see cref="Compositor"/> instance used to create the animation</param> /// <param name="from">The optional starting value for the animation</param> /// <param name="to">A string that indicates the final value for the animation</param> /// <param name="duration">The animation duration</param> /// <param name="delay">The optional initial delay for the animation</param> /// <param name="ease">The optional easing function for the animation</param> public static ScalarKeyFrameAnimation CreateScalarKeyFrameAnimation( this Compositor compositor, float? from, string to, TimeSpan duration, TimeSpan? delay, CompositionEasingFunction ease = null) { // Set duration and delay time ScalarKeyFrameAnimation ani = compositor.CreateScalarKeyFrameAnimation(); ani.Duration = duration; if (delay.HasValue) ani.DelayTime = delay.Value; // Insert "to" and "from" keyframes ani.InsertExpressionKeyFrame(1, to, ease ?? compositor.CreateLinearEasingFunction()); if (from.HasValue) ani.InsertKeyFrame(0, from.Value); return ani; }
protected override void OnConnected() { if (DesignMode.DesignModeEnabled) { return; } compositor = ElementCompositionPreview.GetElementVisual(Window.Current.Content as UIElement).Compositor; var tintOpacity = Convert.ToSingle(TintOpacity); if (tintOpacity < 0f) { tintOpacity = 0f; } if (tintOpacity > 1f) { tintOpacity = 1f; } var arithmeticEffect = new ArithmeticCompositeEffect() { Name = "arithmetic", MultiplyAmount = 0, Source1Amount = 1f - tintOpacity, Source2Amount = tintOpacity, Source1 = new ArithmeticCompositeEffect() { MultiplyAmount = 0f, Source1Amount = 0.95f, Source2Amount = 0.05f, Source1 = new GaussianBlurEffect() { Name = "blur", BlurAmount = Convert.ToSingle(BlurAmount), BorderMode = EffectBorderMode.Hard, Optimization = EffectOptimization.Balanced, Source = new CompositionEffectSourceParameter("source"), }, Source2 = new BorderEffect() { Source = new CompositionEffectSourceParameter("image"), ExtendX = CanvasEdgeBehavior.Wrap, ExtendY = CanvasEdgeBehavior.Wrap, } }, Source2 = new ColorSourceEffect() { Name = "tintcolor", Color = TintColor } }; Brush = compositor.CreateEffectFactory(arithmeticEffect, new[] { "arithmetic.Source1Amount", "arithmetic.Source2Amount", "tintcolor.Color" }).CreateBrush(); var imagesurface = LoadedImageSurface.StartLoadFromUri(new Uri("ms-appx:///FluentDesignSystem/Sketch/SketchTexture.jpg")); var imagebrush = compositor.CreateSurfaceBrush(imagesurface); imagebrush.Stretch = CompositionStretch.None; Brush.SetSourceParameter("image", imagebrush); switch (BackgroundSource) { case AcrylicBackgroundSource.Backdrop: Brush.SetSourceParameter("source", compositor.CreateBackdropBrush()); break; case AcrylicBackgroundSource.Hostbackdrop: Brush.SetSourceParameter("source", compositor.CreateHostBackdropBrush()); break; } CompositionBrush = Brush; var line = compositor.CreateLinearEasingFunction(); TintOpacityFillAnimation = compositor.CreateScalarKeyFrameAnimation(); TintOpacityFillAnimation.InsertExpressionKeyFrame(0f, "TintOpacity", line); TintOpacityFillAnimation.InsertKeyFrame(1f, 1f, line); TintOpacityFillAnimation.Duration = TimeSpan.FromSeconds(0.1d); TintOpacityFillAnimation.Target = "arithmetic.Source2Amount"; HostOpacityZeroAnimation = compositor.CreateScalarKeyFrameAnimation(); HostOpacityZeroAnimation.InsertExpressionKeyFrame(0f, "1f - TintOpacity", line); HostOpacityZeroAnimation.InsertKeyFrame(1f, 0f, line); HostOpacityZeroAnimation.Duration = TimeSpan.FromSeconds(0.1d); HostOpacityZeroAnimation.Target = "arithmetic.Source1Amount"; TintToFallBackAnimation = compositor.CreateColorKeyFrameAnimation(); TintToFallBackAnimation.InsertKeyFrame(0f, TintColor, line); TintToFallBackAnimation.InsertKeyFrame(1f, FallbackColor, line); TintToFallBackAnimation.Duration = TimeSpan.FromSeconds(0.1d); TintToFallBackAnimation.Target = "tintcolor.Color"; //Window.Current.Activated += Current_Activated; //Window.Current.VisibilityChanged += Current_VisibilityChanged; CoreWindow.GetForCurrentThread().Activated += AcrylicBrush_Activated; CoreWindow.GetForCurrentThread().VisibilityChanged += AcrylicBrush_VisibilityChanged; }
/// <summary> /// Handles the Arrange layout phase /// </summary> /// <param name="finalSize">Final Size of the control</param> /// <returns>Size</returns> protected override Size ArrangeOverride(Size finalSize) { if ((_compositor == null) || (_generator == null)) return base.ArrangeOverride(finalSize); if (Double.IsInfinity(finalSize.Width) || Double.IsInfinity(finalSize.Height) || Double.IsNaN(finalSize.Width) || Double.IsNaN(finalSize.Height)) return base.ArrangeOverride(finalSize); // Stop the animations and dispose the previous nodes // and their animations if (_isAnimationStarted) { for (var i = 0; i < _nodes.Count; i++) { _nodes[i].StopAnimation(AnimatedProperty); _animations[i].Dispose(); _animations[i] = null; _nodes[i].Dispose(); _nodes[i] = null; } _container.StopAnimation(AnimatedProperty); _containerAnimation.Dispose(); _containerAnimation = null; _container.Dispose(); _container = null; _animations.Clear(); _nodes.Clear(); _isAnimationStarted = false; } // Validate MaxNodes and ActiveNodes if ((MaxNodes <= 0) || (ActiveNodes <= 0)) return finalSize; // Coerce ActiveNodes to MaxNodes if ActiveNodes > MaxNodes if (ActiveNodes > MaxNodes) ActiveNodes = MaxNodes; // Take the smallest of the width or height var sideLength = (float)Math.Min(finalSize.Width, finalSize.Height); // Size of the progress ring displayed _ringSize = new Vector2(sideLength, sideLength); var sideHalf = sideLength / 2f; // Radius of each node _nodeRadius = (float)NodeSizeFactor * sideHalf; // Size of each node _nodeSize = new Vector2(_nodeRadius * 2f, _nodeRadius * 2f); // Radius of the node _ringRadius = sideHalf - _nodeRadius; // Each animation will consist of '_maxFrameBlocks' number of // FrameBlocks. Each FrameBlock will consist of keyframes which allow // the element being animated to move to the next slot and wait // at that slot until all other elements have moved to their next slot. // Each FrameBlock (except the last one) will have '_maxFramesPerBlock' // number of keyframes. The last keyframe in the last FrameBlock // will always be (1f, "this.StartingValue + 360") // Total number of FrameBlocks in each animation _maxFrameBlocks = ActiveNodes; // Total keyframes in each FrameBlock _maxFramesPerBlock = ActiveNodes + 1; // Total keyframes in each animation _maxKeyFrames = _maxFrameBlocks * _maxFramesPerBlock; // Normalized Progress Key unit value for each keyframe _keyFrameSlice = 1f / _maxKeyFrames; // ======================================================================== // NOTE: // gamma * maxNodes = 360 // gamma = alpha + beta // beta = 2 * Asin(nodeRadius / ringRadius) * (180 / Math.PI) // invisibleNodes = MaxNodes - ActiveNodes // phi = (invisibleNodes * gamma) // theta = phi - beta // ======================================================================== // gamma is the angle between adjacent nodes when maxNodes number of nodes are arranged in a circle _gamma = 360f / MaxNodes; // beta is the angle a node must travel after hitting the adjacent node _beta = 2f * (float)(Math.Asin(_nodeRadius / _ringRadius) * (180f / Math.PI)); // alpha is the smallest angle a node must travel before hitting the adjacent node _alpha = _gamma - _beta; // phi is the angle occupied by (MaxNodes - ActiveNodes) number of nodes _phi = (MaxNodes - ActiveNodes + 1) * _gamma; // theta is the largest angle a node must travel before hitting the adjacent node _theta = _phi - _beta; // Create the Animations _animations = CreateAnimations(); // Create the Container _container = _compositor.CreateContainerVisual(); _container.Size = _ringSize; _container.Offset = new Vector3(((float)finalSize.Width - sideLength) / 2f, ((float)finalSize.Height - sideLength) / 2f, 0f); _container.CenterPoint = new Vector3(_ringSize.X / 2f, _ringSize.Y / 2f, 0f); // Create the Nodes var offset = new Vector3(_nodeRadius, _ringSize.Y / 2f, 0); var centerPoint = new Vector3(_ringSize.X / 2f - _nodeRadius, 0, 0); _nodes = new List<SpriteVisual>(); var geometry = CanvasGeometry.CreateCircle(_generator.Device, new Vector2(_nodeRadius, _nodeRadius), _nodeRadius); // Create/Update the nodeMask var color = NodeColor; if (_nodeMask == null) { //Task.Run(async () => // { _nodeMask = _generator.CreateGeometrySurface(_nodeSize.ToSize(), geometry, color); // }) //.Wait(); } else { //Task.Run(async () => // { _nodeMask.Redraw(_nodeSize.ToSize(), geometry, color); // }) //.Wait(); } // Create the SurfaceBrush for the nodes var brush = _compositor.CreateSurfaceBrush(_nodeMask.Surface); var baseAngle = 0f; // Create the visuals for the nodes for (var i = 0; i < _maxFramesPerBlock; i++) { var node = _compositor.CreateSpriteVisual(); node.Size = _nodeSize; node.AnchorPoint = new Vector2(0.5f); node.Offset = offset; node.CenterPoint = centerPoint; node.Brush = brush; node.RotationAngleInDegrees = baseAngle; if (i == 0) { baseAngle += _phi; } else if (i == _maxFramesPerBlock - 2) { baseAngle = -_beta; } else { baseAngle += _gamma; } _nodes.Add(node); // Add the visual to the container _container.Children.InsertAtTop(node); } // Add the container to the Visual Tree ElementCompositionPreview.SetElementChildVisual(this, _container); // Start Node animations for (var i = 0; i < _maxFramesPerBlock; i++) { _nodes[i].StartAnimation(AnimatedProperty, _animations[i]); } // Start container animation _containerAnimation = _compositor.CreateScalarKeyFrameAnimation(); _containerAnimation.InsertExpressionKeyFrame(1f, "this.StartingValue + 360f", _compositor.CreateLinearEasingFunction()); _containerAnimation.Duration = RingDuration; _containerAnimation.IterationBehavior = AnimationIterationBehavior.Forever; _container.StartAnimation(AnimatedProperty, _containerAnimation); _isAnimationStarted = true; return finalSize; }
private void StartGearMotor(double secondsPerRotation) { // Start the first gear (the red one) if (_gearMotionScalarAnimation == null) { _gearMotionScalarAnimation = _compositor.CreateScalarKeyFrameAnimation(); var linear = _compositor.CreateLinearEasingFunction(); _gearMotionScalarAnimation.InsertExpressionKeyFrame(0.0f, "this.StartingValue"); _gearMotionScalarAnimation.InsertExpressionKeyFrame(1.0f, "this.StartingValue + 360", linear); _gearMotionScalarAnimation.IterationBehavior = AnimationIterationBehavior.Forever; } _gearMotionScalarAnimation.Duration = TimeSpan.FromSeconds(secondsPerRotation); _gearVisuals.First().StartAnimation("RotationAngleInDegrees", _gearMotionScalarAnimation); }
/// <summary> /// Handles the Arrange layout phase /// </summary> /// <param name="finalSize">Final Size of the control</param> /// <returns>Size</returns> protected override Size ArrangeOverride(Size finalSize) { if ((_compositor == null) || (_generator == null)) { return(base.ArrangeOverride(finalSize)); } if (Double.IsInfinity(finalSize.Width) || Double.IsInfinity(finalSize.Height) || Double.IsNaN(finalSize.Width) || Double.IsNaN(finalSize.Height)) { return(base.ArrangeOverride(finalSize)); } // Stop the animations and dispose the previous nodes // and their animations if (_isAnimationStarted) { for (var i = 0; i < _nodes.Count; i++) { _nodes[i].StopAnimation(AnimatedProperty); _animations[i].Dispose(); _animations[i] = null; _nodes[i].Dispose(); _nodes[i] = null; } _container.StopAnimation(AnimatedProperty); _containerAnimation.Dispose(); _containerAnimation = null; _container.Dispose(); _container = null; _animations.Clear(); _nodes.Clear(); _isAnimationStarted = false; } // Validate MaxNodes and ActiveNodes if ((MaxNodes <= 0) || (ActiveNodes <= 0)) { return(finalSize); } // Coerce ActiveNodes to MaxNodes if ActiveNodes > MaxNodes if (ActiveNodes > MaxNodes) { ActiveNodes = MaxNodes; } // Take the smallest of the width or height var sideLength = (float)Math.Min(finalSize.Width, finalSize.Height); // Size of the progress ring displayed _ringSize = new Vector2(sideLength, sideLength); var sideHalf = sideLength / 2f; // Radius of each node _nodeRadius = (float)NodeSizeFactor * sideHalf; // Size of each node _nodeSize = new Vector2(_nodeRadius * 2f, _nodeRadius * 2f); // Radius of the node _ringRadius = sideHalf - _nodeRadius; // Each animation will consist of '_maxFrameBlocks' number of // FrameBlocks. Each FrameBlock will consist of keyframes which allow // the element being animated to move to the next slot and wait // at that slot until all other elements have moved to their next slot. // Each FrameBlock (except the last one) will have '_maxFramesPerBlock' // number of keyframes. The last keyframe in the last FrameBlock // will always be (1f, "this.StartingValue + 360") // Total number of FrameBlocks in each animation _maxFrameBlocks = ActiveNodes; // Total keyframes in each FrameBlock _maxFramesPerBlock = ActiveNodes + 1; // Total keyframes in each animation _maxKeyFrames = _maxFrameBlocks * _maxFramesPerBlock; // Normalized Progress Key unit value for each keyframe _keyFrameSlice = 1f / _maxKeyFrames; // ======================================================================== // NOTE: // gamma * maxNodes = 360 // gamma = alpha + beta // beta = 2 * Asin(nodeRadius / ringRadius) * (180 / Math.PI) // invisibleNodes = MaxNodes - ActiveNodes // phi = (invisibleNodes * gamma) // theta = phi - beta // ======================================================================== // gamma is the angle between adjacent nodes when maxNodes number of nodes are arranged in a circle _gamma = 360f / MaxNodes; // beta is the angle a node must travel after hitting the adjacent node _beta = 2f * (float)(Math.Asin(_nodeRadius / _ringRadius) * (180f / Math.PI)); // alpha is the smallest angle a node must travel before hitting the adjacent node _alpha = _gamma - _beta; // phi is the angle occupied by (MaxNodes - ActiveNodes) number of nodes _phi = (MaxNodes - ActiveNodes + 1) * _gamma; // theta is the largest angle a node must travel before hitting the adjacent node _theta = _phi - _beta; // Create the Animations _animations = CreateAnimations(); // Create the Container _container = _compositor.CreateContainerVisual(); _container.Size = _ringSize; _container.Offset = new Vector3(((float)finalSize.Width - sideLength) / 2f, ((float)finalSize.Height - sideLength) / 2f, 0f); _container.CenterPoint = new Vector3(_ringSize.X / 2f, _ringSize.Y / 2f, 0f); // Create the Nodes var offset = new Vector3(_nodeRadius, _ringSize.Y / 2f, 0); var centerPoint = new Vector3(_ringSize.X / 2f - _nodeRadius, 0, 0); _nodes = new List <SpriteVisual>(); var geometry = CanvasGeometry.CreateCircle(_generator.Device, new Vector2(_nodeRadius, _nodeRadius), _nodeRadius); // Create/Update the nodeMask var color = NodeColor; if (_nodeMask == null) { //Task.Run(async () => // { _nodeMask = _generator.CreateGeometrySurface(_nodeSize.ToSize(), geometry, color); // }) //.Wait(); } else { //Task.Run(async () => // { _nodeMask.Redraw(_nodeSize.ToSize(), geometry, color); // }) //.Wait(); } // Create the SurfaceBrush for the nodes var brush = _compositor.CreateSurfaceBrush(_nodeMask.Surface); var baseAngle = 0f; // Create the visuals for the nodes for (var i = 0; i < _maxFramesPerBlock; i++) { var node = _compositor.CreateSpriteVisual(); node.Size = _nodeSize; node.AnchorPoint = new Vector2(0.5f); node.Offset = offset; node.CenterPoint = centerPoint; node.Brush = brush; node.RotationAngleInDegrees = baseAngle; if (i == 0) { baseAngle += _phi; } else if (i == _maxFramesPerBlock - 2) { baseAngle = -_beta; } else { baseAngle += _gamma; } _nodes.Add(node); // Add the visual to the container _container.Children.InsertAtTop(node); } // Add the container to the Visual Tree ElementCompositionPreview.SetElementChildVisual(this, _container); // Start Node animations for (var i = 0; i < _maxFramesPerBlock; i++) { _nodes[i].StartAnimation(AnimatedProperty, _animations[i]); } // Start container animation _containerAnimation = _compositor.CreateScalarKeyFrameAnimation(); _containerAnimation.InsertExpressionKeyFrame(1f, "this.StartingValue + 360f", _compositor.CreateLinearEasingFunction()); _containerAnimation.Duration = RingDuration; _containerAnimation.IterationBehavior = AnimationIterationBehavior.Forever; _container.StartAnimation(AnimatedProperty, _containerAnimation); _isAnimationStarted = true; return(finalSize); }
void InitConpositionResources() { easing = compositor.CreateCubicBezierEasingFunction(new Vector2(0.215f, 0.61f), new Vector2(0.355f, 1f)); steping = compositor.CreateStepEasingFunction(2); ProgressAnimation = compositor.CreateScalarKeyFrameAnimation(); ProgressAnimation.InsertExpressionKeyFrame(0f, "This.StartingValue", easing); ProgressAnimation.InsertExpressionKeyFrame(1f, "propSet.newvalue", easing); ProgressAnimation.SetReferenceParameter("propSet", propSet); ProgressAnimation.Duration = TimeSpan.FromSeconds(0.3d); ProgressAnimation.Target = "progress"; //ImplicitAnimations = compositor.CreateImplicitAnimationCollection(); //ImplicitAnimations["progress"] = ProgressAnimation; //propSet.ImplicitAnimations = ImplicitAnimations; TopBorderVisual = ElementCompositionPreview.GetElementVisual(TopBorder); BottomBorderVisual = ElementCompositionPreview.GetElementVisual(BottomBorder); CenterBorderVisual = ElementCompositionPreview.GetElementVisual(CenterBorder); ContentBorderVisual = ElementCompositionPreview.GetElementVisual(ContentBorder); TopBorderVisual.CenterPoint = new Vector3(38f, 36f, 0f); BottomBorderVisual.CenterPoint = new Vector3(39f, 36f, 0f); CenterBorderVisual.CenterPoint = new Vector3(36f, 36f, 0f); ContentBorderVisual.CenterPoint = new Vector3(36, 36, 0); TopRotationAnimation = compositor.CreateExpressionAnimation("0.25 * Pi * propSet.progress"); TopRotationAnimation.SetReferenceParameter("propSet", propSet); BottomRotationAnimation = compositor.CreateExpressionAnimation("-0.25 * Pi * propSet.progress"); BottomRotationAnimation.SetReferenceParameter("propSet", propSet); IconRotationAnimation = compositor.CreateExpressionAnimation("propSet.isopened == 1 ? -Pi * propSet.progress : Pi * propSet.progress"); IconRotationAnimation.SetReferenceParameter("propSet", propSet); ExternalScaleXAnimation = compositor.CreateExpressionAnimation(" 1 - 0.4 * propSet.progress"); ExternalScaleXAnimation.SetReferenceParameter("propSet", propSet); InternalScaleXAnimation = compositor.CreateExpressionAnimation(" 1 - 0.04 * propSet.progress"); InternalScaleXAnimation.SetReferenceParameter("propSet", propSet); IsOpenedAnimation = compositor.CreateScalarKeyFrameAnimation(); IsOpenedAnimation.InsertExpressionKeyFrame(0f, "This.StartingValue", steping); IsOpenedAnimation.InsertKeyFrame(1f, 1f, steping); IsOpenedAnimation.Duration = TimeSpan.FromSeconds(0.001d); IsOpenedAnimation.DelayTime = TimeSpan.FromSeconds(0.3d); IsNotOpenedAnimation = compositor.CreateScalarKeyFrameAnimation(); IsNotOpenedAnimation.InsertExpressionKeyFrame(0f, "This.StartingValue", steping); IsNotOpenedAnimation.InsertKeyFrame(1f, 0f, steping); IsNotOpenedAnimation.Duration = TimeSpan.FromSeconds(0.001d); IsNotOpenedAnimation.DelayTime = TimeSpan.FromSeconds(0.3d); TopBorderVisual.StartAnimation("RotationAngle", TopRotationAnimation); BottomBorderVisual.StartAnimation("RotationAngle", BottomRotationAnimation); ContentBorderVisual.StartAnimation("RotationAngle", IconRotationAnimation); TopBorderVisual.StartAnimation("Scale.X", ExternalScaleXAnimation); BottomBorderVisual.StartAnimation("Scale.X", ExternalScaleXAnimation); CenterBorderVisual.StartAnimation("Scale.X", InternalScaleXAnimation); }