Создание градиентной сетки в CSS/JQuery

Я не уверен, возможно ли это или нет, но могу ли я использовать методы CSS/Jquery для создания градиентной сетки? Что-то похожее на это enter image description here

Я хотел бы случайно создать эту сетку, а затем, возможно, ее анимировать, поэтому я стараюсь избегать использования изображений. Я не уверен, что возможно что-то подобное.

Я думал, возможно, создав несколько слоев отдельных градиентов, а затем объединив их все вместе в фиксированное положение и изменив их параметры непрозрачности?

Ответ 1

В настоящее время

Я экспериментировал с чем-то в этом направлении несколько лет назад, используя SVG, тэг canvas HTML5 и совсем недавно CSS3-градиенты. Я не верю, что есть естественный способ выйти за рамки простых линейных или радиальных градиентов в настоящее время.

Вопрос в том, можно ли моделировать градиент сетки, используя только простые линейные и радиальные градиенты (которые являются единственными доступными инструментами).

К сожалению, когда вы комбинируете несколько градиентов с использованием непрозрачности или rgba, цвета разных градиентов имеют тенденцию сочетаться таким образом, что это не полезно, что приводит к размытым цветам. Избежание этого потребовало бы возможности отображать его в браузере как единый комплексный градиент.

Существуют также существенные ограничения для форм, которые могут иметь градиенты: линейные градиенты под произвольным углом и эллиптические градиенты с радиальной симметрией. Ни один из них не допускает формы свободной формы, неправильной формы. 2D-преобразования, которые могут быть применены к результирующему изображению, являются довольно регулярными по своей природе (масштабирование, перекос и т.д.).

В будущем

Наиболее перспективным вариантом, о котором я знаю в ближайшем будущем, является возможная поддержка градиентов сетки в SVG 2.0 (и, возможно, кривые диффузии). Если это произойдет и в конечном итоге поддерживается браузерами, это должно значительно расширить возможности. И тег canvas HTML5 и CSS3 могут вскоре последовать.

И как отмечалось в примечании @vals в комментарии ниже, WebGL должен предлагать некоторые очень перспективные варианты (для тэгов HTML5 с использованием 3D-контекста).

Ссылки по теме

Ответ 2

Я сделал простой макет, чтобы продемонстрировать это.

Во-первых, я положу 4 divs, первый, чтобы показать частичные результаты, и последний, чтобы увидеть конечный результат. Разметка просто:

<div class="box mesh1"></div>
<div class="box mesh2"></div>
<div class="box mesh3"></div> 
<div class="box mesh"></div> 

здесь поле предназначено только для измерений, mesh1 - 3, удерживая частичные результаты, в сетке мы все вместе ставим.

CSS:

.box {
    width: 400px;
    height: 150px;
    position: relative;
    display: inline-block;
}

.mesh1, .mesh {
background:
    -webkit-linear-gradient(5deg,  rgba(0, 250, 0, 0.5), rgba(0, 100, 0, 0.5))
}

.mesh:after, .mesh:before {
    content: "";
    position: absolute;
    left: 0px;
    bottom: 0px;
    top: 0px;
    right: 0px;
}
.mesh2, .mesh:after {
background:   -webkit-radial-gradient(center center, circle cover, rgba(250, 0, 0, 0.6) 0%, rgba(120, 0, 10, 0.5) 100%);}

.mesh3, .mesh:before {
background: -webkit-radial-gradient(10% 10%, ellipse cover, rgba(0, 0, 250, 0.6) 0%, white 100%);}

Я даю классу mesh1 фоновый линейный, наклонный 5 градусов и задающий цвета в формате rgba, чтобы обеспечить прозрачность.

Затем, чтобы иметь возможность накладывать больше градиентов, я указываю псевдоэлементы как раньше, так и после, используя одни и те же свойства макета.

Для элемента after я даю круговой градиент, совместно используемый с mesh2 К элементу before я даю эллиптический градиент, от центра. Все они могут быть rgba.

В конце вы видите в ячейке div результат перекрытия всего

(я использовал всюду нотацию webkit, чтобы сделать ее коротким)

Я бы не сказал, что это очень артистично, но я оставляю эту часть вам: -)

скрипка здесь

Ответ 3

В моем первом ответе я интерпретировал это больше в "художественном" способе, чем в "математическом" способе. Ответ от Мэтта Кофлина заставляет меня задуматься о более математическом ответе, в котором мы сделаем "сетку" частью требования более строгим.

То есть у нас есть матрица цветов, и мы хотим показать это в сетке. Если сетка имеет интервал, равный 100px, тогда цвет [x] [y] матрицы будет передан пикселю в 100x и 100y. Пиксели между ними были бы аппроксимированы билинейным способом.

Для такого подхода css будет:

.mesh { overflow: hidden; position: absolute;   width: 300px;   height: 300px;    }

.tile {    width: 200px;    height: 200px;    position: absolute;    display: block;   }

.tile11, .tile21, .tile31 {
left: -50px;
}
.tile12, .tile22, .tile32 {
left: 50px;
}
.tile13, .tile23, .tile33 {
left: 150px;
}
.tile11, .tile12, .tile13 {
top: -50px;
}
.tile21, .tile22, .tile23 {
    top: 50px;
}
.tile31, .tile32, .tile33 {
top: 150px;
}

.tile11 {
background: -webkit-radial-gradient(center center, 100px 100px, 
      rgba(255, 0, 0, 1) 0%, 
      rgba(255, 0, 0, 0.5) 50%,
      rgba(255, 0, 0, 0) 100%);}

.tile12 {
background: -webkit-radial-gradient(center center, 100px 100px, 
      rgba(255, 0, 0, 1) 0%, 
      rgba(255, 0, 0, 0.5) 50%,
      rgba(255, 0, 0, 0) 100%);}

Я использую каждый div как локальный вкладчик сетки, получая только "касание" промежуточного соседа и переход к полной прозрачности за пределами этой точки.

В результате получится следующее:

fiddle

2 первых цвета являются красными как тест. В идеальной системе линия, соединяющая 2 точки, должна быть абсолютно красной все время.

Это правда, что это не идеальный результат, но "мутная" или "умываемость" результата более или менее избегается

Ответ 4

Я написал о решении для создания легких, масштабируемых градиентов сетки с использованием растровых изображений: https://peterhrynkow.com/performance/2019/01/13/blowing-up-images-to-make-them-small.html

Это не решает проблему необходимости генерировать их случайным образом, но, по крайней мере, дает вам небольшой размер файла и независимое от разрешения масштабирование, которое вы ожидаете от решения CSS или SVG.