js 修改svg背景色_SVG和JS的散景背景

百里业
2023-12-01

js 修改svg背景色

SVG is commonly associated with regular geometric designs that feature hard edges, but with a little cleverness, it can also be used to create random fuzziness.

SVG通常与规则的几何设计相关联,这些设计的特征是具有硬边,但是稍微聪明一点,也可以用于创建随机的模糊性。

“Bokeh” is the out-of-focus effects produced by a lens, particularly one associated with a limited depth of field. Visually, this can appear as a pleasant blur, or distorted points of light in different shapes; here, I’m using circles.

“散景”是镜头产生的散焦效果,特别是与有限景深相关的效果。 在视觉上,这可能表现为令人愉悦的模糊或不同形状的光线扭曲点; 在这里,我正在使用圈子。

This effect has been popularly rendered (and often animated) using <canvas>, but I wanted to create a variant that could be applied as a pure background image. This meant that the blur on each of the circles had to be rendered inside the SVG itself: the CSS blur() filter does not work as one might expect on SVG elements.

这种效果已经普遍使用<canvas>渲染(并且通常是动画),但是我想创建一个可以用作纯背景图像的变体。 这意味着必须在SVG本身内部渲染每个圆上的模糊: CSS blur()过滤器无法像人们对SVG元素所期望的那样工作。

Bokeh is, by its very nature, semi-random, so at the core of this effect are two quick functions that create two different kinds of randomness: one a random floating point number (to two decimal places), the other a whole number.

Bokeh本质上是半随机的,因此此效果的核心是两个快速函数,它们会产生两种不同类型的随机性:一个是随机浮点数(至小数点后两位),另一个是整数。

随机种子 (Random Seeds)

var randomFloat = function(min,max) {
    return (Math.random() * (max - min) + min).toFixed(2);
}
var randomRange = function(min,max) {
    return Math.floor(Math.random()*(max-min+1)+min);
}

Coupled with these functions are a bunch of variables as upper and lower limits:

与这些函数耦合的是一堆变量,作为上限和下限:

  • the minimum and maximum number of circles

    最小和最大圈数
  • their min and max radius

    他们的最小和最大半径
  • and their upper and lower opacity

    及其上下不透明度
var minRad = 9,
maxRad = 15,
minCircs = 10,
maxCircs = 25,
minOpacity = 0.2,
maxOpacity = 0.8,

After some experimentation I found that best and most realistic visual results were produced using similar hues that varied in saturation and luminosity, making HSLa color an obvious choice for rendering the circles. (The a component is provided by the two opacity variables defined earlier). These choices required more variables:

经过一些实验,我发现使用饱和度和亮度不同的类似色调可以产生最佳和最真实的视觉效果,从而使HSLa颜色成为渲染圆圈的明显选择。 (该a分量由前面定义的两个不透明度变量提供)。 这些选择需要更多变量:

var hue = 300,
minSat = 25,
maxSat = 75,
minLum = 25,
maxLum = 75;

Finally, each circle needed to be blurred:

最后,每个圆都需要模糊:

var minBlur = .75,
maxBlur = 4,
blurVariants = 3;

渲染结果 (Rendering the Result)

While it would be completely possible to complete the effect as an actual SVG element, I opted to create the result as a string, concatenating changes as the script progressed, which made the result easier to convert into base64 later. (More on that in a moment).

虽然完全有可能将效果作为一个实际的SVG元素来完成,但我选择将结果创建为字符串, 在脚本进行时将更改串联在一起 ,这使得结果在以后更容易转换为base64 。 (稍后会详细介绍)。

var svg = '<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">';

Each of the blur effects is rendered as a separate SVG filter, each with a unique id:

每个模糊效果均呈现为单独的SVG滤镜,每个滤镜具有唯一的id

svg += '<defs>';
for (var i=0; i < blurVariants; i++) {
    svg += '<filter id="bokeh'+i+'">';
    svg += '<feGaussianBlur stdDeviation="'+randomFloat(minBlur, maxBlur)+"'></feGaussianBlur>";
    svg += '</filter>';
}
svg += '</defs>";

Finally, each of the circles is rendered out using the limits set by the variables defined earlier:

最后,每个圆都使用前面定义的变量设置的限制进行渲染:

for (var i=1;i < randomRange(minCircs, maxCircs);i++) {
    svg += '<circle ";
    svg += 'r="'+randomRange(minRad, maxRad)+'%"';
    svg += 'cx="'+randomRange(0, 100)+'%"';
    svg += 'cy="'+randomRange(0, 100)+'%"';
    svg += 'fill="hsla('+hue+', '+randomRange(minSat, maxSat)+'%, '+randomRange(minLum, maxLum)+'%, '+randomFloat(minOpacity, maxOpacity)+')"';
    svg += ' filter="url(#bokeh'+randomRange(0,blurVariants)+")';
    svg += '></circle>;;
    }
svg += '</svg>';

深背景 (Deep Background)

Placing the SVG as a string for the background (background-image: url("<svg>…")) can be problematic, and has poor cross-browser compatibility. Instead, I opted to convert the SVG string into base64, and apply that as the page background via JavaScript:

将SVG放置为背景字符串( background-image: url("<svg>…") )可能会出现问题,并且跨浏览器的兼容性较差。 相反,我选择将SVG字符串转换为base64,然后通过JavaScript用作页面背景

var encodedData = window.btoa(svg),
url = "data:image/svg+xml;base64," + encodedData;
document.body.style.backgroundImage = "url("+url+")";

制作演示 (Making The Demo)

To provide some user control - rather than simply refreshing the page to get a new result - I allowed the user to alter one of the variables in the demo. This was enabled by turning the SVG creation part of the script into a function, and one of the variables into reading a range input:

为了提供一些用户控件-而不是简单地刷新页面以获得新的结果-我允许用户更改演示中的变量之一。 通过将脚本的SVG创建部分转换为函数,并将其中一个变量转换为读取range输入来启用此功能:

var hue = document.getElementById("hueangle").value;

Any changes to this slider then call the function, recreating the background with new random results:

对此滑块进行的任何更改均会调用该函数,并使用新的随机结果重新创建背景:

hueangle.addEventListener("change", function() { 
    svg();
})

You can learn more about these changes by inspecting the associated CodePen demo.

您可以通过检查相关的CodePen演示进一步了解这些更改。

翻译自: https://thenewcode.com/1061/Bokeh-Backgrounds-with-SVG-and-JS

js 修改svg背景色

 类似资料: