Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[css-images] Turbulence/noise image function #1273

Open
AmeliaBR opened this issue Apr 21, 2017 · 6 comments
Open

[css-images] Turbulence/noise image function #1273

AmeliaBR opened this issue Apr 21, 2017 · 6 comments

Comments

@AmeliaBR
Copy link
Contributor

AmeliaBR commented Apr 21, 2017

From Henrik Andersson on the www-style mailing list:

As many image effect specialists can tell you, noise can be used well in
various effects.

As such, I think that it would be useful if there was a way to generate
noise images in css.


From me:

The web platform already has a way to generate a noise image, the <feTurbulence> filter primitive. However, using it to generate a rectangle of noise requires:

  • SVG filter markup
  • a dummy element to which the filter will be applied

Which is a lot of messing around in markup for a stylistic effect. A CSS-only shorthand would be nice.

Turbulence doesn't make sense as a shorthand filter function, because the filter shorthands only work with a single image processing line, starting with the original and modifying it on each step. Most uses of noise would want to modify the noise and composite or blend it with the original rendering of the element.

However, a noise primitive could be very useful as an image layer in a background image stack, now that we have background-blend-mode. And even more so when/if browsers implement the filter() function for modifying an image value.

I'm imagining something like

background-image:
    filter(turbulence(stitch 0.2/3), saturate(10%)), 
    linear-gradient(lightBlue, darkRed);
background-size: 3em 3em, 100% 100%;
background-blend-mode: hard-light;

Considering that browsers already implement the feTurbulence algorithms, it probably wouldn't be too difficult to implement (although there are a few open issues on the spec that need to be resolved).

It could even be easily polyfilled using SVG data URIs (or as easy as any other CSS polyfill, anyway).

Initial proposal, to be added to CSS Images 4:


Noise images

A noise image generates a rectangular region of Perlin noise, following the algorithms described for the <feTurbulence> filter primitive. A noise image is drawn into a box with the dimensions of the concrete object size. However, the image itself has no intrinsic dimensions.

There are two noise image functions, corresponding to the two noise algorithms. The amount of noise is determined by a base-frequency (usually a decimal between 0 and 1) in the horizontal and vertical directions, and by the number of octaves (multiples of the base frequency) which are compounded (an integer, usually between 1 and 10). The noise function can be "stiched" across edges to provide a smooth appearance when the image is tiled (such as in a repeating background image). An optional seed parameter can be used to further alter the final generated noise.

<noise-image> = [<turbulence> | <fractal-noise>]
<turbulence> = turbulence( <noise-parameters> )
<fractal-noise> = fractal-noise( <noise-parameters> )

<noise-parameters> = [stitch | no-stitch]? <base-frequency> 
                         [/ <num-octaves>]? [seed  <seed>]?
<base-frequency> = <non-negative-number>{1,2}
<num-octaves> = <non-negative-integer>
<seed> = <integer> (or <number>: feTurbulence allows decimals, but truncates them)

The default values are no-stitch, <num-octaves>=1, and <seed>=0, matching the defaults for feTurbulence. A single <base-frequency> value is used for both x and y.


@AmeliaBR
Copy link
Contributor Author

Here's a pen showing what the end result of my sample CSS would look like (implemented using an SVG data URI, but not a full polyfill): https://codepen.io/AmeliaBR/pen/Gmqgyg?editors=1011

background-image:
    filter(turbulence(stitch 0.2/3), saturate(10%)), 
    linear-gradient(lightBlue, darkRed);
background-size: 3em 3em, 100% 100%;
background-blend-mode: hard-light;

Screenshot of the generated background from the linked pen, with the randomized texture over the blue to red gradient

@smfr
Copy link
Contributor

smfr commented Apr 25, 2017

Would you want the noise image to change every time the UA renders, or be fixed for a given image?

@AmeliaBR
Copy link
Contributor Author

By having the seed as a parameter (with a fixed default), it would be fixed: a given image function and image dimensions would always generate the same result. An author could use JS and CSS variables if they wanted to randomize the seed.

@bradkemper
Copy link
Contributor

That would be cool.

I'm also still hoping we can do an svg at-rule, as described at https://github.com/jonathantneal/postcss-write-svg/blob/master/README.md, to encapsulate some of the complexity of this sort of thing into something more readable.

@bradkemper
Copy link
Contributor

Maybe I shouldn't say "this sort of thing", but in cases where a data uri for svg needs to be considered, or in cases where it might be more readable than multiple embedding of functions.

@jimmyfrasche
Copy link

This would be handy, especially with #6807 and #7666. Should it be updated to use the per-element randomness from #2826?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants