[css-images-4] Per WG resolution, cross-fade() takes 1+ arguments. De… · w3c/csswg-drafts@ab20b4c (original) (raw)
`@@ -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
`
`
395``
`-
cross-fade() = cross-fade( <> , <>? )
`
396``
`-
<cf-mixing-image> = <>? && <>
`
397``
`-
<cf-final-image> = <> | <>
`
``
393`+
cross-fade() = cross-fade( <># )
`
``
394`+
<cf-image> = <>? && [ <> | <> ]
`
398
395`
`
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 <> represents how much of the first image is retained
`
404
``
`-
when it is blended with the second image.
`
``
400
`+
The <> represents how much of each image is retained
`
``
401
`+
when it is blended with the other images.
`
405
402
` The <> 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 <>,
`
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(p A, B)'',
`
417
``
`-
where A and B are images
`
418
``
`-
and p is a percentage between 0% and 100%,
`
419
``
`-
the function represents an image
`
420
``
`-
with width equal to widthA × p + widthB × (1-p)
`
421
``
`-
and height equal to heightA × p + heightB × (1-p).
`
422
``
`-
The contents of the image must be constructed by
`
423
``
`-
first scaling A and B to the size of the generated image,
`
424
``
`-
then applying dissolve(A,p) plus dissolve(B,1-p).
`
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
`+
`
``
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
`+
`
``
423
+
``
424
`+
If a <> 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 <> arguments to the function;
`
``
434
`+
the <> arguments have no effect.
`
``
435
`+
They are calculated as follows:
`
``
436
+
``
437
`+
`
``
438
`+
To determine the intrinsic dimensions of a cross-fade():
`
``
439
+
``
440
`+
- Let |images| be an empty list.
`
``
441
+
``
442
`+
- For each |argument| of the ''cross-fade()'' function with an <> value:
`
``
443
`+
- Let |item| be a [=tuple=] consisting of a width, a height, and a percentage.
`
``
444
`+
- Run the [=object size negotation=] algorithm for the <>,
`
``
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
`+
- Set |item|’s percentage to the |argument|’s percentage.
`
``
449
+
``
450
`+
- If |images| is empty,
`
``
451
`+
return no intrinsic dimensions.
`
``
452
+
``
453
`+
- Let |percentage sum| be the sum of all the percentages of the [=list/items=] in |images|.
`
``
454
+
``
455
`+
- [=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
`+
- Let |final width| and |final height| be ''0px''.
`
``
462
+
``
463
`+
- [=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
`+
- Return an intrinsic width of |final width|
`
``
470
`+
and an intrinsic height of |final height|.
`
``
471
`+
`
``
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
`+
`
``
481
`+
To determine the appearance of a cross-fade():
`
``
482
+
``
483
`+
- Let |images| be an empty list.
`
``
484
+
``
485
`+
- 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
`+
- For each |argument| of the ''cross-fade()'' function:
`
``
491
`+
- Let |item| be a [=tuple=] consisting of an image and a percentage.
`
``
492
`+
- If |argument| has an <>,
`
``
493
`+
rescale it to |size|’s width and height
`
``
494
`+
and set |item|’s image to the result.
`
``
495
`+
Otherwise, |argument| has a <>;
`
``
496
`+
set |item|’s image to a solid-color image of the <>,
`
``
497
`+
with |size|’s dimensions.
`
``
498
`+
- Set |item|’s percentage to the |argument|’s percentage.
`
``
499
+
``
500
`+
- Let |percentage sum| be the sum of all the percentages of the [=list/items=] in |images|.
`
``
501
+
``
502
`+
- [=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
`+
- 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 dissolve operator to each source image,
`
``
513
`+
then combining them all together with the Porter-Duff plus operator. [[PORTER-DUFF]]
`
``
514
+
``
515
`+
Issue: What color space does this average take place in? sRGB? Controlled by @color-space?
`
``
516
+
``
517
`+
- 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 transparent black),
`
``
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 issue 2722
`
``
527
`+
for making ''transparent'' generally act like just “transparency”,
`
``
528
`+
rather than specifically being transparent black.
`
``
529
`+
We'd specify this by filtering them out in step 3.
`
``
530
+
``
531
`+
- Return |final image|.
`
``
532
`+
`
426
533
``
427
534
`<!--
`
428
535
`████████ ██ ████████ ██ ██ ████████ ██ ██ ████████ ███ ███
`