SVG viewBox нарушает 100% заполнение viewPort при сохранении соотношения сторон

Вопрос: Как я могу использовать систему координат viewBox, по-прежнему полностью заполняя viewPort и сохраняя соотношение сторон?

Я новичок в программировании svg, поэтому, надеюсь, я просто неправильно понимаю базовую концепцию.

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

Вот базовый пример, с которым я пытаюсь приступить к работе (JSFiddle):

<svg version="1.1" 
     xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink" 
     width="200px" 
     height="400px"  
     preserveAspectRatio="xMidYMid meet" 
     style="border: 1px solid black;">

    <image x="0" y="0" width="100%" height="100%"
           preserveAspectRatio="xMidYMid meet"
           xlink:href="http://www.bized.co.uk/sites/bized/modules/bized_cb_navigation/images/floorplan_info.gif">
    </image>
</svg>

Это прекрасно работает. поскольку, однако, viewPort изменяется, изображение всегда заполняет его, сохраняя при этом соотношение сторон. (См. пример широкоэкранного изображения)

Затем я добавляю систему координат viewBox="0 0 100 100":

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

Когда я проверяю SVG в инспекторе элементов DOM Chrome, для первых двух примеров без использования viewBox="0 0 100 100" элемент svg имеет тот же размер, что и viewPort. После добавления атрибута viewBox элемент становится квадратом со сторонами, равными меньшей из сторон viewPort.

Это поведение объясняется в этом руководстве как:

«... окно просмотра масштабируется в соответствии с меньшим из двух соотношений сторон ...»

Мне нужен атрибут viewBox, чтобы я мог масштабировать и панорамировать изображение в viewPort.


person Rafael Emshoff    schedule 15.07.2015    source источник


Ответы (2)


Это потому, что у вас фактически есть два конкурирующих преобразования viewBox.

Из-за вашего квадратного viewBox вы помещаете изображение в квадрат, а затем вставляете квадрат в свой прямоугольник SVG.

Если вы сделаете SVG viewBox такими же размерами, как ваше изображение (или подойдет такое же соотношение сторон), проблема будет решена.

viewBox="0 0 155 210"

http://jsfiddle.net/2qexypLs/15/

http://jsfiddle.net/2qexypLs/16/

person Paul LeBeau    schedule 15.07.2015

Мое текущее решение - использовать JavaScript для динамической установки значений viewBox width и height на то же значение, что и значения svg width и height. Таким образом, соотношение сторон для x и y будет одинаковым, а заливка вернется к 100% viewPort. (JsFiddle)

Для слоя интерактивных элементов карты у меня есть отдельная система координат, которая сопоставляется с коэффициентом масштабирования фонового изображения, когда определен svg viewPort. Это означает, что все координаты необходимо пересчитать в событии svg define / change width / height.

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

person Rafael Emshoff    schedule 15.07.2015