private TProperty GetInterpolatedValue() { if (_easingProgress == EasingTime || !Converter.SupportsInterpolate) { return(_currentValue); } double easingAmount = _easingProgress.TotalSeconds / EasingTime.TotalSeconds; return(Converter.Interpolate(_previousValue, _currentValue, Easings.Interpolate(easingAmount, EasingFunction))); }
/// <inheritdoc /> public override void Render(SKCanvas canvas, SKPointI basePosition) { if (Disposed) { throw new ObjectDisposedException("Folder"); } // Ensure the folder is ready if (!Enabled || !Children.Any(c => c.Enabled) || Path == null) { return; } // No point rendering if none of the children are going to render if (!Children.Any(c => c is RenderProfileElement renderElement && !renderElement.Timeline.IsFinished)) { return; } lock (Timeline) { foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => e.Enabled)) { baseLayerEffect.BaseProperties?.Update(Timeline); baseLayerEffect.Update(Timeline.Delta.TotalSeconds); } SKPaint layerPaint = new(); try { SKRectI rendererBounds = SKRectI.Create(0, 0, Bounds.Width, Bounds.Height); foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => e.Enabled)) { baseLayerEffect.PreProcess(canvas, rendererBounds, layerPaint); } canvas.SaveLayer(layerPaint); canvas.Translate(Bounds.Left - basePosition.X, Bounds.Top - basePosition.Y); // If required, apply the opacity override of the module to the root folder if (IsRootFolder && Profile.Module.OpacityOverride < 1) { double multiplier = Easings.SineEaseInOut(Profile.Module.OpacityOverride); layerPaint.Color = layerPaint.Color.WithAlpha((byte)(layerPaint.Color.Alpha * multiplier)); } // No point rendering if the alpha was set to zero by one of the effects if (layerPaint.Color.Alpha == 0) { return; } // Iterate the children in reverse because the first layer must be rendered last to end up on top for (int index = Children.Count - 1; index > -1; index--) { Children[index].Render(canvas, new SKPointI(Bounds.Left, Bounds.Top)); } foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => e.Enabled)) { baseLayerEffect.PostProcess(canvas, rendererBounds, layerPaint); } } finally { canvas.Restore(); layerPaint.DisposeSelfAndProperties(); } Timeline.ClearDelta(); } }
public override void Render(double deltaTime, SKCanvas canvas, SKImageInfo canvasInfo) { if (_disposed) { throw new ObjectDisposedException("Folder"); } if (Path == null || !Enabled || !Children.Any(c => c.Enabled)) { return; } // No need to render if at the end of the timeline if (TimelinePosition > TimelineLength) { return; } if (_folderBitmap == null) { _folderBitmap = new SKBitmap(new SKImageInfo((int)Path.Bounds.Width, (int)Path.Bounds.Height)); } else if (_folderBitmap.Info.Width != (int)Path.Bounds.Width || _folderBitmap.Info.Height != (int)Path.Bounds.Height) { _folderBitmap.Dispose(); _folderBitmap = new SKBitmap(new SKImageInfo((int)Path.Bounds.Width, (int)Path.Bounds.Height)); } using SKPath folderPath = new SKPath(Path); using SKCanvas folderCanvas = new SKCanvas(_folderBitmap); using SKPaint folderPaint = new SKPaint(); folderCanvas.Clear(); folderPath.Transform(SKMatrix.MakeTranslation(folderPath.Bounds.Left * -1, folderPath.Bounds.Top * -1)); SKPoint targetLocation = Path.Bounds.Location; if (Parent is Folder parentFolder) { targetLocation -= parentFolder.Path.Bounds.Location; } canvas.Save(); using SKPath clipPath = new SKPath(folderPath); clipPath.Transform(SKMatrix.MakeTranslation(targetLocation.X, targetLocation.Y)); canvas.ClipPath(clipPath); foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => e.Enabled)) { baseLayerEffect.PreProcess(folderCanvas, _folderBitmap.Info, folderPath, folderPaint); } // No point rendering if the alpha was set to zero by one of the effects if (folderPaint.Color.Alpha == 0) { return; } // Iterate the children in reverse because the first layer must be rendered last to end up on top for (int index = Children.Count - 1; index > -1; index--) { folderCanvas.Save(); ProfileElement profileElement = Children[index]; profileElement.Render(deltaTime, folderCanvas, _folderBitmap.Info); folderCanvas.Restore(); } // If required, apply the opacity override of the module to the root folder if (IsRootFolder && Profile.Module.OpacityOverride < 1) { double multiplier = Easings.SineEaseInOut(Profile.Module.OpacityOverride); folderPaint.Color = folderPaint.Color.WithAlpha((byte)(folderPaint.Color.Alpha * multiplier)); } foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => e.Enabled)) { baseLayerEffect.PostProcess(canvas, canvasInfo, folderPath, folderPaint); } canvas.DrawBitmap(_folderBitmap, targetLocation, folderPaint); canvas.Restore(); }
/// <inheritdoc /> public override void Render(SKCanvas canvas) { if (Disposed) { throw new ObjectDisposedException("Folder"); } // Ensure the folder is ready if (!Enabled || !Children.Any(c => c.Enabled) || Path == null) { return; } // No point rendering if none of the children are going to render if (!Children.Any(c => c is RenderProfileElement renderElement && !renderElement.Timeline.IsFinished)) { return; } lock (Timeline) { foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => e.Enabled)) { baseLayerEffect.BaseProperties?.Update(Timeline); baseLayerEffect.Update(Timeline.Delta.TotalSeconds); } try { canvas.Save(); Renderer.Open(Path, Parent as Folder); if (Renderer.Canvas == null || Renderer.Path == null || Renderer.Paint == null) { throw new ArtemisCoreException("Failed to open folder render context"); } SKRect rendererBounds = Renderer.Path.Bounds; foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => e.Enabled)) { baseLayerEffect.PreProcess(Renderer.Canvas, rendererBounds, Renderer.Paint); } // If required, apply the opacity override of the module to the root folder if (IsRootFolder && Profile.Module.OpacityOverride < 1) { double multiplier = Easings.SineEaseInOut(Profile.Module.OpacityOverride); Renderer.Paint.Color = Renderer.Paint.Color.WithAlpha((byte)(Renderer.Paint.Color.Alpha * multiplier)); } // No point rendering if the alpha was set to zero by one of the effects if (Renderer.Paint.Color.Alpha == 0) { return; } // Iterate the children in reverse because the first layer must be rendered last to end up on top for (int index = Children.Count - 1; index > -1; index--) { Children[index].Render(Renderer.Canvas); } foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => e.Enabled)) { baseLayerEffect.PostProcess(Renderer.Canvas, rendererBounds, Renderer.Paint); } canvas.DrawBitmap(Renderer.Bitmap, Renderer.TargetLocation, Renderer.Paint); } finally { canvas.Restore(); Renderer.Close(); } Timeline.ClearDelta(); } }