1
0
Fork 0
mirror of https://github.com/immich-app/immich.git synced 2024-12-29 15:11:58 +00:00

chore(web): fade between thumbhash and thumbnail (#2856)

This commit is contained in:
Thomas 2023-06-19 22:21:06 +01:00 committed by GitHub
parent 93c35efe67
commit df74111427
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 106 additions and 83 deletions

131
web/package-lock.json generated
View file

@ -10,6 +10,7 @@
"dependencies": {
"@zoom-image/svelte": "^0.1.0",
"axios": "^0.27.2",
"buffer": "^6.0.3",
"copy-image-clipboard": "^2.1.2",
"handlebars": "^4.7.7",
"justified-layout": "^4.1.0",
@ -21,7 +22,7 @@
"socket.io-client": "^4.6.1",
"svelte-local-storage-store": "^0.5.0",
"svelte-material-icons": "^3.0.4",
"unlazy": "^0.8.9"
"thumbhash": "^0.1.1"
},
"devDependencies": {
"@babel/preset-env": "^7.20.2",
@ -4135,15 +4136,6 @@
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@unlazy/core": {
"version": "0.8.9",
"resolved": "https://registry.npmjs.org/@unlazy/core/-/core-0.8.9.tgz",
"integrity": "sha512-DQ4WB/cuEWTknU/59uRwpSipvMAJzBDmRyaHDUc1RcXi0Z7/Vcl0EE7BpROxEynqd1EI+2oMWQaDLyXffUdUiA==",
"dependencies": {
"fast-blurhash": "^1.1.2",
"thumbhash": "^0.1.1"
}
},
"node_modules/@zoom-image/core": {
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@zoom-image/core/-/core-0.18.2.tgz",
@ -4595,6 +4587,25 @@
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
"node_modules/base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
@ -4663,6 +4674,29 @@
"node-int64": "^0.4.0"
}
},
"node_modules/buffer": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.2.1"
}
},
"node_modules/buffer-crc32": {
"version": "0.2.13",
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
@ -5955,11 +5989,6 @@
"node": ">= 14"
}
},
"node_modules/fast-blurhash": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/fast-blurhash/-/fast-blurhash-1.1.2.tgz",
"integrity": "sha512-lJVOgYSlahqkRhrKumNx/SGB2F/qS0D1z7xjGYjb5EZJRtlzySGMniZjkQ9h9Rv8sPmM/V9orEgRiMwazDNH6A=="
},
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@ -6518,6 +6547,25 @@
"node": ">=4"
}
},
"node_modules/ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/ignore": {
"version": "5.2.4",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
@ -11461,18 +11509,6 @@
"node": ">= 4.0.0"
}
},
"node_modules/unlazy": {
"version": "0.8.9",
"resolved": "https://registry.npmjs.org/unlazy/-/unlazy-0.8.9.tgz",
"integrity": "sha512-lRCuXN20N1esqSQqtSVBLAw9GJz0lcBuOBs3UGGw7cFWHQlWJVZZ3OviwOl42f1CnVHjAON1rs2hIdJWgMAUyg==",
"dependencies": {
"@unlazy/core": "0.8.9"
},
"peerDependencies": {
"fast-blurhash": "^1.1.2",
"thumbhash": "^0.1.1"
}
},
"node_modules/update-browserslist-db": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz",
@ -14771,15 +14807,6 @@
"eslint-visitor-keys": "^3.3.0"
}
},
"@unlazy/core": {
"version": "0.8.9",
"resolved": "https://registry.npmjs.org/@unlazy/core/-/core-0.8.9.tgz",
"integrity": "sha512-DQ4WB/cuEWTknU/59uRwpSipvMAJzBDmRyaHDUc1RcXi0Z7/Vcl0EE7BpROxEynqd1EI+2oMWQaDLyXffUdUiA==",
"requires": {
"fast-blurhash": "^1.1.2",
"thumbhash": "^0.1.1"
}
},
"@zoom-image/core": {
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@zoom-image/core/-/core-0.18.2.tgz",
@ -15110,6 +15137,11 @@
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
"base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
},
"binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
@ -15156,6 +15188,15 @@
"node-int64": "^0.4.0"
}
},
"buffer": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
"requires": {
"base64-js": "^1.3.1",
"ieee754": "^1.2.1"
}
},
"buffer-crc32": {
"version": "0.2.13",
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
@ -16094,11 +16135,6 @@
"source-map-support": "^0.5.21"
}
},
"fast-blurhash": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/fast-blurhash/-/fast-blurhash-1.1.2.tgz",
"integrity": "sha512-lJVOgYSlahqkRhrKumNx/SGB2F/qS0D1z7xjGYjb5EZJRtlzySGMniZjkQ9h9Rv8sPmM/V9orEgRiMwazDNH6A=="
},
"fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@ -16517,6 +16553,11 @@
"harmony-reflect": "^1.4.6"
}
},
"ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
},
"ignore": {
"version": "5.2.4",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
@ -20074,14 +20115,6 @@
"integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
"dev": true
},
"unlazy": {
"version": "0.8.9",
"resolved": "https://registry.npmjs.org/unlazy/-/unlazy-0.8.9.tgz",
"integrity": "sha512-lRCuXN20N1esqSQqtSVBLAw9GJz0lcBuOBs3UGGw7cFWHQlWJVZZ3OviwOl42f1CnVHjAON1rs2hIdJWgMAUyg==",
"requires": {
"@unlazy/core": "0.8.9"
}
},
"update-browserslist-db": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz",

