@@ -376,8 +376,6 @@ Image Fallbacks and Annotations: the ''image()'' notation {#image-notation}
376
376
Combining images: the ''cross-fade()'' notation {#cross-fade-function}
377
377
----------------------------------------------------------------------
378
378
379
-
380
-
381
379
When transitioning between images,
382
380
CSS requires a way to explicitly refer to the intermediate image
383
381
that is a combination of the start and end images.
@@ -392,37 +390,146 @@ Combining images: the ''cross-fade()'' notation {#cross-fade-function}
392
390
The syntax for ''cross-fade()'' is defined as:
393
391
394
392
<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>> ]
398
395
</pre>
399
396
400
397
The function represents an image generated by
401
- combining two images.
398
+ combining two or more images.
402
399
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 .
405
402
The <<percentage>> must be between ''0%'' and ''100%'' inclusive;
406
403
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>
426
533
427
534
<!--
428
535
████████ ██ ████████ ██ ██ ████████ ██ ██ ████████ ███ ███
0 commit comments