@@ -376,8 +376,6 @@ Image Fallbacks and Annotations: the ''image()'' notation {#image-notation}
376376Combining images: the ''cross-fade()'' notation {#cross-fade-function}
377377----------------------------------------------------------------------
378378
379-
380-
381379 When transitioning between images,
382380 CSS requires a way to explicitly refer to the intermediate image
383381 that is a combination of the start and end images.
@@ -392,37 +390,146 @@ Combining images: the ''cross-fade()'' notation {#cross-fade-function}
392390 The syntax for ''cross-fade()'' is defined as:
393391
394392 <pre class=prod>
395- <dfn caniuse="css-cross-fade">cross-fade()</dfn> = cross-fade( <<cf-mixing-image>> , <<cf-final-image>> ? )
396- <dfn><cf-mixing-image></dfn> = <<percentage>> ? && <<image>>
397- <dfn><cf-final-image></dfn> = <<image>> | <<color>>
393+ <dfn caniuse="css-cross-fade">cross-fade()</dfn> = cross-fade( <<cf-image>> # )
394+ <dfn><cf-image></dfn> = <<percentage>> ? && [ <<image>> | <<color>> ]
398395 </pre>
399396
400397 The function represents an image generated by
401- combining two images.
398+ combining two or more images.
402399
403- The <<percentage>> represents how much of the first image is retained
404- when it is blended with the second image .
400+ The <<percentage>> represents how much of each image is retained
401+ when it is blended with the other images .
405402 The <<percentage>> must be between ''0%'' and ''100%'' inclusive;
406403 any other value is invalid.
407- If omitted,
408- it defaults to the value ''50%'' .
409-
410- If the last argument is a <<color>> ,
411- it represents a solid-color image with the same intrinsic dimensions as the first image.
412- If omitted,
413- it defaults to the color ''transparent'' .
414-
415- More precisely,
416- given ''cross-fade(<var>p</var> <var>A</var>, <var>B</var>)'' ,
417- where <var> A</var> and <var> B</var> are images
418- and <var> p</var> is a percentage between 0% and 100%,
419- the function represents an image
420- with width equal to <code> width<sub> A</sub> × <var> p</var> + width<sub> B</sub> × (1-<var> p</var> )</code>
421- and height equal to <code> height<sub> A</sub> × <var> p</var> + height<sub> B</sub> × (1-<var> p</var> )</code> .
422- The contents of the image must be constructed by
423- first scaling <var> A</var> and <var> B</var> to the size of the generated image,
424- then applying <code> dissolve(<var> A</var> ,<var> p</var> ) plus dissolve(<var> B</var> ,1-<var> p</var> )</code> .
425- The "dissolve()" function and "plus" compositing operator are defined in the literature by Porter-Duff. [[PORTERDUFF]]
404+
405+ If any percentages are omitted,
406+ all the specified percentages are summed together
407+ and subtracted from ''100%'' ,
408+ the result is floored at ''0%'' ,
409+ then divided equally between all images with omitted percentages
410+ at computed-value time.
411+
412+ <div class=note>
413+ While this is not reflected in the computed value,
414+ when all the arguments’ percentages sum to greater than ''100%'' ,
415+ the sizing/painting details effectively rescale them so that they sum to exactly ''100%'' .
416+
417+ On the other hand,
418+ when the sum is less than ''100%'' ,
419+ the sizing/painting details effectively act like there's an additional ''transparent'' argument,
420+ with its percentage set to the remaining value
421+ necessary to make the sum equal ''100%'' .
422+ </div>
423+
424+ If a <<color>> is provided,
425+ it represents a solid-color image
426+ with “automatic” dimensions
427+ (it doesn't participate in the sizing of the result image at all;
428+ see details in the sizing details below).
429+
430+ ### ''cross-fade()'' Sizing ### {#cross-fade-sizing}
431+
432+ The dimensions of the image represented by a ''cross-fade()''
433+ are a weighted average of dimensions of the <<image>> arguments to the function;
434+ the <<color>> arguments have no effect.
435+ They are calculated as follows:
436+
437+ <div algorithm>
438+ To determine the <dfn export>intrinsic dimensions of a cross-fade()</dfn> :
439+
440+ 1. Let |images| be an empty list.
441+
442+ 2. For each |argument| of the ''cross-fade()'' function with an <<image>> value:
443+ 1. Let |item| be a [=tuple=] consisting of a width, a height, and a percentage.
444+ 2. Run the [=object size negotation=] algorithm for the <<image>> ,
445+ as appropriate for the context in which the ''cross-fade()'' appears,
446+ and set |item|’s width and height
447+ to the width and height of the resulting [=concrete object size=] .
448+ 3. Set |item|’s percentage to the |argument|’s percentage.
449+
450+ 3. If |images| is empty,
451+ return no intrinsic dimensions.
452+
453+ 4. Let |percentage sum| be the sum of all the percentages of the [=list/items=] in |images|.
454+
455+ 5. [=list/For each=] |item| in |images|,
456+ divide |item|’s percentage by |percentage sum|,
457+ and set |item|’s percentage to the result.
458+
459+ Assert: The percentages in |images| now sum to ''100%'' .
460+
461+ 6. Let |final width| and |final height| be ''0px'' .
462+
463+ 7. [=list/For each=] |item| in |images|,
464+ multiply |item|’s width by |item|’s percentage
465+ and add the result to |final width|,
466+ and multiply |item|’s height by |item|’s percentage
467+ and add the result to |final height|.
468+
469+ 8. Return an intrinsic width of |final width|
470+ and an intrinsic height of |final height|.
471+ </div>
472+
473+ ### ''cross-fade()'' Painting ### {#cross-fade-painting}
474+
475+ The image represented by a ''cross-fade()''
476+ is a weighted average of the input arguments to the function,
477+ calculated as follows:
478+
479+
480+ <div algorithm>
481+ To determine the <dfn export>appearance of a cross-fade()</dfn> :
482+
483+ 1. Let |images| be an empty list.
484+
485+ 2. Let |size| be a [=tuple=] of width and height,
486+ initialized to the result of finding the [=concrete object size=]
487+ of the ''cross-fade()'' function
488+ (using the [=intrinsic dimensions of a cross-fade()=] ).
489+
490+ 3. For each |argument| of the ''cross-fade()'' function:
491+ 1. Let |item| be a [=tuple=] consisting of an image and a percentage.
492+ 2. If |argument| has an <<image>> ,
493+ rescale it to |size|’s width and height
494+ and set |item|’s image to the result.
495+ Otherwise, |argument| has a <<color>> ;
496+ set |item|’s image to a solid-color image of the <<color>> ,
497+ with |size|’s dimensions.
498+ 3. Set |item|’s percentage to the |argument|’s percentage.
499+
500+ 4. Let |percentage sum| be the sum of all the percentages of the [=list/items=] in |images|.
501+
502+ 5. [=list/For each=] |item| in |images|,
503+ divide |item|’s percentage by |percentage sum|,
504+ and set |item|’s percentage to the result.
505+
506+ 6. Let |final image| be an image
507+ with |size|’s dimensions,
508+ and every pixel being the weighted linear average of the corresponding pixels of [=list/each=] |item|’s image in |images|,
509+ weighted according to the |item|’s percentage.
510+ (Average both the color channels and the alpha channel of the pixels.)
511+
512+ Note: This is applying the Porter-Duff <code> dissolve</code> operator to each source image,
513+ then combining them all together with the Porter-Duff <code> plus</code> operator. [[PORTER-DUFF]]
514+
515+ Issue: What color space does this average take place in? sRGB? Controlled by @color-space?
516+
517+ 8. If |percentage sum| is less than ''100%'' ,
518+ multiply the alpha channel of every pixel in |final image| by |percentage sum|.
519+
520+ Note: This ensures that ''cross-fade(img 50%)'' doesn't darken the image
521+ (as would happen by blending with <a>transparent black</a> ),
522+ but just makes it more transparent,
523+ as the author almost certainly intends.
524+
525+ Issue: Should this also apply to explicit ''transparent'' arguments?
526+ See <a href="https://github.com/w3c/csswg-drafts/issues/2722">issue 2722</a>
527+ for making ''transparent'' generally act like just “transparency”,
528+ rather than specifically being <a>transparent black</a> .
529+ We'd specify this by filtering them out in step 3.
530+
531+ 8. Return |final image|.
532+ </div>
426533
427534<!--
428535████████ ██ ████████ ██ ██ ████████ ██ ██ ████████ ███ ███
0 commit comments