add lazy image
2051e040
Simon Liebers
committed
succeeded
4 changed files
LazyImage.razor
/WPE.App.Shared.BaseComponents/Pages/Animations/LazyImage.razor+93
/WPE.App.Shared.BaseComponents/Pages/Animations/LazyImage.razor
Add comment 1 Plus  @using Infsoft.WPE.App.Shared.BaseComponents.Models.General
Add comment 2 Plus  @using Microsoft.JSInterop
Add comment 3 Plus  @using System.Net.Http
Add comment 4 Plus  
Add comment 5 Plus  @inject IJSRuntime JS
Add comment 6 Plus  @inject HttpClient Http
Add comment 7 Plus  
Add comment 8 Plus  @inherits StyledComponent
Add comment 9 Plus  @implements IAsyncDisposable
Add comment 10 Plus  
Add comment 11 Plus  <div class="@wrapperClass" style="@Style">
Add comment 12 Plus   <img class="@imageClass" id="@uid" />
Add comment 13 Plus   @if (!loaded)
Add comment 14 Plus   {
Add comment 15 Plus   <div class="loader skeleton" />
Add comment 16 Plus   }
Add comment 17 Plus  </div>
Add comment 18 Plus  
Add comment 19 Plus  @code {
Add comment 20 Plus   [Parameter]
Add comment 21 Plus   [EditorRequired]
Add comment 22 Plus   public required string Url { get; set; }
Add comment 23 Plus  
Add comment 24 Plus   [Parameter]
Add comment 25 Plus   public bool FillParent { get; set; } = false;
Add comment 26 Plus  
Add comment 27 Plus   private string uid = Guid.NewGuid().ToString();
Add comment 28 Plus   private bool loaded = false;
Add comment 29 Plus   private string currentUrl = "";
Add comment 30 Plus  
Add comment 31 Plus   private IJSObjectReference? module;
Add comment 32 Plus  
Add comment 33 Plus   private string wrapperClass => GetWrapperClass();
Add comment 34 Plus   private string imageClass => loaded ? "image loaded" : "image";
Add comment 35 Plus  
Add comment 36 Plus   protected override void OnParametersSet()
Add comment 37 Plus   {
Add comment 38 Plus   base.OnParametersSet();
Add comment 39 Plus  
Add comment 40 Plus   if (currentUrl != Url)
Add comment 41 Plus   {
Add comment 42 Plus   currentUrl = Url;
Add comment 43 Plus   _ = LoadImage();
Add comment 44 Plus   }
Add comment 45 Plus   }
Add comment 46 Plus  
Add comment 47 Plus   protected async override Task OnAfterRenderAsync(bool firstRender)
Add comment 48 Plus   {
Add comment 49 Plus   if (firstRender)
Add comment 50 Plus   {
Add comment 51 Plus   module = await JS.InvokeAsync<IJSObjectReference>(
Add comment 52 Plus   "import", $"./_content/{typeof(LazyImage).Assembly.GetName().Name}/Pages/Animations/LazyImage.razor.js");
Add comment 53 Plus  
Add comment 54 Plus   _ = LoadImage();
Add comment 55 Plus   }
Add comment 56 Plus   }
Add comment 57 Plus  
Add comment 58 Plus   private async Task LoadImage()
Add comment 59 Plus   {
Add comment 60 Plus   loaded = false;
Add comment 61 Plus   this.StateHasChanged();
Add comment 62 Plus  
Add comment 63 Plus   var stream = await Http.GetStreamAsync(Url);
Add comment 64 Plus   await SetImage(uid, stream);
Add comment 65 Plus   loaded = true;
Add comment 66 Plus  
Add comment 67 Plus   await Task.Delay(200);
Add comment 68 Plus   this.StateHasChanged();
Add comment 69 Plus   }
Add comment 70 Plus  
Add comment 71 Plus   private string GetWrapperClass()
Add comment 72 Plus   {
Add comment 73 Plus   string wrapperClass = loaded ? "lazy-image skeleton-wrapper" : "lazy-image skeleton-wrapper-anim skeleton-wrapper";
Add comment 74 Plus   wrapperClass += FillParent ? " fill" : "";
Add comment 75 Plus   return wrapperClass;
Add comment 76 Plus   }
Add comment 77 Plus  
Add comment 78 Plus   private async Task SetImage(string imageElementId, Stream imageStream)
Add comment 79 Plus   {
Add comment 80 Plus   var dotnetImageStream = new DotNetStreamReference(imageStream);
Add comment 81 Plus  
Add comment 82 Plus   if (module != null)
Add comment 83 Plus   await module.InvokeVoidAsync("SetLazyImage", imageElementId, dotnetImageStream);
Add comment 84 Plus   }
Add comment 85 Plus  
Add comment 86 Plus   async ValueTask IAsyncDisposable.DisposeAsync()
Add comment 87 Plus   {
Add comment 88 Plus   if (module is not null)
Add comment 89 Plus   {
Add comment 90 Plus   await module.DisposeAsync();
Add comment 91 Plus   }
Add comment 92 Plus   }
Add comment 93 Plus  }
LazyImage.razor.css
/WPE.App.Shared.BaseComponents/Pages/Animations/LazyImage.razor.css+36
/WPE.App.Shared.BaseComponents/Pages/Animations/LazyImage.razor.css
Add comment 1 Plus  .lazy-image {
Add comment 2 Plus   position: relative;
Add comment 3 Plus   width: 100%;
Add comment 4 Plus   overflow: hidden;
Add comment 5 Plus  }
Add comment 6 Plus  
Add comment 7 Plus   .lazy-image .image {
Add comment 8 Plus   position: relative;
Add comment 9 Plus   width: 100%;
Add comment 10 Plus   display: block;
Add comment 11 Plus   object-fit: cover;
Add comment 12 Plus   transition: .2s;
Add comment 13 Plus   }
Add comment 14 Plus  
Add comment 15 Plus   .lazy-image .image:not(.loaded) {
Add comment 16 Plus   visibility: hidden;
Add comment 17 Plus   opacity: 0;
Add comment 18 Plus   }
Add comment 19 Plus  
Add comment 20 Plus   .lazy-image .loader {
Add comment 21 Plus   position: absolute;
Add comment 22 Plus   inset: 0;
Add comment 23 Plus   }
Add comment 24 Plus  
Add comment 25 Plus   .lazy-image.fill {
Add comment 26 Plus   width: 100%;
Add comment 27 Plus   height: 100%;
Add comment 28 Plus   overflow: hidden;
Add comment 29 Plus   }
Add comment 30 Plus  
Add comment 31 Plus   .lazy-image.fill .image {
Add comment 32 Plus   width: 100%;
Add comment 33 Plus   height: 100%;
Add comment 34 Plus   overflow: hidden;
Add comment 35 Plus   }
Add comment 36 Plus  
LazyImage.razor.js
/WPE.App.Shared.BaseComponents/Pages/Animations/LazyImage.razor.js+15
/WPE.App.Shared.BaseComponents/Pages/Animations/LazyImage.razor.js
Add comment 1 Plus  export const SetLazyImage = async (imageElementId, imageStream) => {
Add comment 2 Plus   try {
Add comment 3 Plus   const arrayBuffer = await imageStream.arrayBuffer();
Add comment 4 Plus   const blob = new Blob([arrayBuffer]);
Add comment 5 Plus   const url = URL.createObjectURL(blob);
Add comment 6 Plus   const image = document.getElementById(imageElementId);
Add comment 7 Plus   image.onload = () => {
Add comment 8 Plus   URL.revokeObjectURL(url);
Add comment 9 Plus   }
Add comment 10 Plus   image.src = url;
Add comment 11 Plus   }
Add comment 12 Plus   catch (e) {
Add comment 13 Plus   console.log(e);
Add comment 14 Plus   }
Add comment 15 Plus  }
WPE.App.Shared.BaseComponents.csproj
/WPE.App.Shared.BaseComponents/WPE.App.Shared.BaseComponents.csproj
/WPE.App.Shared.BaseComponents/WPE.App.Shared.BaseComponents.csproj