diff --git a/src/Pixeval.Controls/ZoomableImage/ZoomableImage.xaml.Frame.cs b/src/Pixeval.Controls/ZoomableImage/ZoomableImage.xaml.Frame.cs index e2c0d2f8..9726d4e1 100644 --- a/src/Pixeval.Controls/ZoomableImage/ZoomableImage.xaml.Frame.cs +++ b/src/Pixeval.Controls/ZoomableImage/ZoomableImage.xaml.Frame.cs @@ -38,9 +38,11 @@ public partial class ZoomableImage zoomableImage._timerRunning = false; // 使CanvasControl具有大小,否则不会触发CanvasControlOnDraw zoomableImage.OriginalImageWidth = zoomableImage.OriginalImageHeight = 10; - zoomableImage.InitSource(); + zoomableImage._initSource = true; } + private bool _initSource; + private async void InitSource() { _frames.Clear(); @@ -53,7 +55,8 @@ public partial class ZoomableImage { var randomAccessStream = source.AsRandomAccessStream(); randomAccessStream.Seek(0); - _frames.Add(await CanvasBitmap.LoadAsync(CanvasControl, randomAccessStream)); + var frame = await CanvasBitmap.LoadAsync(CanvasControl, randomAccessStream); + _frames.Add(frame); } } catch (Exception) @@ -80,6 +83,13 @@ public partial class ZoomableImage private void CanvasControlOnDraw(CanvasControl sender, CanvasDrawEventArgs e) { + if (_initSource) + { + _initSource = false; + InitSource(); + return; + } + if (!IsPlaying || _timerRunning) { if (_currentFrame is null) diff --git a/src/Pixeval.Controls/ZoomableImage/ZoomableImage.xaml.cs b/src/Pixeval.Controls/ZoomableImage/ZoomableImage.xaml.cs index c1ed979e..da8bdb35 100644 --- a/src/Pixeval.Controls/ZoomableImage/ZoomableImage.xaml.cs +++ b/src/Pixeval.Controls/ZoomableImage/ZoomableImage.xaml.cs @@ -78,6 +78,8 @@ public sealed partial class ZoomableImage : UserControl if (_frames.Count is 0) { await Task.Delay(20, _token.Token); + // 尝试触发加载资源 + CanvasControl.Invalidate(); } else { diff --git a/src/Pixeval/Controls/IllustratorItem/IllustratorIllustrationsOverview.xaml.cs b/src/Pixeval/Controls/IllustratorItem/IllustratorIllustrationsOverview.xaml.cs index c6870190..97ef5475 100644 --- a/src/Pixeval/Controls/IllustratorItem/IllustratorIllustrationsOverview.xaml.cs +++ b/src/Pixeval/Controls/IllustratorItem/IllustratorIllustrationsOverview.xaml.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using CommunityToolkit.WinUI; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Media; @@ -25,7 +24,6 @@ public sealed partial class IllustratorIllustrationsOverview Source = source, Stretch = Stretch.UniformToFill }; - UIElementExtensions.SetClipToBounds(image, true); Grid.SetColumn(image, i); BannerContainer.Children.Add(image); ++i; diff --git a/src/Pixeval/Controls/NovelItem/NovelItem.xaml b/src/Pixeval/Controls/NovelItem/NovelItem.xaml index ed6ba2aa..c46c5927 100644 --- a/src/Pixeval/Controls/NovelItem/NovelItem.xaml +++ b/src/Pixeval/Controls/NovelItem/NovelItem.xaml @@ -10,7 +10,6 @@ xmlns:interactivity="using:Microsoft.Xaml.Interactivity" xmlns:labs="using:CommunityToolkit.Labs.WinUI.MarkdownTextBlock" xmlns:local="using:Pixeval.Controls" - xmlns:markup="using:Pixeval.Controls.MarkupExtensions" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:model="using:Pixeval.CoreApi.Model" Background="{StaticResource CardBackgroundFillColorDefaultBrush}" diff --git a/src/Pixeval/Controls/NovelItem/NovelItem.xaml.cs b/src/Pixeval/Controls/NovelItem/NovelItem.xaml.cs index 6a578314..8415f76d 100644 --- a/src/Pixeval/Controls/NovelItem/NovelItem.xaml.cs +++ b/src/Pixeval/Controls/NovelItem/NovelItem.xaml.cs @@ -35,20 +35,18 @@ public sealed partial class NovelItem { var old = _isPointerOver; _isPointerOver = value; + var currentView = ConnectedAnimationService.GetForCurrentView(); if (IsPointerOver > 0 && old <= 0) { - var anim1 = ConnectedAnimationService.GetForCurrentView().PrepareToAnimate("ForwardConnectedAnimation1", this); - var anim2 = ConnectedAnimationService.GetForCurrentView().PrepareToAnimate("ForwardConnectedAnimation2", Image); - var anim3 = ConnectedAnimationService.GetForCurrentView().PrepareToAnimate("ForwardConnectedAnimation3", HeartButton); - var anim4 = ConnectedAnimationService.GetForCurrentView().PrepareToAnimate("ForwardConnectedAnimation4", TitleTextBlock); - var anim5 = ConnectedAnimationService.GetForCurrentView().PrepareToAnimate("ForwardConnectedAnimation5", AuthorTextBlock); - var anim6 = ConnectedAnimationService.GetForCurrentView().PrepareToAnimate("ForwardConnectedAnimation6", TagsList); - anim1.Configuration = new BasicConnectedAnimationConfiguration(); - anim2.Configuration = new BasicConnectedAnimationConfiguration(); - anim3.Configuration = new BasicConnectedAnimationConfiguration(); - anim4.Configuration = new BasicConnectedAnimationConfiguration(); - anim5.Configuration = new BasicConnectedAnimationConfiguration(); - anim6.Configuration = new BasicConnectedAnimationConfiguration(); + var anim1 = currentView.PrepareToAnimate("ForwardConnectedAnimation1", this); + var anim2 = currentView.PrepareToAnimate("ForwardConnectedAnimation2", Image); + var anim3 = currentView.PrepareToAnimate("ForwardConnectedAnimation3", HeartButton); + var anim4 = currentView.PrepareToAnimate("ForwardConnectedAnimation4", TitleTextBlock); + var anim5 = currentView.PrepareToAnimate("ForwardConnectedAnimation5", AuthorTextBlock); + var anim6 = currentView.PrepareToAnimate("ForwardConnectedAnimation6", TagsList); + anim1.Configuration = anim2.Configuration = anim3.Configuration = + anim4.Configuration = anim5.Configuration = anim6.Configuration = + new BasicConnectedAnimationConfiguration(); _ = anim1.TryStart(NovelItemPopup); _ = anim2.TryStart(PopupImage); _ = anim3.TryStart(PopupHeartButton); @@ -56,14 +54,32 @@ public sealed partial class NovelItem _ = anim5.TryStart(PopupAuthorTextBlock); _ = anim6.TryStart(PopupTagsList); NovelItemPopup.Child.To().Width = ActualWidth + 10; + NovelItemPopup.IsOpen = true; } - - if (IsPointerOver <= 0 && old > 0) + else if (IsPointerOver <= 0 && old > 0) { - // TODO: Backward connected animation + var anim1 = currentView.PrepareToAnimate("BackwardConnectedAnimation1", NovelItemPopup); + var anim2 = currentView.PrepareToAnimate("BackwardConnectedAnimation2", PopupImage); + var anim3 = currentView.PrepareToAnimate("BackwardConnectedAnimation3", PopupHeartButton); + var anim4 = currentView.PrepareToAnimate("BackwardConnectedAnimation4", PopupTitleTextBlock); + var anim5 = currentView.PrepareToAnimate("BackwardConnectedAnimation5", PopupAuthorTextBlock); + var anim6 = currentView.PrepareToAnimate("BackwardConnectedAnimation6", PopupTagsList); + anim1.Configuration = anim2.Configuration = anim3.Configuration = + anim4.Configuration = anim5.Configuration = anim6.Configuration = + new BasicConnectedAnimationConfiguration(); + anim1.Completed += (_, _) => + { + NovelItemPopup.IsOpen = false; + NovelItemPopup.Visibility = Visibility.Visible; + }; + _ = anim1.TryStart(this); + _ = anim2.TryStart(Image); + _ = anim3.TryStart(HeartButton); + _ = anim4.TryStart(TitleTextBlock); + _ = anim5.TryStart(AuthorTextBlock); + _ = anim6.TryStart(TagsList); + _ = Task.Delay(100).ContinueWith(_ => NovelItemPopup.Visibility = Visibility.Collapsed, TaskScheduler.FromCurrentSynchronizationContext()); } - - NovelItemPopup.IsOpen = IsPointerOver > 0; } } diff --git a/src/Pixeval/Pages/IllustrationViewer/IllustrationViewerPage.xaml b/src/Pixeval/Pages/IllustrationViewer/IllustrationViewerPage.xaml index 789913c9..540c814d 100644 --- a/src/Pixeval/Pages/IllustrationViewer/IllustrationViewerPage.xaml +++ b/src/Pixeval/Pages/IllustrationViewer/IllustrationViewerPage.xaml @@ -222,13 +222,12 @@ - + Source="{x:Bind ThumbnailSource, Mode=OneWay}" /> diff --git a/src/Pixeval/Pages/NovelViewer/NovelViewerPage.xaml b/src/Pixeval/Pages/NovelViewer/NovelViewerPage.xaml index 537ec2a1..7cbf66dc 100644 --- a/src/Pixeval/Pages/NovelViewer/NovelViewerPage.xaml +++ b/src/Pixeval/Pages/NovelViewer/NovelViewerPage.xaml @@ -320,13 +320,12 @@ - + Source="{x:Bind ThumbnailSource, Mode=OneWay}" /> diff --git a/src/Pixeval/Util/IO/FileCache.cs b/src/Pixeval/Util/IO/FileCache.cs index 4477aba8..7ea5fc47 100644 --- a/src/Pixeval/Util/IO/FileCache.cs +++ b/src/Pixeval/Util/IO/FileCache.cs @@ -396,7 +396,7 @@ public class FileCache ++HitCount; return typeof(T) switch { - var type when type == typeof(Stream) || type.IsAssignableTo(typeof(Stream)) => (T)(object)file.OpenRead(), + var type when type == typeof(Stream) || type.IsAssignableTo(typeof(Stream)) => (T)(object)await file.OpenRead().CopyToMemoryStreamAsync(true), var type when type == typeof(byte[]) => (T)(object)File.ReadAllBytesAsync(file.FullName), _ => await Functions.Block(async () => { diff --git a/src/Pixeval/Util/IO/IOHelper.cs b/src/Pixeval/Util/IO/IOHelper.cs index 1928061c..824ed92a 100644 --- a/src/Pixeval/Util/IO/IOHelper.cs +++ b/src/Pixeval/Util/IO/IOHelper.cs @@ -114,16 +114,22 @@ public static partial class IoHelper return httpClient.SendAsync(httpRequestMessage); } + public static async Task CopyToMemoryStreamAsync(this FileStream source, bool dispose) + { + var s = _recyclableMemoryStreamManager.GetStream(); + await source.CopyToAsync(s); + s.Position = 0; + if (dispose) + await source.DisposeAsync(); + return s; + } + public static async Task ReadZipArchiveEntriesAsync(Stream zipStream, bool dispose) { Stream s; - if (zipStream is FileStream) + if (zipStream is FileStream fs) { - s = _recyclableMemoryStreamManager.GetStream(); - await zipStream.CopyToAsync(s); - s.Position = 0; - if (dispose) - await zipStream.DisposeAsync(); + s = await fs.CopyToMemoryStreamAsync(dispose); dispose = true; } else