@@ -32,6 +32,11 @@ const FORMAT_ALIASES = {
32
32
"svg+xml" : "svg" ,
33
33
} ;
34
34
35
+ const ANIMATED_TYPES = [
36
+ "webp" ,
37
+ "gif" ,
38
+ ] ;
39
+
35
40
36
41
class Image {
37
42
#input;
@@ -185,7 +190,7 @@ class Image {
185
190
return valid . sort ( ( a , b ) => a - b ) ;
186
191
}
187
192
188
- static getFormatsArray ( formats , autoFormat , svgShortCircuit ) {
193
+ static getFormatsArray ( formats , autoFormat , svgShortCircuit , isAnimated ) {
189
194
if ( formats && formats . length ) {
190
195
if ( typeof formats === "string" ) {
191
196
formats = formats . split ( "," ) ;
@@ -216,6 +221,17 @@ class Image {
216
221
} ) ;
217
222
}
218
223
224
+ if ( isAnimated ) {
225
+ let validAnimatedFormats = formats . filter ( f => ANIMATED_TYPES . includes ( f ) ) ;
226
+ // override formats if a valid animated format is found, otherwise leave as-is
227
+ if ( validAnimatedFormats . length > 0 ) {
228
+ debug ( "Filtering non-animated formats from output: from %o to %o" , formats , validAnimatedFormats ) ;
229
+ formats = validAnimatedFormats ;
230
+ } else {
231
+ debug ( "No animated output formats found for animated image, using static image instead." ) ;
232
+ }
233
+ }
234
+
219
235
// Remove duplicates (e.g., if null happens to coincide with an explicit format
220
236
// or a user passes in multiple duplicate values)
221
237
formats = [ ...new Set ( formats ) ] ;
@@ -426,11 +442,18 @@ class Image {
426
442
return orientation >= 5 && orientation <= 8 ;
427
443
}
428
444
445
+ isAnimated ( metadata , options ) {
446
+ // input has multiple pages: https://sharp.pixelplumbing.com/api-input#metadata
447
+ // sharp options have animated image support enabled
448
+ return metadata ?. pages > 1 && options ?. sharpOptions ?. animated ;
449
+ }
450
+
429
451
// metadata so far: width, height, format
430
452
// src is used to calculate the output file names
431
453
getFullStats ( metadata ) {
432
454
let results = [ ] ;
433
- let outputFormats = Image . getFormatsArray ( this . options . formats , metadata . format || this . options . overrideInputFormat , this . options . svgShortCircuit ) ;
455
+ let isImageAnimated = this . isAnimated ( metadata , this . options ) ;
456
+ let outputFormats = Image . getFormatsArray ( this . options . formats , metadata . format || this . options . overrideInputFormat , this . options . svgShortCircuit , isImageAnimated ) ;
434
457
435
458
if ( this . needsRotation ( metadata . orientation ) ) {
436
459
[ metadata . height , metadata . width ] = [ metadata . width , metadata . height ] ;
0 commit comments