Пример с использованием SVG
D3 наиболее полезен, когда используется для создания и манипулирования визуальными образами на основе SVG. Рисование с использованием div‘ов и других HTML-элементов возможно, но немного неуклюже, и обычно появляются несоответствия отображения в различных браузерах. Использование SVG более надежно, визуально последовательно и быстрее.
Редакторы векторной графики, такие как Illustrator, могут быть использованы для создания SVG-файлов, но нам необходимо научиться создавать их с помощью кода.
Элемент SVG
Scalable Vector Graphics(масштабируемая векторная графика) — формат изображений на основе текста. Каждое SVG-изображение определено с использованием разметки кода, похожей на HTML. SVG-код может быть включен напрямую в HTML-документ. Каждый веб-браузер поддерживает SVG, исключением является только Internet Explorer версии 8 и старше. SVG основан на XML, поэтому вы можете заметить, что элементы, не имеющие закрывающего тега, должны быть самозакрывающимися. Например:
Перед тем как вы сможете что-нибудь рисовать, вам надо создать SVG-элемент. Думайте об SVG-элементе, как о холсте, на котором отрисовываются все ваши визуальные образы(В такой трактовке, SVG концептуально схож с элементом HTML — canvas). Как минимум, хорошо задать ширину и высоту с помощью атрибутов width и height, соответственно. Если вы их не зададите, SVG растянется на всю площадь блока.
Здесь SVG-элемент, созданный с использованием кода выше:
Не видите его? Нажмите правой кнопкой по пустому месту выше и выберите «Просмотр кода элемента». Ваш веб-инспектор должен показать что-то похожее:
Заметьте, что тут есть SVG-элемент, который занимает 500 пикселей по горизонтали и 50 пикселей по вертикали.
Также заметьте, что браузеры считают пиксели единицей измерения по умолчанию. Мы указали размеры как 500 и 50, а не 500px и 50px. Мы можем указать px явно, или любую другую единицу измерения, например: em, pt, in, cm, и mm.
Простые фигуры
Существует некоторый набор фигур, которые вы можете поместить внутрь элемента SVG. Этот набор включает: rect, circle, ellipse, line, text и path.
Если вы знакомы с программирование компьютерной графики, вы вспомните, что обычно координатная система на основе пикселей начинается с левого верхнего угла и имеет координаты точки (0,0). Увеличение х происходить слева направо, увеличение у-сверху вниз.
rect рисует квадрат. Квадрат задается четырьмя значениями: x, y — указывают точку верхнего левого угла; width, height — указывают ширину и высоту квадрата. Этот квадрат занимает все пространство нашего SVG:
circle рисует круг. Круг задается тремя величинами: cx, cy указывают точку, расположенную в центре описываемой окружности, r задает радиус круга. Этот круг расположен в центре нашего SVG, потому что атрибут cx(«center-x») равен 250. Пример:
ellipse задается схоже с circle, но предполагается, что радиус задается по двум осям: по х и по у. Вместо х используйте rx, вместо y — ry.
line рисует линию. Используйте x1 и y1 для задания координат начала линии, и x2 и y2 для задания координат конца. Атрибут stroke должен задавать цвет линии, иначе она будет невидимая.
Easy-peasy
текст будет наследовать CSS-стили шрифта родительского элемента, если только вы не зададите свои стили для текста. Обратите внимание, как форматирование текста выше совпадает с текстом, описываемом в этом параграфе. Мы может переопределить стили форматирования так:
Easy-peasy
Также заметьте, когда любой визуальный элемент упирается в границу SVG-элемента, он будет обрезан. Будьте осторожны, когда используете text, чтобы ваши загагулины у текста не были обрезаны. Вы можете увидеть, что случится с текстом, если выставить baseline (то есть у) равным 50, такую же, как высота SVG:
Easy-peasy
path рисует что-нибудь более сложное, чем фигуры, описанные выше(например, силуэт стран на геокартах), и будет описан отдельно. А теперь мы будем работать с простыми фигурами.
Стилизация SVG-элементов
- fill — заливка. Цветовое значение. Также как и в CSS цвет может быть указан несколькими способами:
- по имени: orange;
- значение в шестнадцатиричной системе счисления: #3388aa, #38a;
- значение в формате RGB: rgb(10, 150, 20);
- значение в формате RGBA: rgba(10, 150, 20, 0.5).
С text также можно использовать следующие свойства:
Существует два способа применения стилей к SVG-элементам: либо напрямую прописывать стили внутри элемента как его атрибуты, или через правила CSS.
Ниже некоторые CSS-свойства заданы непосредственно в элементе circle:
По-другому мы могли бы сделать так: не прописывать атрибуты стиля, а указать класс стилей(также как и обычному HTML элементу):
а потом добавить fill, stroke и stroke-width параметры в CSS-стили необходимого класса:
.pumpkin
Второй подход имеет несколько очевидных преимуществ:
- Можно описать класс один раз и применять его ко многим элементам.
- CSS-код проще воспринимать, чем атрибуты внутри элементов.
- По этим причинам второй подход более прост в обслуживании, а также он быстрее применим.
Использование CSS для применения стилей к SVG, однако, может кого-то привести в замешательство. fill, stroke, stroke-width все-таки не CSS-свойства(ближайшие CSS-эквиваленты это background-color и border). Чтобы помочь вам запомнить, какие правила в таблице стилей указаны для SVG-элементов, желательно включать svg в CSS-селектор:
svg .pumpkin < /* . */ >
Наложение и порядок их рисования
В SVG нет как таковых слоев и никакого понятия глубины. SVG не поддерживает CSS-свойство z-index, таким образом фигуры могут быть упорядочены в рамках двухмерного пространства.
И еще, если нарисовать несколько фигур, то они перекрываются:
Порядок, в котором элементы указаны в коде, определяет их глубину. Фиолетовый квадрат указан в коде первым, поэтому первым он и отрисовывается. Дальше рисуется синий квадрат над фиолетовым, дальше зеленый над синим и фиолетовым и т.д.
Думайте так, будто SVG-фигуры рисуются на холсте. Цвет, который применяется позже всех, закрашивает остальные цвета, оказываясь «впереди».
Этот аспект рисования порядка становится важным, когда у вас есть несколько визуальных элементов, которые не должны быть ничем перекрыты. Например, у вас могут быть оси или метки значений на осях, которые появляются на диаграмме рассеивания. Оси и метки должны быть добавлены в SVG в конце, чтобы они появились перед остальными элементами и были видны.
Прозрачность
Прозрачность может быть полезна, когда элементы вашей визуализации пересекаются, но должны быть видимыми все, или когда вы хотите выделить одни элементы, но при этом сделать более незаметными другие.
Существует два способа применить прозрачность: использовать RGB-цвет с альфа-каналом или установить свойству opacity числовое значение.
Вы можете использовать rgba() везде, где надо указать цвет, например в атрибутах fill и stroke. rgba() ожидает, что вы передадите ему 3 значения в промежутке от 0 до 255 для красного, зеленого и синего, плюс альфа-канал(прозрачность) в диапазоне от 0.0 до 1.0.
Заметьте, что с методом rgba(), прозрачность применяется к fill и stroke атрибутам независимо. Заливка следующих кругов на 75% прозрачна, а их рамка — на 25%:
Для применения прозрачности ко всему элементу, необходимо установить атрибут opacity. Ниже полностью видимые круги:
а это те же круги с различной прозрачностью:
Вы также можете использовать атрибут opacity у элемента, цвета которого заданы в формате rgba(). Когда вы это делаете — прозрачность умножается. Ниже круги используют те же значения цвета RGBA для fill и stroke. У первого элемента не установлен атрибут opacity, а у двух других установлен:
Обратите внимание, что у третьего круга opacity равно 0.2 или 20%. Тем не менее его фиолетовая часть имеет прозрачность в 75%. Таким образом, фиолетовая часть в конечном итоге прозрачна на 0.2*0.75 = 0.15 или 15%.
Чтобы увидеть большее количество примеров с использованием SVG, включая path, маски, фильтры и т.д. — смотрите SVG пример для браузеров, автором которых является David Dailey.
Автором оригинального текста книги D3 Tutorials является Scott Murray
На русский язык перевел Ivanov Sergey. 2014 годОсновные Фигуры
Существует несколько основных фигур, используемых в большинстве рисунков SVG. Назначение этих фигур вполне очевидно из их имён. Мы привели здесь некоторые атрибуты, определяющие положение и размер, но спецификация элемента, вероятно, содержит более точное и полное описание, вместе с другими свойствами, не описанными здесь. Однако, так как они используются в большинстве документов SVG, важно иметь некоторое представление о них.
Основные формы
Чтобы вставить форму, нужно создать элемент в документе. Разные элементы соответствуют разным формам и требуют разные атрибуты для описания размера и положения этих форм. Некоторые немного громоздки, поскольку могут быть созданы другими формами, но для удобства они все здесь приведены и способствуют сохранению документов SVG настолько короткими и читаемыми, насколько это возможно. Все основные формы показаны на изображении справа. Код для генерации выглядит как-то так:

