May 30

Чертежи в SVG формате. Часть 1 — Черновик стандарта

Мопед не мой, я только объявление разместил (с)

Это цикл статей, посвященных работе с SVG, размещенный на сайте http://v.sytnik.lviv.ua (ныне недоступный). Статьи мне показались очень информативными, поэтому захотелось их сохранить.

В интернете можно найти много разной информации о создании чертежей в формате SVG. Чаще предлагается какой-то редактор и экспорт из формата DXF в SVG. Просматривая код SVG сразу видно что там много лишнего. Созданный в одном редакторе файл SVG не всегда может корректно открыться в другом. Одно радует, что браузеры начали поддерживать SVG формат. Всюду пишут про недостатки использования SVG. А может надо придерживаться единых правил структуры файла для отображения чертежей?

Из экспериментов и тестов пришёл к таким правилам при создании чертёжа:

  • использование объектной модели чертежа;
  • используем только одну единицу измерения (та что по умолчанию в пикселях);
  • условно принимаем — один пиксель равен одному миллиметру (для браузера будет в пикселях, а для нас в мм);
  • масштаб описания элементов всегда 1:1;
  • для отображения объектов в другом масштабе используем вложенный svg рисунок;
  • для уникальных объектов задаём id а для характерных class;

Объектная модель чертежа

Упрощенно чертёж можно описать в виде XML структуры.

<svg id="Detail1" ...>
    <defs id="defsCAD"> ... </defs>
    <svg id="Shtamp" name="Frame drawing" ... >
        ...
    </svg>
    <svg id="View1" ... >
        <g id="layer-0" name="System layer" ...>
            <line class="line-type-1" ... />
            <line class="line-type-1" ... />
            <circle class="line-type-1" ... />
            <path class="line-type-1" ... />
            <rect class="line-type-1" ... />
            <line class="line-type-2" ... />
            <line class="line-type-2" ... />
            <g class="dimL">
                <line class="line-type-2" ... />
                <line class="line-type-2" ... />
                <line class="line-type-2" ... />
                <text ... >...</text> 
            </g>
            ...
        </g>
        <g id="layer-1" name="Layer 1" ...>
            ...
        </g>
    </svg>
    <svg id="View2" ... >
        <line class="line-type-1" ... />
        ...
    </svg>
    <svg id="View3" ... > ... </svg>
</svg>

Тег svg

<svg> — тег используется для описания самого чертежа и встроенных видов, штампа и техтребований. Если необходимо использовать масштаб отличный от 1:1, то реализуется с помощью свойств тега.
Например масштаб 1:4

<svg id="View1"
     x="50"
     y="7"
     width="150"
     height="162"
     viewBox="-25 -200 600 648">

width="150" height="162" viewBox="…… 600 648" — соотношение величин задаёт масштаб отображения вида на листе.

Например масштаб 10:1

<svg id="View1" 
     x="50" 
     y="7" 
     width="150" 
     height="162" 
     viewBox="-0.6 -5 15 16.2">

Тег defs

<defs> — здесь описываем все примитивные повторяющиеся элементы. Замечена одна особенность при использовании SVG элемента marker — на него не действуют параметры масштаба из тега <svg>, что намного упрощает работу с масштабом. (При любом масштабе вида стрелки в размерах должны быть одинаковые). Но на линии в элемента marker не действует параметр свойства vector-effect: non-scaling-stroke;

Тег line

<line class=«atr1» …/> — в файле CSS описываем стили линий для графических примитивов. Жаль что в Internet Explorer для каждого масштаба необходимо указывать свой стиль линии (толщина линии и интервал пунктиров). Как правило в чертеже одновременно не используются все возможные масштабы и достаточно задать только для используемых масштабов.
Пример описания стилей линий для элементов line, circle, path, rect и др.:

line, rect, circle, ellipse, path, text {
  vector-effect: non-scaling-stroke;
}
/* main line */
.line-type-1 { fill: none; stroke: blue; stroke-width: 2;
}
/* hairline */
.line-type-2 { fill: none; stroke: black; stroke-width: .7;
}
/* axial */
.line-type-3 { fill: none; stroke: red; stroke-width: .7; stroke-dasharray: 25, 4, 3, 4;
}
/* dashed */
.line-type-4 { fill: none; stroke: black; stroke-width: .7; stroke-dasharray: 7, 4;
}
/* main line for the scale 0.25 */
.line-type-1_025 { fill: none; stroke: blue; stroke-width: 8;
}
/* hairline for the scale 0.25 */
.line-type-2_025 { stroke: black; stroke-width: 2.8;
}

Тег g

<g class="dimL">…</g> — элементы описывающие объекты как размер группируем.
Пример:

...
<defs id="defsCAD">
<!-- Draw arrows and tick marks -->
    <marker id="dimArrow-1" viewBox="-2 -12 29 24" markerWidth="44" markerHeight="36" orient="auto">
        <path class="line-type-2_025" stroke="black" d="M0,0 L20,-4 16,0 20,4 z M0,-10 L0,10 M0,0 L27,0"/>
    </marker>
    <marker id="dimArrow-2" viewBox="-27 -12 29 24" markerWidth="44" markerHeight="36" orient="auto">
        <path class="line-type-2_025" stroke="black" d="M0,0 L-20,-4 -16,0 -20,4 z M0,-10 L0,10 M0,0 L-27,0"/>
    </marker>
</defs>
...
    <g class="DimL">
        <line class="line-type-2" x1="190" y1="180" x2="190" y2="230"/>
        <line class="line-type-2" x1="310" y1="180" x2="310" y2="230"/>
        <line id="dim1" class="line-type-2" x1="190" y1="230" x2="310" y2="230" marker-start="url(#dimArrow-1)" marker-end="url(#dimArrow-2)"/>
        <text x="265" y="222" font-size="28" text-anchor="middle">120</text> 
    </g>
...

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

<svg id="Shtamp" type="1" x="0" y="0" width="420" height="297" viewBox="0 0 420 297">
    ...
    <rect class="line-type-2" x="1" y="1" width="418" height="295"/>
   ....
</svg>