Skip to content

Commit ab20b4c

Browse files
committed
[css-images-4] Per WG resolution, cross-fade() takes 1+ arguments. Define sizing and painting of the new function arguments in detail.
1 parent 1f55cc3 commit ab20b4c

File tree

1 file changed

+134
-27
lines changed

1 file changed

+134
-27
lines changed

css-images-4/Overview.bs

+134-27
Original file line numberDiff line numberDiff line change
@@ -376,8 +376,6 @@ Image Fallbacks and Annotations: the ''image()'' notation {#image-notation}
376376
Combining 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>&lt;cf-mixing-image></dfn> = <<percentage>>? && <<image>>
397-
<dfn>&lt;cf-final-image></dfn> = <<image>> | <<color>>
393+
<dfn caniuse="css-cross-fade">cross-fade()</dfn> = cross-fade( <<cf-image>># )
394+
<dfn>&lt;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> &times; <var>p</var> + width<sub>B</sub> &times; (1-<var>p</var>)</code>
421-
and height equal to <code>height<sub>A</sub> &times; <var>p</var> + height<sub>B</sub> &times; (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

Comments
 (0)