svg width="200" height="250" version="1.1" xmlns="http://www.w3.org/2000/svg"> rect x="10" y="10" width="30" height="30" stroke="black" fill="transparent" stroke-width="5"/> rect x="60" y="10" rx="10" ry="10" width="30" height="30" stroke="black" fill="transparent" stroke-width="5"/> circle cx="25" cy="75" r="20" stroke="red" fill="transparent" stroke-width="5"/> ellipse cx="75" cy="75" rx="20" ry="5" stroke="red" fill="transparent" stroke-width="5"/> line x1="10" x2="50" y1="110" y2="150" stroke="orange" fill="transparent" stroke-width="5"/> polyline points="60 110 65 120 70 115 75 130 80 125 85 140 90 135 95 150 100 145" stroke="orange" fill="transparent" stroke-width="5"/> polygon points="50 160 55 180 70 180 60 190 65 205 50 195 35 205 40 190 30 180 45 180" stroke="green" fill="transparent" stroke-width="5"/> path d="M20,230 Q40,205 50,230 T90,230" fill="none" stroke="blue" stroke-width="5"/> svg>Примечание: Атрибуты stroke , stroke-width и fill описываются в руководстве далее.
Прямоугольники
Элемент rect делает как раз то, что вы и ожидаете, то есть рисует прямоугольник на экране. Существуют только 6 основных атрибутов, которые контролируют положение и форму прямоугольника на экране. Ранее показанное изображение отображает два элемента rect, которые выглядят немного лишними. Один справа имеет набор атрибутов rx и ry, которые отвечают за округлые углы. Если этого набора нет, то по умолчанию они принимаются равными 0.
rect x="10" y="10" width="30" height="30"/> rect x="60" y="10" rx="10" ry="10" width="30" height="30"/>
Положение x верхнего левого угла прямоугольника.
Положение y верхнего левого угла прямоугольника.
Радиус x углов прямоугольника
Радиус y углов прямоугольника
Окружность
Как вы могли предположить, элемент circle рисует окружность на экране. Существует 3 атрибута для описания этого элемента.
circle cx="25" cy="75" r="20"/>Положение x центра окружности.
Положение y центра окружности.
Эллипс
Ellipse — это наиболее общая форма элемента окружность, в котором можно масштабировать радиусы x и y (обычно называемые математиками половиной большой оси и половиной малой оси) окружности по отдельности.
ellipse cx="75" cy="75" rx="20" ry="5"/>Радиус x эллипса.
Радиус y эллипса.
Положение x центра эллипса.
Положение y центра эллипса.
Линия
Line изображает простую прямую линию. Её атрибутами являются две точки, которые определяют начальную и конечную точки линии.
line x1="10" x2="50" y1="110" y2="150"/>Положение x точки 1.
Положение y точки 1.
Положение x точки 2.
Положение y точки 2.
Ломаная линия
Элемент polyline воспроизводит группу соединённых прямых линий. Поскольку этот список может быть довольно длинным, все точки включены в один атрибут:
polyline points="60 110, 65 120, 70 115, 75 130, 80 125, 85 140, 90 135, 95 150, 100 145"/>Список точек, каждая разделённая пробелом, запятой, EOL, или символом перевода строки. Каждая точка должна содержать два числа, координату x и координату y. Поэтому список (0,0), (1,1) и (2,2) может быть записан: «0 0, 1 1, 2 2».
Многоугольник
Элемент polygon очень похож на элемент polyline в том, что они образованы сегментами прямых линий, соединяющими список точек. Но для многоугольников путь автоматически возвращается к первой точке в конце, создавая тем самым замкнутую форму. Следует отметить, что прямоугольник является частным случаем многоугольника, поэтому polygon можно использовать для создания элемента в случаях, когда необходимо большая гибкость.
polygon points="50 160, 55 180, 70 180, 60 190, 65 205, 50 195, 35 205, 40 190, 30 180, 45 180"/>Список точек, каждая разделённая пробелом, запятой, EOL, или символом перевода строки. Каждая точка должна содержать два числа, координату x и координату y. Поэтому список (0,0), (1,1) и (2,2) может быть записан как: «0 0, 1 1, 2 2». Полигон замыкается финальной прямой линией от (2,2) до (0,0).
Путь
Path, вероятно, наиболее общая форма, которую можно использовать в SVG. Используя элемент path вы можете рисовать прямоугольники (с закруглёнными углами или без), окружности, эллипсы, ломанные линии и многоугольники; и по существу любые другие типы форм: кривые Безье, квадратические кривые и многое другое. По этой причине элемент path будет рассмотрен отдельно в следующей секции этого руководства, но сейчас отметим только, что существует единственный атрибут для контроля его формы.
path d="M 20 230 Q 40 205, 50 230 T 90230"/>Список точек и другой информации о том, как рисовать путь. Для подробной информации смотри секцию Пути.
- « Предыдущая статья
- Следующая статья »
Found a content problem with this page?
- Edit the page on GitHub.
- Report the content issue.
- View the source on GitHub.
This page was last modified on 3 авг. 2023 г. by MDN contributors.
Your blueprint for a better internet.
Как рисовать красивые соединения с помощью SVG
Мы делаем систему симуляции различных процессов, в которой пользователь с помощью визуального программирования может описать и посмотреть, как работает тот или иной процесс. Иными словами, проверить, как на результат процесса влияют те или иные причинно-следственные связи. Вся система построена на нодах — наглядных представлениях функций, которые принимают, обрабатывают, показывают и в конце концов отправляют данные в следующие ноды.

