react-native-fast-image 8.30.0 → 8.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +457 -210
- package/android/src/main/java/com/dylanvann/fastimage/FastImageApngRenderer.java +12 -1
- package/app.plugin.js +1 -1
- package/dist/index.d.ts +357 -63
- package/ios/FastImage/FFFAnimatedAVIFCoder.h +11 -0
- package/ios/FastImage/FFFAnimatedAVIFCoder.m +103 -0
- package/ios/FastImage/FFFastImageSource.h +4 -0
- package/ios/FastImage/FFFastImageSource.m +36 -2
- package/ios/FastImage/FFFastImageViewManager.m +1 -2
- package/package.json +4 -2
|
@@ -87,6 +87,8 @@ final class FastImageApngRenderer {
|
|
|
87
87
|
// How many times the file says it plays (0: forever).
|
|
88
88
|
private final int plays;
|
|
89
89
|
private volatile boolean paused = false;
|
|
90
|
+
// Once a frame has been rendered (on the decoder's thread).
|
|
91
|
+
private volatile boolean rendered = false;
|
|
90
92
|
|
|
91
93
|
ApngDrawable(Loader loader, int plays) {
|
|
92
94
|
super(loader);
|
|
@@ -110,7 +112,10 @@ final class FastImageApngRenderer {
|
|
|
110
112
|
// while paused.
|
|
111
113
|
setAutoPlay(!paused);
|
|
112
114
|
if (paused) {
|
|
113
|
-
|
|
115
|
+
// Before the first frame, onStart pauses once it's rendered:
|
|
116
|
+
// the decoder's start clears a pause, then skips rendering if
|
|
117
|
+
// one came in meanwhile, which left the view blank.
|
|
118
|
+
if (rendered) pause();
|
|
114
119
|
} else {
|
|
115
120
|
resume();
|
|
116
121
|
}
|
|
@@ -130,6 +135,12 @@ final class FastImageApngRenderer {
|
|
|
130
135
|
super.start();
|
|
131
136
|
}
|
|
132
137
|
|
|
138
|
+
@Override
|
|
139
|
+
public void onRender(ByteBuffer byteBuffer) {
|
|
140
|
+
super.onRender(byteBuffer);
|
|
141
|
+
rendered = true;
|
|
142
|
+
}
|
|
143
|
+
|
|
133
144
|
// On its decoder thread, once starting has drawn the first frame:
|
|
134
145
|
// starting clears a pause made before it got there, so pause again.
|
|
135
146
|
@Override
|
package/app.plugin.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// "plugins": [["react-native-fast-image", { "maxDiskSize": 209715200 }]]
|
|
5
5
|
//
|
|
6
6
|
// maxDiskSize (bytes), maxDiskAge (seconds, iOS) and maxMemorySize (bytes,
|
|
7
|
-
// iOS); 0 means no limit. See the README's
|
|
7
|
+
// iOS); 0 means no limit. See the README's Native config section.
|
|
8
8
|
|
|
9
9
|
const INFO_PLIST_KEYS = {
|
|
10
10
|
maxDiskSize: 'FastImageMaxDiskSize',
|
package/dist/index.d.ts
CHANGED
|
@@ -1,40 +1,103 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { StyleProp, ViewStyle, ImageRequireSource, AccessibilityProps, ViewProps } from 'react-native';
|
|
3
3
|
import { cacheControl, priority, resizeMode } from './constants';
|
|
4
4
|
type ColorValue = NonNullable<ViewStyle['backgroundColor']>;
|
|
5
|
+
/** How the image fits the view: see [`resizeMode`](#resizemode). */
|
|
5
6
|
export type ResizeMode = 'contain' | 'cover' | 'stretch' | 'center' | 'repeat';
|
|
7
|
+
/** An image's load priority: see [`source.priority`](#sourcepriority). */
|
|
6
8
|
export type Priority = 'low' | 'normal' | 'high';
|
|
9
|
+
/** How fresh an image must be: see [`source.cache`](#sourcecache). */
|
|
7
10
|
export type Cache = 'immutable' | 'web' | 'cacheOnly';
|
|
11
|
+
/** A remote image to load, and how to load and cache it. */
|
|
8
12
|
export type Source = {
|
|
13
|
+
/**
|
|
14
|
+
* Remote url to load the image from. e.g. `'https://example.com/image.jpg'`.
|
|
15
|
+
*
|
|
16
|
+
* Also loads local files (`file://`, and on Android `content://`), photo
|
|
17
|
+
* library images on iOS (`ph://`, see
|
|
18
|
+
* [Photo library images](#photo-library-images-ios)) and SVG images (see
|
|
19
|
+
* [SVG images](docs/formats.md#svg-images)).
|
|
20
|
+
*/
|
|
9
21
|
uri?: string;
|
|
22
|
+
/** Headers to load the image with. e.g. `{ Authorization: 'someAuthToken' }`. */
|
|
10
23
|
headers?: {
|
|
11
24
|
[key: string]: string;
|
|
12
25
|
};
|
|
26
|
+
/**
|
|
27
|
+
* A hint for which images to start loading first when several are
|
|
28
|
+
* waiting: `'high'` ones before `'normal'` ones, and `'low'` ones after.
|
|
29
|
+
* It's best effort, not an order: several images load at once, and when
|
|
30
|
+
* each finishes depends on its size and the network.
|
|
31
|
+
*
|
|
32
|
+
* - `'low'`: e.g. images further down a list.
|
|
33
|
+
* - `'normal'`: the default.
|
|
34
|
+
* - `'high'`: e.g. the image the screen is about.
|
|
35
|
+
*
|
|
36
|
+
* @default 'normal'
|
|
37
|
+
*/
|
|
13
38
|
priority?: Priority;
|
|
39
|
+
/**
|
|
40
|
+
* How fresh the image must be. See
|
|
41
|
+
* [how caching is handled](docs/how-is-caching-handled.md) for how the
|
|
42
|
+
* options fit together.
|
|
43
|
+
*
|
|
44
|
+
* - `'immutable'`: loads the image once, then shows the cached copy until
|
|
45
|
+
* its url (or `cacheKey`) changes.
|
|
46
|
+
* - `'web'`: follows the server's HTTP cache headers, as a browser does,
|
|
47
|
+
* checking with the server when it loads. These responses are kept in
|
|
48
|
+
* their own HTTP cache (50 MB on each platform), which `clearDiskCache`
|
|
49
|
+
* also clears.
|
|
50
|
+
* - `'cacheOnly'`: only shows a cached image, without making a request.
|
|
51
|
+
*
|
|
52
|
+
* @default 'immutable'
|
|
53
|
+
*/
|
|
14
54
|
cache?: Cache;
|
|
15
55
|
/**
|
|
16
|
-
* The key the image is cached under, instead of its uri.
|
|
17
|
-
* change while the image stays the same, e.g. signed urls with a
|
|
18
|
-
* an expiry
|
|
56
|
+
* The key the image is cached under, instead of its uri. Use it for urls
|
|
57
|
+
* that change while the image stays the same, e.g. signed urls with a
|
|
58
|
+
* token or an expiry. Use something that identifies the image, and change
|
|
59
|
+
* it when the image changes (e.g. include a version or the time it was
|
|
60
|
+
* updated), or the old image keeps showing.
|
|
61
|
+
*
|
|
62
|
+
* Not used with `cache: 'web'`, which follows the HTTP cache (keyed by
|
|
63
|
+
* url).
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```jsx
|
|
67
|
+
* <FastImage
|
|
68
|
+
* source={{
|
|
69
|
+
* uri: signedUrl,
|
|
70
|
+
* cacheKey: `avatar-${user.id}-${user.avatarUpdatedAt}`,
|
|
71
|
+
* }}
|
|
72
|
+
* />
|
|
73
|
+
* ```
|
|
19
74
|
*/
|
|
20
75
|
cacheKey?: string;
|
|
21
76
|
/**
|
|
22
|
-
* Whether the decoded image is kept in the memory cache
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
77
|
+
* Whether the decoded image is kept in the memory cache. With `false`
|
|
78
|
+
* it's only kept on disk: a view doesn't leave it in memory once it stops
|
|
79
|
+
* showing it, and `FastImage.preload` downloads it without decoding it.
|
|
80
|
+
* Use it for large images that are shown once or rarely, like a
|
|
81
|
+
* full-screen photo: a decoded photo can take tens of MB of memory. Images
|
|
82
|
+
* shown again, like a list scrolled back, are decoded from disk again.
|
|
83
|
+
*
|
|
84
|
+
* @default true
|
|
27
85
|
*/
|
|
28
86
|
memoryCache?: boolean;
|
|
29
87
|
/**
|
|
30
|
-
* With several sources (`source` as an array), the image's
|
|
31
|
-
* uri in pixels (
|
|
32
|
-
* loads the source closest to its own size.
|
|
88
|
+
* With several sources (`source` as an array), the image's width at this
|
|
89
|
+
* uri, in pixels (times `scale`, if given).
|
|
33
90
|
*/
|
|
34
91
|
width?: number;
|
|
92
|
+
/**
|
|
93
|
+
* With several sources (`source` as an array), the image's height at this
|
|
94
|
+
* uri, in pixels (times `scale`, if given).
|
|
95
|
+
*/
|
|
35
96
|
height?: number;
|
|
97
|
+
/** With several sources, the scale `width` and `height` are multiplied by. */
|
|
36
98
|
scale?: number;
|
|
37
99
|
};
|
|
100
|
+
/** How the image fades in: see [`transition`](#transition). */
|
|
38
101
|
export type Transition = {
|
|
39
102
|
/**
|
|
40
103
|
* How long the fade takes, in milliseconds; 0 means no fade. Defaults to
|
|
@@ -64,6 +127,11 @@ export type Transition = {
|
|
|
64
127
|
*/
|
|
65
128
|
skipOnCacheHit?: 'none' | 'memory' | 'all' | null;
|
|
66
129
|
};
|
|
130
|
+
/**
|
|
131
|
+
* `onLoad`'s event: `nativeEvent` has the image's `width` and `height`, in
|
|
132
|
+
* pixels, and `target`, the view's React tag (missing on Android with the
|
|
133
|
+
* legacy architecture).
|
|
134
|
+
*/
|
|
67
135
|
export interface OnLoadEvent {
|
|
68
136
|
nativeEvent: {
|
|
69
137
|
width: number;
|
|
@@ -71,11 +139,19 @@ export interface OnLoadEvent {
|
|
|
71
139
|
target?: number;
|
|
72
140
|
};
|
|
73
141
|
}
|
|
142
|
+
/**
|
|
143
|
+
* `onError`'s event: `nativeEvent.error` says what went wrong, e.g. an HTTP
|
|
144
|
+
* status code or an image that can't be decoded.
|
|
145
|
+
*/
|
|
74
146
|
export interface OnErrorEvent {
|
|
75
147
|
nativeEvent: {
|
|
76
148
|
error: string;
|
|
77
149
|
};
|
|
78
150
|
}
|
|
151
|
+
/**
|
|
152
|
+
* A load's result, as `onLoadEnd` gets it: `ok` with the image's size, or not
|
|
153
|
+
* `ok` with the error (as `onLoad` and `onError` get them).
|
|
154
|
+
*/
|
|
79
155
|
export type LoadResult = {
|
|
80
156
|
ok: true;
|
|
81
157
|
width: number;
|
|
@@ -84,17 +160,46 @@ export type LoadResult = {
|
|
|
84
160
|
ok: false;
|
|
85
161
|
error: string;
|
|
86
162
|
};
|
|
163
|
+
/**
|
|
164
|
+
* `configureCache`'s changes: a number (0 for no limit), or `null` to go back
|
|
165
|
+
* to the app's native config (Info.plist, AndroidManifest.xml) or the
|
|
166
|
+
* platform's default. Leave one out to keep it. Changes are saved, and used on
|
|
167
|
+
* the next launches too. Android only has `maxDiskSize`.
|
|
168
|
+
*/
|
|
87
169
|
export interface CacheLimits {
|
|
170
|
+
/**
|
|
171
|
+
* The most bytes of images kept on disk. When it's over, the least
|
|
172
|
+
* recently used are removed (on iOS, until it's half this size). Default:
|
|
173
|
+
* no limit on iOS, 250 MB on Android.
|
|
174
|
+
*/
|
|
88
175
|
maxDiskSize?: number | null;
|
|
176
|
+
/**
|
|
177
|
+
* iOS: the seconds an image is kept on disk after it was last used, or 0
|
|
178
|
+
* to keep them until `maxDiskSize` removes them. Default: 1 week.
|
|
179
|
+
*/
|
|
89
180
|
maxDiskAge?: number | null;
|
|
181
|
+
/**
|
|
182
|
+
* iOS: the most bytes of decoded images kept in memory. Default: no limit
|
|
183
|
+
* (they're removed when the system is low on memory).
|
|
184
|
+
*/
|
|
90
185
|
maxMemorySize?: number | null;
|
|
91
186
|
}
|
|
187
|
+
/**
|
|
188
|
+
* `configureCache`'s result: the limits in effect (0 for no limit), and the
|
|
189
|
+
* bytes the disk cache uses now. Android only has `maxDiskSize` and
|
|
190
|
+
* `diskSize`, and neither if the app has its own `AppGlideModule`.
|
|
191
|
+
*/
|
|
92
192
|
export interface CacheState {
|
|
93
193
|
maxDiskSize?: number;
|
|
94
194
|
maxDiskAge?: number;
|
|
95
195
|
maxMemorySize?: number;
|
|
196
|
+
/** The bytes the disk cache uses now. */
|
|
96
197
|
diskSize?: number;
|
|
97
198
|
}
|
|
199
|
+
/**
|
|
200
|
+
* `getCachePath`'s and `writeToCache`'s result: `ok` with the file's path, or
|
|
201
|
+
* not `ok` with the error.
|
|
202
|
+
*/
|
|
98
203
|
export type CachePathResult = {
|
|
99
204
|
ok: true;
|
|
100
205
|
path: string;
|
|
@@ -102,6 +207,10 @@ export type CachePathResult = {
|
|
|
102
207
|
ok: false;
|
|
103
208
|
error: string;
|
|
104
209
|
};
|
|
210
|
+
/**
|
|
211
|
+
* `onProgress`'s event: `nativeEvent` has the bytes `loaded` and the `total`,
|
|
212
|
+
* and `progress`, `loaded / total` from 0 to 1.
|
|
213
|
+
*/
|
|
105
214
|
export interface OnProgressEvent {
|
|
106
215
|
nativeEvent: {
|
|
107
216
|
loaded: number;
|
|
@@ -115,116 +224,301 @@ export interface ImageStyle extends ViewStyle {
|
|
|
115
224
|
}
|
|
116
225
|
export interface FastImageProps extends AccessibilityProps, ViewProps {
|
|
117
226
|
/**
|
|
118
|
-
*
|
|
119
|
-
* same image at different sizes
|
|
120
|
-
*
|
|
227
|
+
* Source for the remote image to load: a `Source`, a `require()`d image,
|
|
228
|
+
* or an array of the same image at different sizes.
|
|
229
|
+
*
|
|
230
|
+
* When `source` changes, the image that's showing stays until the new one
|
|
231
|
+
* has loaded. In views that get reused for other content, such as rows in
|
|
232
|
+
* FlashList or recyclerlistview, set `recyclingKey` so a reused row
|
|
233
|
+
* doesn't show the previous row's image.
|
|
234
|
+
*
|
|
235
|
+
* **Several sizes of an image.** `source` can also be an array of the
|
|
236
|
+
* same image at different sizes, each with its `width` and `height` in
|
|
237
|
+
* pixels (times `scale`, if it has one). The view loads the one whose size
|
|
238
|
+
* is closest to its own, in pixels, so a small view downloads a small
|
|
239
|
+
* image:
|
|
240
|
+
*
|
|
241
|
+
* ```jsx
|
|
242
|
+
* <FastImage
|
|
243
|
+
* style={{ width: 120, height: 120 }}
|
|
244
|
+
* source={[
|
|
245
|
+
* { uri: 'https://example.com/photo-200.jpg', width: 200, height: 200 },
|
|
246
|
+
* { uri: 'https://example.com/photo-800.jpg', width: 800, height: 800 },
|
|
247
|
+
* ]}
|
|
248
|
+
* />
|
|
249
|
+
* ```
|
|
250
|
+
*
|
|
251
|
+
* - The view picks once it has been laid out. One that has no size (e.g.
|
|
252
|
+
* sized from `onLoad`) loads the largest.
|
|
253
|
+
* - When the view's size changes so that another size fits better, it
|
|
254
|
+
* loads that one (with its load events), and keeps showing the current
|
|
255
|
+
* image until then, without a `transition`.
|
|
256
|
+
* - Each size is cached separately. A `cacheKey` applies to its own entry:
|
|
257
|
+
* give each size its own key (or none), or the sizes would replace each
|
|
258
|
+
* other in the cache.
|
|
259
|
+
* - `FastImage.preload`, `getCachePath` and `writeToCache` take one size:
|
|
260
|
+
* pass the one a view will show. An array fails with
|
|
261
|
+
* `{ ok: false, error }`.
|
|
262
|
+
* - An array of one is the same as that source.
|
|
121
263
|
*/
|
|
122
264
|
source?: Source | Source[] | ImageRequireSource;
|
|
265
|
+
/**
|
|
266
|
+
* An asset loaded with `require(...)`, shown while the first image loads,
|
|
267
|
+
* and if an image fails to load. When `source` changes, the previous image
|
|
268
|
+
* shows while the new one loads instead (see `source` and
|
|
269
|
+
* `recyclingKey`).
|
|
270
|
+
*
|
|
271
|
+
* On Android, `defaultSource` doesn't show in debug builds: there the dev
|
|
272
|
+
* server serves `require()`d images, and `defaultSource` is only loaded
|
|
273
|
+
* from the app's resources.
|
|
274
|
+
*/
|
|
123
275
|
defaultSource?: ImageRequireSource;
|
|
276
|
+
/**
|
|
277
|
+
* How the image fills the view.
|
|
278
|
+
*
|
|
279
|
+
* - `'contain'`: scales it uniformly (keeping its aspect ratio) so all of
|
|
280
|
+
* it fits in the view (minus padding).
|
|
281
|
+
* - `'cover'`: scales it uniformly (keeping its aspect ratio) so it covers
|
|
282
|
+
* the view (minus padding), cropping what doesn't fit.
|
|
283
|
+
* - `'stretch'`: scales its width and height separately to fill the view,
|
|
284
|
+
* which can change its aspect ratio.
|
|
285
|
+
* - `'center'`: centers it at its own size, scaled down uniformly to fit
|
|
286
|
+
* if it's larger than the view.
|
|
287
|
+
* - `'repeat'`: repeats it to cover the view, from its top-left corner, at
|
|
288
|
+
* the image's own size in pixels (a bundled image at its size in
|
|
289
|
+
* points), scaled down to fit if it's larger than the view. An animated
|
|
290
|
+
* image repeats its first frame, and `defaultSource` repeats too.
|
|
291
|
+
*
|
|
292
|
+
* @default 'cover'
|
|
293
|
+
*/
|
|
124
294
|
resizeMode?: ResizeMode;
|
|
295
|
+
/**
|
|
296
|
+
* If true, the image is shown with React Native's `Image` instead, styled
|
|
297
|
+
* and laid out the same way. FastImage's own features, such as its
|
|
298
|
+
* caching options, `priority` and `transition`, don't apply.
|
|
299
|
+
*/
|
|
125
300
|
fallback?: boolean;
|
|
126
301
|
/**
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
302
|
+
* For views that get reused for other content, such as rows in FlashList
|
|
303
|
+
* or recyclerlistview. Set it to something that identifies the content,
|
|
304
|
+
* e.g. the item's id. When it changes, the image is cleared right away (to
|
|
305
|
+
* `defaultSource`, or blank) instead of staying until the new one has
|
|
306
|
+
* loaded. Unlike changing `key`, this keeps the view, which is what list
|
|
307
|
+
* recycling is for.
|
|
308
|
+
*
|
|
309
|
+
* @example
|
|
310
|
+
* ```jsx
|
|
311
|
+
* <FastImage recyclingKey={item.id} source={{ uri: item.imageUrl }} />
|
|
312
|
+
* ```
|
|
133
313
|
*/
|
|
134
314
|
recyclingKey?: string | null;
|
|
135
315
|
/**
|
|
136
|
-
* How many times an animated image (GIF, animated WebP, APNG,
|
|
137
|
-
* AVIF
|
|
138
|
-
*
|
|
139
|
-
*
|
|
316
|
+
* How many times an animated image (GIF, animated WebP, APNG, or animated
|
|
317
|
+
* AVIF) plays:
|
|
318
|
+
*
|
|
319
|
+
* - Not set: as many times as the file says (like a browser).
|
|
320
|
+
* - `true`: forever.
|
|
321
|
+
* - `false`: once.
|
|
322
|
+
* - A number: that many times.
|
|
323
|
+
*
|
|
324
|
+
* Changing it restarts the animation.
|
|
140
325
|
*/
|
|
141
326
|
loop?: boolean | number;
|
|
142
327
|
/**
|
|
143
328
|
* How the image is filtered when it's drawn smaller or larger than its
|
|
144
|
-
* size
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
329
|
+
* size (like CSS's `image-rendering`):
|
|
330
|
+
*
|
|
331
|
+
* - `'auto'`: the platform's usual filtering.
|
|
332
|
+
* - `'smooth'`: iOS only. Keeps a large image drawn much smaller than its
|
|
333
|
+
* size (e.g. a big photo as a thumbnail, or fine lines and text) from
|
|
334
|
+
* looking jagged or noisy. Such an image is already decoded at about the
|
|
335
|
+
* view's size by default (see `downsample`), so this is for images shown
|
|
336
|
+
* at less than half their size with `downsample={false}`, or a little
|
|
337
|
+
* smaller than their size. **It uses more memory:** the image is also
|
|
338
|
+
* kept at smaller sizes for drawing, about a third more than the decoded
|
|
339
|
+
* image. On Android it's the same as `'auto'` (images are always decoded
|
|
340
|
+
* at about the view's size there).
|
|
341
|
+
* - `'pixelated'`: sharp pixels, without smoothing, e.g. for pixel art
|
|
342
|
+
* drawn larger than its size. On Android, animated images are still
|
|
343
|
+
* smoothed.
|
|
344
|
+
*
|
|
345
|
+
* @default 'auto'
|
|
148
346
|
*/
|
|
149
347
|
imageRendering?: 'auto' | 'smooth' | 'pixelated';
|
|
150
348
|
/**
|
|
151
|
-
* Pauses an animated image (GIF, animated WebP, APNG,
|
|
152
|
-
*
|
|
349
|
+
* Pauses an animated image (GIF, animated WebP, APNG, or animated AVIF) on
|
|
350
|
+
* the frame it's showing; `false` plays it again from there
|
|
153
351
|
* (on Android, an animated WebP or AVIF plays again from its first frame:
|
|
154
352
|
* Android can't resume one). Each image animates on its own, so pausing
|
|
155
353
|
* one doesn't pause others showing the same file.
|
|
156
354
|
*/
|
|
157
355
|
paused?: boolean;
|
|
158
356
|
/**
|
|
159
|
-
* Fades the image in when it loads
|
|
160
|
-
* a duration in milliseconds, or a `Transition
|
|
161
|
-
*
|
|
162
|
-
*
|
|
357
|
+
* Fades the image in when it loads. `true` uses the platform's usual
|
|
358
|
+
* fade, a number is the duration in milliseconds, or pass a `Transition`.
|
|
359
|
+
*
|
|
360
|
+
* Downloads, local files (`file://`, `content://`) and bundled images
|
|
361
|
+
* (`require()`) fade in. In lists that reuse views (e.g. FlashList), set
|
|
362
|
+
* `recyclingKey`, so a reused view starts empty and its image fades in,
|
|
363
|
+
* instead of showing the previous item's image until it loads.
|
|
364
|
+
*
|
|
365
|
+
* @default false
|
|
366
|
+
* @example
|
|
367
|
+
* ```jsx
|
|
368
|
+
* <FastImage source={{ uri }} transition />
|
|
369
|
+
* <FastImage source={{ uri }} transition={500} />
|
|
370
|
+
* <FastImage source={{ uri }} transition={{ betweenImages: true, skipOnCacheHit: 'none' }} />
|
|
371
|
+
* ```
|
|
163
372
|
*/
|
|
164
373
|
transition?: boolean | number | Transition | null;
|
|
165
374
|
/**
|
|
166
|
-
*
|
|
167
|
-
* takes much less memory.
|
|
168
|
-
*
|
|
169
|
-
* the
|
|
375
|
+
* Decodes a large image at about the size it's shown at, instead of at
|
|
376
|
+
* full size, so it takes much less memory.
|
|
377
|
+
*
|
|
378
|
+
* - `true`: an image at least twice the size its view needs is decoded
|
|
379
|
+
* at about the view's size. If the view grows, the image is decoded
|
|
380
|
+
* again for its new size (from the disk cache).
|
|
381
|
+
* - `false`: images are decoded at full size, e.g. for an image that's
|
|
382
|
+
* zoomed in on with a transform (a pinch-to-zoom viewer), which would
|
|
383
|
+
* otherwise show the smaller copy enlarged.
|
|
384
|
+
*
|
|
385
|
+
* It doesn't change `onLoad`'s width and height (the image's own size) or
|
|
386
|
+
* the cached file. Needs SDWebImage 5.19.7 or later: before 5.19 images
|
|
387
|
+
* are decoded at full size, and 5.19.0 to 5.19.6 show photos stored
|
|
388
|
+
* sideways with an EXIF orientation (most phone photos) sideways. Photo
|
|
389
|
+
* library images are always decoded this way, and on Android images are
|
|
390
|
+
* always decoded at about the view's size (but Android 16 and later
|
|
391
|
+
* decode animated WebP at full size, and scale it as they draw it).
|
|
392
|
+
*
|
|
393
|
+
* If you control the images, serve them at the size they're shown
|
|
394
|
+
* (resized on your server or by an image CDN), which also saves
|
|
395
|
+
* bandwidth.
|
|
396
|
+
*
|
|
397
|
+
* @platform ios
|
|
398
|
+
* @default true
|
|
170
399
|
*/
|
|
171
400
|
downsample?: boolean;
|
|
172
401
|
/**
|
|
173
|
-
* Blurs the image by this radius, in points
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
402
|
+
* Blurs the image by this radius, in points (the same radius looks about
|
|
403
|
+
* the same on iOS and Android). `0` is no blur.
|
|
404
|
+
*
|
|
405
|
+
* It's for still images, or a radius that changes now and then (e.g.
|
|
406
|
+
* blurring a photo behind a sheet). Each change blurs the image again on
|
|
407
|
+
* the CPU, so don't animate it.
|
|
408
|
+
*
|
|
409
|
+
* - Only the loaded image is blurred, not `defaultSource`.
|
|
410
|
+
* - An animated image (GIF, animated WebP, APNG or AVIF) shows its first frame,
|
|
411
|
+
* blurred, and doesn't animate.
|
|
412
|
+
* - With `tintColor`, the blurred image is tinted.
|
|
413
|
+
* - The image is blurred at about the size it's shown at, off the main
|
|
414
|
+
* thread. The cached file stays the original image, so `getCachePath`
|
|
415
|
+
* and other views of it aren't affected.
|
|
416
|
+
* - Changing it blurs the image that's showing again, without sending the
|
|
417
|
+
* load events again.
|
|
418
|
+
*
|
|
419
|
+
* To animate a blur, or to blur an animated image, use React Native's
|
|
420
|
+
* `filter` style instead, which the GPU draws:
|
|
421
|
+
* `style={{ filter: [{ blur: 6 }] }}`. It needs the New Architecture.
|
|
422
|
+
* React Native's docs list `blur` for Android 12+ only; on iOS it's behind
|
|
423
|
+
* an experimental React Native feature flag (`enableSwiftUIBasedFilters`,
|
|
424
|
+
* SwiftUI-based filters).
|
|
425
|
+
*
|
|
426
|
+
* @default 0
|
|
178
427
|
*/
|
|
179
428
|
blurRadius?: number;
|
|
429
|
+
/** Called when the image starts to load. */
|
|
180
430
|
onLoadStart?(): void;
|
|
181
|
-
onProgress?(event: OnProgressEvent): void;
|
|
182
|
-
onLoad?(event: OnLoadEvent): void;
|
|
183
|
-
onError?(event: OnErrorEvent): void;
|
|
184
431
|
/**
|
|
185
|
-
* Called
|
|
186
|
-
*
|
|
432
|
+
* Called while the image downloads, with the bytes `loaded` so far, the
|
|
433
|
+
* `total`, and `progress` (`loaded / total`, from 0 to 1; the last event
|
|
434
|
+
* has 1). Not called while the total is unknown (a response without a
|
|
435
|
+
* `Content-Length`).
|
|
436
|
+
*
|
|
437
|
+
* @example
|
|
438
|
+
* ```jsx
|
|
439
|
+
* onProgress={e => console.log(e.nativeEvent.progress)}
|
|
440
|
+
* ```
|
|
187
441
|
*/
|
|
188
|
-
|
|
442
|
+
onProgress?(event: OnProgressEvent): void;
|
|
189
443
|
/**
|
|
190
|
-
*
|
|
444
|
+
* Called on a successful image fetch. Called with the width and height of
|
|
445
|
+
* the image itself, not of the view (on iOS, in points: an `@2x` asset
|
|
446
|
+
* reports half its pixel size).
|
|
191
447
|
*
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
* {
|
|
448
|
+
* @example
|
|
449
|
+
* ```jsx
|
|
450
|
+
* onLoad={e => console.log(e.nativeEvent.width, e.nativeEvent.height)}
|
|
451
|
+
* ```
|
|
195
452
|
*/
|
|
196
|
-
|
|
453
|
+
onLoad?(event: OnLoadEvent): void;
|
|
197
454
|
/**
|
|
455
|
+
* Called on an image fetching error, with a message describing it (e.g.
|
|
456
|
+
* the HTTP status code).
|
|
198
457
|
*
|
|
199
|
-
*
|
|
458
|
+
* @example
|
|
459
|
+
* ```jsx
|
|
460
|
+
* onError={e => console.log(e.nativeEvent.error)}
|
|
461
|
+
* ```
|
|
200
462
|
*/
|
|
201
|
-
|
|
463
|
+
onError?(event: OnErrorEvent): void;
|
|
202
464
|
/**
|
|
203
|
-
*
|
|
465
|
+
* Called when the image finishes loading, whether it was successful or an
|
|
466
|
+
* error, with the result: `{ ok: true, width, height }` (the image's size,
|
|
467
|
+
* as `onLoad` gets it) or `{ ok: false, error }` (as `onError` gets it).
|
|
468
|
+
* TypeScript makes you check `ok` before reading the size or the error.
|
|
204
469
|
*
|
|
205
|
-
*
|
|
470
|
+
* @example
|
|
471
|
+
* ```jsx
|
|
472
|
+
* <FastImage
|
|
473
|
+
* source={{ uri }}
|
|
474
|
+
* onLoadEnd={(result) => {
|
|
475
|
+
* if (result.ok) setAspectRatio(result.width / result.height)
|
|
476
|
+
* else setFailed(result.error)
|
|
477
|
+
* }}
|
|
478
|
+
* />
|
|
479
|
+
* ```
|
|
206
480
|
*/
|
|
207
|
-
|
|
481
|
+
onLoadEnd?(result: LoadResult): void;
|
|
482
|
+
/**
|
|
483
|
+
* The image's style: View's style props (`borderRadius` clips the image),
|
|
484
|
+
* and `tintColor`, as with React Native's `Image` (the `tintColor` prop
|
|
485
|
+
* wins).
|
|
486
|
+
*/
|
|
487
|
+
style?: StyleProp<ImageStyle>;
|
|
208
488
|
/**
|
|
209
|
-
*
|
|
489
|
+
* If supplied, changes the color of all the non-transparent pixels to the
|
|
490
|
+
* given color.
|
|
210
491
|
*/
|
|
211
|
-
|
|
492
|
+
tintColor?: ColorValue;
|
|
212
493
|
/**
|
|
213
|
-
* Render children within the image.
|
|
494
|
+
* Render children within the image. In the next major version,
|
|
495
|
+
* `FastImage` won't render children: use `FastImageBackground`.
|
|
214
496
|
*/
|
|
215
497
|
children?: React.ReactNode;
|
|
216
498
|
}
|
|
499
|
+
/** A preloaded source that loaded (and is now cached). */
|
|
217
500
|
export interface PreloadSuccess {
|
|
501
|
+
/** The source's uri. */
|
|
218
502
|
uri: string;
|
|
219
503
|
ok: true;
|
|
504
|
+
/** The image's width (as in `onLoad`). */
|
|
220
505
|
width: number;
|
|
506
|
+
/** The image's height (as in `onLoad`). */
|
|
221
507
|
height: number;
|
|
222
508
|
}
|
|
509
|
+
/** A preloaded source that failed to load. */
|
|
223
510
|
export interface PreloadFailure {
|
|
511
|
+
/** The source's uri (none for a source without one, e.g. `null`). */
|
|
224
512
|
uri?: string;
|
|
225
513
|
ok: false;
|
|
514
|
+
/** What went wrong. */
|
|
226
515
|
error: string;
|
|
227
516
|
}
|
|
517
|
+
/**
|
|
518
|
+
* `preload`'s result for a source. Check `ok` to tell which it is: e.g.
|
|
519
|
+
* `if (result.ok)` narrows it to a `PreloadSuccess`, with its size. Reading
|
|
520
|
+
* `width` or `error` without checking is a type error.
|
|
521
|
+
*/
|
|
228
522
|
export type PreloadResult = PreloadSuccess | PreloadFailure;
|
|
229
523
|
export interface FastImageStaticProperties {
|
|
230
524
|
resizeMode: typeof resizeMode;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#import <SDWebImage/SDImageIOAnimatedCoder.h>
|
|
2
|
+
|
|
3
|
+
// Animated AVIFs (AVIF image sequences), decoded with ImageIO, which reads
|
|
4
|
+
// them where it reads AVIF (iOS 16 and later): SDWebImage's own coders decode
|
|
5
|
+
// an AVIF's first frame only. Still AVIFs keep SDWebImage's ImageIO coder.
|
|
6
|
+
// Registered with SDWebImage's coders by FFFastImageSource.
|
|
7
|
+
@interface FFFAnimatedAVIFCoder : SDImageIOAnimatedCoder
|
|
8
|
+
|
|
9
|
+
@property (nonatomic, class, readonly, nonnull) FFFAnimatedAVIFCoder* sharedCoder;
|
|
10
|
+
|
|
11
|
+
@end
|