Белый шум (зернистость) на черном фоне
Как можно оптимизировано сделать белый шум на черном фоне?
Пробовал взять кусок изображения, background-repeat и его анимировать (как шум на старом телевизоре). Получилось то, что нужно, но сайт начинает виснуть. Есть ли более лаконичные и оптимизированные способы, чтобы такое реализовать? Возможно, с помощью js?
Ответы (2 шт):
Сделал пример на js, но думаю лучше обычную гифку сделать и не нагружать браузер.
const canvas = document.getElementById('white-noise');
const ctx = canvas.getContext('2d');
ctx.canvas.height = canvas.offsetHeight;
ctx.canvas.width = canvas.offsetWidth;
render();
function render() {
const image = ctx.createImageData(ctx.canvas.width, ctx.canvas.height);
for (let i = 0; i < image.data.length; i += 4) {
const color = Math.random() * 255;
image.data[i] = color;
image.data[i + 1] = color;
image.data[i + 2] = color;
image.data[i + 3] = 255;
}
ctx.putImageData(image, 0, 0);
requestAnimationFrame(render);
}
#white-noise {
width: 100%;
height: 300px;
}
<canvas id="white-noise"></canvas>
Можно подготовить анимированный gif. Можно подготовить набор фоновых изображений и использовать css-анимацию.
Хорошая рекомендация выше про WebGL, есть уже готовые шейдеры:
Еще видел подобные штуки на SVG-фильтрах.
Но если уж очень хочется ограничиться JS и CSS, и использовать background, то могу предложить такое извращение (берегите глаза):
var canvas = document.createElement("canvas");
var sheet = document.getElementById('tv-css').sheet;
var ctx = canvas.getContext("2d");
let tileSize = 256;
canvas.width = tileSize;
canvas.height = tileSize;
let cssKeyFrames = [];
let frames = 16;
let array = ctx.createImageData(tileSize, tileSize);
for (let i = 0; i < frames; i++) {
for (let j = 0; j < array.data.length;) {
const c = ~~(Math.random() * 2) * 255;
array.data[j++] = c;
array.data[j++] = c;
array.data[j++] = c;
array.data[j++] = 255;
}
ctx.putImageData(array, 0, 0);
let img = canvas.toDataURL("image/jpeg", 0.1);
cssKeyFrames.push(~~(100 / (frames - 1) * i) +
'% { background: url(' + img + ') repeat top left/512px 512px; }'
);
}
let styles = '@keyframes tvShow { ' + cssKeyFrames.join('') + '}';
sheet.insertRule(styles, 1);
<style id="tv-css">
body {
animation: tvShow 1s infinite steps(2, end);
}
</style>
Т.е. генерируем кадры и CSS-правила для анимации. Если сложить все изображения в файлы и самому прописать CSS, то и JS не нужен.