Мне в голову приходит лишь два варианта, как можно было бы представить связи между нодами, чтобы это было понятно и красиво:

- Ломанные линии с прямыми углами как в UML-диаграммах. Такой вид соединений хорош, когда нам надо показывать четкие иерархии и отношения между соединяемыми объектами, для которых, зачастую, нет разницы, откуда приходит это соединение. В реальном мире это могло бы напоминать трубопровод, с различными разветвлениями и пересечениями, который соединяет резервуары.
- Плавные кривые, какие используют Nodes в UE4 или Shader Nodes в Blender. Они наглядно показывают не только отношения между объектами, но и их взаимодействие, а так же определяют конкретные входы и выходы для разных данных. В свою очередь эти связи можно представить как провода в аналоговом модульном синтезаторе, которые соединяют генераторы звука и множество фильтров между собой для извлечения уникального звука.
Второй вариант выглядит идеальным для решения задачи — наши ноды могут не иметь четкой структуры и иерархии, они могут иметь по несколько входов и выходов, но между ними строго ограничены взаимодействия типами входных и выходных данных. Как же красиво нарисовать эти связи?
Реализация
Так как наше приложение не использует canvas, решение так же должно использовать возможности DOM для отображения соединений. Первый кандидат на рисование кривых — это в SVG.
Ниже условно представлено, как выглядит основное пространство, в котором происходит работа:
.container < position: absolute; width: 100%; height: 100%; top: 0px; left: 0px; overflow: hidden; >.nodes-container < position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; transform-origin: left top; /* Задается динамически, но здесь и далее для удобства будут использованы эти значения */ transform: translate(640px, 360px) scale(0.5); >Поместим в DOM выше nodes-container, чтобы он рендерился первым и находился ниже. Так же накинем ему некоторых стилей, чтобы он занимал собой все пространство и не перехватывал события, а внутри обернем все соединения в для синхронизации transform с .nodes-container .
.container < /* . */ >.nodes-container < /* . */ >.connections-container
На этом подготовка закончена и можно перейти к отрисовке самих соединений. Для начала соединим порты прямыми линиями, чтобы разобраться с их позиционированием. У элемента есть атрибут d , в котором описывается геометрия фигуры. Для прямой линии достаточно двух команд — “Move to” — M и “Line to” — L . Первая указывает точку, от которой начинается рисование фигуры, вторая — рисует линию до следующей точки. Обе команды имеют синтаксис следующего вида:
M x, y L x, yНам известны центры портов в формате , поэтому для соединения точек и < x: 45, y: 90 >выражение d будет выглядеть как:
M 20, 60 L 45, 90надо добавить еще несколько свойств, чтобы избежать заполнения фигуры, а также указать цвет и толщину самой линии:
Теперь пора добавить красоты и сделать естественный изгиб получившимся линиям для случаев, когда порты находятся на разной высоте. Для этого мы воспользуемся связкой из двух квадратичных кривых Безье. В результате мы должны получить кривую, которая по форме будет напоминать букву S, так как порты нод могут находится слева и справа, но не сверху или снизу. Квадратичная кривая Безье задается тремя контрольными точками P₀ (начальная), P₁ (контрольная) и P₂ (конечная), а ее уравнение выглядит следующим образом:


