Re: [fxtf-drafts] [filter-effects-2] Add recolor() shorthand (#334)

Is there a reason why you don't want to have _amount_ (to apply a % effect) in the shorthand function?

User interfaces often use an animated color fading to change their states between active and inactive. That effect could be created with _amount_, which can be animated with CSS animations and transitions. SVG filters can't be animated with CSS. Also, the _amount_ parameter would make recolor() similar to the sepia(amount) colorization function.

Here are the matrices to calculate the three versions of recolor() with _amount_ to control the proportion of the conversion. If _amount_ is 0, then the original image is shown. If _amount_ is 1, then the recolored version is shown.

    recolor() = recolor( amount, colorA, colorB, colorC )

The one color case (monotone) is as performant as the version without the _amount_ value:

    <filter id="recolor-1color" color-interpolation-filters="sRGB">
      <feColorMatrix type="matrix"
                 values="
        [1 - amount] 0 0 0 ([amount] * [colorA_r])
        0 [1 - amount] 0 0 ([amount] * [colorA_g])
        0 0 [1 - amount] 0 ([amount] * [colorA_b])
        0 0 0 1 0"/>
    </filter>

The two color case (duotone) can be written using feColorMatrix, feComponentTransfer and feComposite. feComposite is used to blend the original image and the colorized image.

    <filter id="recolor-2color" color-interpolation-filters="sRGB">
        <feColorMatrix type="matrix"
                       values="0.2126 0.7152 0.0722 0 0
                               0.2126 0.7152 0.0722 0 0
                               0.2126 0.7152 0.0722 0 0
                               0 0 0 1 0" />
        <feComponentTransfer>
          <feFuncR type="table" tableValues="[colorA_r] [colorB_r]"/>
          <feFuncG type="table" tableValues="[colorA_g] [colorB_g]"/>
          <feFuncB type="table" tableValues="[colorA_b] [colorB_b]"/>
        </feComponentTransfer>
        <feComposite operator="arithmetic" k1="0" k2="[amount]" k3="[1 - amount]" k4="0"
                     in2="SourceGraphic"/>
    </filter>

It can be optimized to use only feColorMatrix, so it is as performant as the one color case. It requires pre-calculation of the color matrix and then the values are set to feColorMatrix:

    // grayscale matrix
    G = [ 0.2126, 0.7152, 0.0722, 0, 0,
          0.2126, 0.7152, 0.0722, 0, 0,
          0.2126, 0.7152, 0.0722, 0, 0,
          0, 0, 0, 1, 0,
          0, 0, 0, 0, 1 ];

    // duotone effect matrix controlled by amount
    D = [ ((colorB_r - colorA_r) * amount), 0, 0, 0, (colorA_r * amount),
          ((colorB_g - colorA_g) * amount), 0, 0, 0, (colorA_g * amount),
          ((colorB_b - colorA_b) * amount), 0, 0, 0, (colorA_b * amount),
          0, 0, 0, 1, 0,
          0, 0, 0, 0, 1 ];

    // multiply duotone and grayscale matrices so that the original image is affected by both
    M = mat_mult(D, G);

    // add in the original image
    M[0, 0] += (1 - amount);
    M[1, 1] += (1 - amount);
    M[2, 2] += (1 - amount);

    <filter id="recolor-2color-optimized" color-interpolation-filters="sRGB">
        <feColorMatrix type="matrix"
                       values="[values-of-M]"/>
    </filter>


The three color case (tritone) can only be written using feColorMatrix, feComponentTransfer and feComposite. It is the same as the non-optimized two color case except feComponentTransfer has three colors:

    <filter id="recolor-3color" color-interpolation-filters="sRGB">
        <feColorMatrix type="matrix"
                       values="0.2126 0.7152 0.0722 0 0
                               0.2126 0.7152 0.0722 0 0
                               0.2126 0.7152 0.0722 0 0
                               0 0 0 1 0" />
        <feComponentTransfer>
          <feFuncR type="table" tableValues="[colorA_r] [colorB_r] [colorC_r]"/>
          <feFuncG type="table" tableValues="[colorA_g] [colorB_g] [colorC_g]"/>
          <feFuncB type="table" tableValues="[colorA_b] [colorB_b] [colorC_b]"/>
        </feComponentTransfer>
        <feComposite operator="arithmetic" k1="0" k2="[amount]" k3="[1 - amount]" k4="0"
                     in2="SourceGraphic"/>
    </filter>

Here's a [new CodePen example](https://codepen.io/anon/pen/xNLVxm?editors=1010) with those matrices. The amount parameter has been implemented for all these cases. The example works the best with Firefox and Chrome.

All these recolor() shorthand filters operate in the sRGB colorspace, just like the other existing shorthand filters.


-- 
GitHub Notification of comment by karip
Please view or discuss this issue at https://github.com/w3c/fxtf-drafts/issues/334#issuecomment-493739688 using your GitHub account

Received on Sunday, 19 May 2019 09:04:27 UTC