[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

`+

  1. Let |images| be an empty list.

`

``

441

+

``

442

`+

  1. For each |argument| of the ''cross-fade()'' function with an <> value:

`

``

443

`+

  1. Let |item| be a [=tuple=] consisting of a width, a height, and a percentage.

`

``

444

`+

  1. 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

`+

  1. Set |item|’s percentage to the |argument|’s percentage.

`

``

449

+

``

450

`+

  1. If |images| is empty,

`

``

451

`+

return no intrinsic dimensions.

`

``

452

+

``

453

`+

  1. Let |percentage sum| be the sum of all the percentages of the [=list/items=] in |images|.

`

``

454

+

``

455

`+

  1. [=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

`+

  1. Let |final width| and |final height| be ''0px''.

`

``

462

+

``

463

`+

  1. [=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

`+

  1. 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

`+

  1. Let |images| be an empty list.

`

``

484

+

``

485

`+

  1. 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

`+

  1. For each |argument| of the ''cross-fade()'' function:

`

``

491

`+

  1. Let |item| be a [=tuple=] consisting of an image and a percentage.

`

``

492

`+

  1. 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

`+

  1. Set |item|’s percentage to the |argument|’s percentage.

`

``

499

+

``

500

`+

  1. Let |percentage sum| be the sum of all the percentages of the [=list/items=] in |images|.

`

``

501

+

``

502

`+

  1. [=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

`+

  1. 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

`+

  1. 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

`+

  1. Return |final image|.

`

``

532

`+

`

426

533

``

427

534

`<!--

`

428

535

`████████ ██ ████████ ██ ██ ████████ ██ ██ ████████ ███ ███

`