Для отображения такой кривой в d используется команда Q с аргументами P₁ и P₂. В свою очередь точка P₀ определяется предыдущей командой выражения d, таковой в нашем случае является M , указывающая точку начала фигуры. Таким образом получается половина необходимой линии.
M x0, y0 Q x1, y1 x2, y2Для того, чтобы нарисовать вторую половину — такую же кривую, отраженную по горизонтали, достаточно воспользоваться командой T. Эта команда принимает в качестве аргумента лишь одну точку P₂ для уравнения. P₀ для нее является конечная точка предшествующей кривой, а P₁ рассчитывается как отражение предыдущей контрольной точки относительно текущей P₀. Иными словами, линия продолжается в виде отражения предыдущей кривой Безье до указанной точки.
M x0, y0 Q x1, y1 x2, y2 T x3, y3Давайте напишем функцию, для генерации необходимого выражения d . Нам известны точки и — это координаты портов выхода и входа. Точка — будет являться центром прямой между этими двумя точками.
type Point = < x: number, y: number >; function calculatePath(start: Point, end: Point) < const center = < x: (start.x + end.x) / 2, y: (start.y + end.y) / 2, >; return ` M $,$ Q x1, y1 $,$ T $,$ `; >Остается рассчитать контрольную точку . Для этого мы будем смещать точку начала линии по оси X. Изначальный y необходимо оставить, чтобы у точек входа и выхода линия стремилась к горизонтальному положению. Для расчета смещения возьмем минимум из дистанции между точками start и end , половины расстояния по оси Y, а так же ограничения в 150, чтобы избежать чрезмерного растяжения кривой при больших удалениях нод друг от друга.
type Point = < x: number, y: number >function distance(start: Point, end: Point) < const dx = start.x - end.x const dy = start.y - end.y return Math.sqrt(dx * dx + dy * dy) >function calculatePath(start: Point, end: Point) < const center = < x: (start.x + end.x) / 2, y: (start.y + end.y) / 2, >const controlPoint = < x: start.x + Math.min( distance(start, end), Math.abs(end.y - start.y) / 2, 150 ), y: start.y, >; return ` M $,$ Q $, $ $,$ T $,$ `; >При таком расчете контрольной точки, если порты будут находиться на одной высоте, линия будет прямой, но будет искривляться пропорционально удалению нод друг от друга.

Заключение
Данный способ отрисовки соединения справедлив для нод, чьи порты располагаются на противоположных сторонах. Однако, для портов, расположенных на одной стороне, можно использовать кубические кривые Безье, добавив такой же расчет второй контрольной точки, который будет использовать смещение от конечной.
Спасибо, что прочитали эту статью, надеюсь вам было интересно!
Как нарисовать такое при помощи svg в html?

Здравствуйте как нарисовать такую фигуру в svg
Отслеживать
задан 23 окт 2018 в 11:01
Dmitry Walker Dmitry Walker
21 2 2 бронзовых знака1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Очень простой редактор svg CССЫЛКА
Отслеживать
ответ дан 23 окт 2018 в 12:03
Евгений Николаев Евгений Николаев
2,129 9 9 серебряных знаков 17 17 бронзовых знаков- css3
- html5
- svg
-
Важное на Мете
Похожие
Подписаться на ленту
Лента вопроса
Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.
Дизайн сайта / логотип © 2023 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2023.11.15.1019
Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.
