mirror of
https://github.com/rio-labs/rio.git
synced 2026-01-06 13:19:51 -06:00
add loading animation to Image
This commit is contained in:
@@ -20,7 +20,6 @@ export type ImageState = ComponentState & {
|
||||
|
||||
export class ImageComponent extends ComponentBase<ImageState> {
|
||||
private imageElement: HTMLImageElement;
|
||||
private isLoading: boolean = false;
|
||||
private resizeObserver: ResizeObserver;
|
||||
|
||||
createElement(context: ComponentStatesUpdateContext): HTMLElement {
|
||||
@@ -57,15 +56,7 @@ export class ImageComponent extends ComponentBase<ImageState> {
|
||||
deltaState.imageUrl !== undefined &&
|
||||
this.imageElement.src !== deltaState.imageUrl
|
||||
) {
|
||||
// Until the image is loaded and we get access to its resolution,
|
||||
// let it fill the entire space. This is the correct size for all
|
||||
// `fill_mode`s except `"fit"` anyway, so there's no harm in setting
|
||||
// it now rather than later. (SVGs might temporarily render content
|
||||
// outside of the viewbox, but the only way to prevent that would be
|
||||
// to make the image invisible until loaded.)
|
||||
this.isLoading = true;
|
||||
this.imageElement.style.width = "100%";
|
||||
this.imageElement.style.height = "100%";
|
||||
this.element.classList.add("rio-loading");
|
||||
|
||||
this.imageElement.src = deltaState.imageUrl;
|
||||
|
||||
@@ -96,12 +87,12 @@ export class ImageComponent extends ComponentBase<ImageState> {
|
||||
}
|
||||
|
||||
private _onLoad(): void {
|
||||
this.isLoading = false;
|
||||
this.element.classList.remove("rio-loading");
|
||||
this._updateSize();
|
||||
}
|
||||
|
||||
private _updateSize(): void {
|
||||
if (this.isLoading) {
|
||||
if (this.element.classList.contains("rio-loading")) {
|
||||
// While loading a new image, the size is set to 100%. Don't
|
||||
// overwrite it.
|
||||
return;
|
||||
|
||||
@@ -1,5 +1,26 @@
|
||||
@import "../utils";
|
||||
|
||||
// A loading animation inspired by the "skeleton" effect
|
||||
@mixin loading-animation-shimmer {
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
var(--rio-local-bg) 25%,
|
||||
var(--rio-local-bg-active) 45%,
|
||||
var(--rio-local-bg-variant) 60%,
|
||||
var(--rio-local-bg) 75%
|
||||
);
|
||||
background-size: 400%;
|
||||
animation: shimmer 1.5s infinite linear;
|
||||
}
|
||||
@keyframes shimmer {
|
||||
0% {
|
||||
background-position-x: 100%;
|
||||
}
|
||||
100% {
|
||||
background-position-x: 0%;
|
||||
}
|
||||
}
|
||||
|
||||
.rio-image {
|
||||
pointer-events: none;
|
||||
|
||||
@@ -10,6 +31,19 @@
|
||||
@include kill-size-request-with-absolute();
|
||||
}
|
||||
|
||||
// Until the image is loaded and we get access to its resolution, let it
|
||||
// fill the entire space. This is the correct size for all `fill_mode`s
|
||||
// except `"fit"` anyway, so there's no harm in setting it now rather than
|
||||
// later. (SVGs might temporarily render content outside of the viewbox, but
|
||||
// the only way to prevent that would be to make the image invisible until
|
||||
// loaded.)
|
||||
&.rio-loading img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
@include loading-animation-shimmer();
|
||||
}
|
||||
|
||||
// Error icon
|
||||
svg {
|
||||
pointer-events: auto;
|
||||
|
||||
Reference in New Issue
Block a user