Improved image lazy loader

This commit is contained in:
Eduard Urbach 2017-06-24 17:38:10 +02:00
parent 873be1849f
commit c6694aef8c
7 changed files with 24 additions and 24 deletions

View File

@ -2,4 +2,4 @@ component AnimeGrid(animeList []*arn.Anime)
.anime-grid
each anime in animeList
a.anime-grid-cell.ajax(href="/anime/" + toString(anime.ID))
img.anime-grid-image(src=anime.Image.Small, alt=anime.Title.Romaji, title=anime.Title.Romaji + " (" + toString(anime.Rating.Overall) + ")")
img.anime-grid-image.lazy(data-src=anime.Image.Small, alt=anime.Title.Romaji, title=anime.Title.Romaji + " (" + toString(anime.Rating.Overall) + ")")

View File

@ -4,7 +4,7 @@ component Avatar(user *arn.User)
component AvatarNoLink(user *arn.User)
if user.HasAvatar()
img.user-image(src=user.SmallAvatar(), alt=user.Nick)
img.user-image.lazy(data-src=user.SmallAvatar(), alt=user.Nick)
else
SVGAvatar

View File

@ -57,7 +57,7 @@ component Profile(viewUser *arn.User, user *arn.User, animeList *arn.AnimeList,
else
each item in animeList.Items
a.profile-watching-list-item.ajax(href=item.Anime().Link(), title=item.Anime().Title.Canonical + " (" + toString(item.Episodes) + " / " + arn.EpisodesToString(item.Anime().EpisodeCount) + ")")
img.anime-cover-image.profile-watching-list-item-image(src=item.Anime().Image.Tiny, alt=item.Anime().Title.Canonical)
img.anime-cover-image.profile-watching-list-item-image.lazy(data-src=item.Anime().Image.Tiny, alt=item.Anime().Title.Canonical)
.profile-category.mountable
h3

View File

@ -87,39 +87,34 @@ export class AnimeNotifier {
actions[actionName](this, element, e)
})
// Use "action assigned" flag instead of removing the class.
// This will make sure that DOM diffs which restore the class name
// will not assign the action multiple times to the same element.
element["action assigned"] = true
}
}
lazyLoadImages() {
for(let element of findAll("user-image")) {
this.lazyLoadImage(element as HTMLImageElement)
}
for(let element of findAll("anime-cover-image")) {
for(let element of findAll("lazy")) {
this.lazyLoadImage(element as HTMLImageElement)
}
}
lazyLoadImage(img: HTMLImageElement) {
// Prevent browser from loading it instantly
img["original source"] = img.src
img.src = ""
// Once the image becomes visible, load it
img["became visible"] = () => {
img.src = img["original source"]
img.src = img.dataset.src
if(img.naturalWidth === 0) {
img.onload = function() {
this.classList.add("user-image-found")
this.classList.add("image-found")
}
img.onerror = function() {
this.classList.add("user-image-not-found")
this.classList.add("image-not-found")
}
} else {
img.classList.add("user-image-found")
img.classList.add("image-found")
}
}

View File

@ -32,6 +32,7 @@ mixin grid-image
height 100%
border-radius 3px
object-fit cover
default-transition
mixin grid-icon
font-size 2.5rem

11
styles/images.scarlet Normal file
View File

@ -0,0 +1,11 @@
.lazy
visibility hidden
opacity 0
.image-found
visibility visible
opacity 1 !important
.image-not-found
visibility hidden
opacity 0 !important

View File

@ -4,13 +4,6 @@
height avatar-size
border-radius 100%
object-fit cover
opacity 0
default-transition
:hover
box-shadow outline-shadow-heavy
.user-image-found
opacity 1 !important
.user-image-not-found
opacity 0 !important
box-shadow outline-shadow-heavy