forked from vueuse/vueuse
-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.ts
59 lines (52 loc) · 1.56 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import { watch } from 'vue-demi'
import type { MaybeComputedRef } from '@vueuse/shared'
import { resolveUnref } from '@vueuse/shared'
import type { UseAsyncStateOptions } from '../useAsyncState'
import { useAsyncState } from '../useAsyncState'
export interface UseImageOptions {
/** Address of the resource */
src: string
/** Images to use in different situations, e.g., high-resolution displays, small monitors, etc. */
srcset?: string
/** Image sizes for different page layouts */
sizes?: string
}
async function loadImage(options: UseImageOptions): Promise<HTMLImageElement> {
return new Promise((resolve, reject) => {
const img = new Image()
const { src, srcset, sizes } = options
img.src = src
if (srcset)
img.srcset = srcset
if (sizes)
img.sizes = sizes
img.onload = () => resolve(img)
img.onerror = reject
})
}
/**
* Reactive load an image in the browser, you can wait the result to display it or show a fallback.
*
* @see https://vueuse.org/useImage
* @param options Image attributes, as used in the <img> tag
* @param asyncStateOptions
*/
export const useImage = <Shallow extends true>(
options: MaybeComputedRef<UseImageOptions>,
asyncStateOptions: UseAsyncStateOptions<Shallow> = {},
) => {
const state = useAsyncState<HTMLImageElement | undefined>(
() => loadImage(resolveUnref(options)),
undefined,
{
resetOnExecute: true,
...asyncStateOptions,
},
)
watch(
() => resolveUnref(options),
() => state.execute(asyncStateOptions.delay),
{ deep: true },
)
return state
}