View file

@ -60,6 +60,7 @@
"dependencies": {
"@zoom-image/svelte": "^0.1.0",
"axios": "^0.27.2",
"buffer": "^6.0.3",
"copy-image-clipboard": "^2.1.2",
"handlebars": "^4.7.7",
"justified-layout": "^4.1.0",
@ -71,6 +72,6 @@
"socket.io-client": "^4.6.1",
"svelte-local-storage-store": "^0.5.0",
"svelte-material-icons": "^3.0.4",
"unlazy": "^0.8.9"
"thumbhash": "^0.1.1"
}
}

View file

@ -1,7 +1,8 @@
<script lang="ts">
import { onMount } from 'svelte';
import { lazyLoad } from 'unlazy';
import { imageLoad } from '$lib/utils/image-load';
import { fade } from 'svelte/transition';
import { thumbHashToDataURL } from 'thumbhash';
import { Buffer } from 'buffer';
export let url: string;
export let altText: string;
@ -11,48 +12,36 @@
export let curve = false;
export let shadow = false;
export let circle = false;
let loading = true;
let imageElement: HTMLImageElement;
onMount(() => {
if (thumbhash) {
lazyLoad(imageElement, {
hash: thumbhash,
hashType: 'thumbhash'
});
}
});
let complete = false;
</script>
{#if thumbhash}
<img
style:width={widthStyle}
style:height={heightStyle}
data-src={url}
alt={altText}
class="object-cover"
class:rounded-lg={curve}
class:shadow-lg={shadow}
class:rounded-full={circle}
draggable="false"
bind:this={imageElement}
/>
<img
style:width={widthStyle}
style:height={heightStyle}
src={url}
alt={altText}
class="object-cover transition-opacity duration-300"
class:rounded-lg={curve}
class:shadow-lg={shadow}
class:rounded-full={circle}
class:opacity-0={!thumbhash && !complete}
draggable="false"
use:imageLoad
on:image-load|once={() => (complete = true)}
/>
<!-- not everthing yet has thumbhash support so the old method is kept -->
{:else}
{#if thumbhash && !complete}
<img
style:width={widthStyle}
style:height={heightStyle}
src={url}
src={thumbHashToDataURL(Buffer.from(thumbhash, 'base64'))}
alt={altText}
class="object-cover transition-opacity duration-300"
class="absolute object-cover top-0"
class:rounded-lg={curve}
class:shadow-lg={shadow}
class:rounded-full={circle}
class:opacity-0={loading}
draggable="false"
use:imageLoad
on:image-load|once={() => (loading = false)}
out:fade={{ duration: 300 }}
/>
{/if}