Поместите квадрат svg в центр экрана, масштабируйте его, чтобы он соответствовал ширине и высоте экрана с некоторыми ограничениями
Кажется, это глупый вопрос и, возможно, обман, но на какое-то время я не нашел подходящего решения, поэтому, наконец, осмелюсь спросить.
Я хочу разместить элемент <svg>
внутри html-документа и выполнить следующие требования:
- Изображение помещается как элемент
<svg>
html5, а не внешний svg файл. (На самом деле, я хочу динамически генерировать его с помощью D3.js.)
- Изображение помещается в центр экрана, как по вертикали, так и по горизонтали.
- Фактический размер изображения не должен превышать предопределенное значение (например,
15cm × 15cm
).
- Если текущая ширина экрана или высота меньше, чем
15cm
, изображение следует масштабировать (сохраняя пропорции) таким образом, чтобы оно соответствовало экрану. Никакие части изображения не должны быть обрезаны. Изображение должно быть размещено в центре.
В основном те же требования, что описаны в в этой статье. В нем говорится, что я должен использовать preserveAspectRatio="xMidYMid"
, но не дает никакого примера, как это сделать и как он соответствует другим трюкам, описанным в статье. В этой статье предлагается preserveAspectRatio="xMidYMid meet"
, но снова я не смог воспроизвести приведенные здесь примеры для удовлетворения всех моих требований.
Мой текущий код похож на этот, но он не подходит по высоте и не центрируется по вертикали.
.svg-container {
height:100%;
width:100%;
max-height:15cm;
max-width:15cm;
margin: 0 auto;
}
<div class="svg-container">
<svg id="picture" preserveAspectRatio="xMidYMid meet" viewBox="0 0 100 100">
<circle cx=50 cy=50 r=50></circle>
</svg>
</div>
Ответы
Ответ 1
Следующее работает, если соотношение сторон SVG задано. Если соотношение сторон SVG динамическое, вы должны использовать JavaScript, я считаю.
Этот фрагмент работает в современных браузерах и в полной мере использует относительно новую vmin
длину окна просмотра. Поддержка браузера довольно хорошая. Для горизонтального и вертикального центрирования используется режим flexbox. Опять же, поддержка браузера довольно хорошая.
Фокус в том, что размеры SVG заданы относительно ширины или высоты экрана, в зависимости от того, что меньше всего. Это означает, что даже если мы установим его как 100vmin
, SVG гарантированно будет соответствовать экрану (но едва). Чтобы обеспечить максимальные размеры, старый добрый max-width
и max-height
, в точности так, как они предназначены для использования.
html, body {
/* ensure that all of the viewport is used */
width: 100%;
height: 100%;
/* ensure that no scrollbars appear */
margin: 0;
padding: 0;
/* center SVG horizontally and vertically */
display: flex;
align-items: center;
justify-content: center;
}
#picture {
/* ensure 1:1 aspect ratio, tweak 50 to make SVG larger */
width: 50vmin;
height: 50vmin;
/* set some maximum size (width and height need to match
* aspect ratio, 1:1 in this case */
max-width: 200px;
max-height: 200px;
}
<svg id="picture" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="50"></circle>
</svg>
Ответ 2
Попробуйте этот css:
#picture {
transform: translate(-50%, -50%);
top: 50%;
left: 50%;
position: absolute;
max-height:15cm;
max-width:15cm;
width: 80%;
height: 80%;
}
вот результат:
https://jsfiddle.net/twe9jfkf/
это то, чего вы пытаетесь достичь?
Ответ 3
Вместо css вы можете попробовать использовать svg width/height и viewBox, вычисленный с помощью getBBox()
Ниже приведен базовый пример:
<!DOCTYPE HTML>
<html>
<body>
<svg>
<circle cx=50 cy=50 r=50 fill=red />
</svg>
<script>
//--onload, onresize----
function sizeSVG()
{
var mySVG=document.getElementsByTagName("svg")[0]
var svgW=window.innerWidth
var svgH=window.innerHeight
var bb=mySVG.getBBox()
var bbx=bb.x
var bby=bb.y
var bbw=bb.width
var bbh=bb.height
mySVG.setAttribute("viewBox",bbx+" "+bby+" "+bbw+" "+bbh )
mySVG.setAttribute("width",svgW)
mySVG.setAttribute("height",svgH)
}
document.addEventListener("onload",sizeSVG(),false)
window.onresize=sizeSVG
</script>
</body>
</html>
Ответ 4
Решение flexbox было бы моим первым выбором.
Поскольку кто-то еще ответил с этой идеей, я придумал этот подход.
В основном это абсолютная технология центрирования и полагаться на абсолютную позицию и автоматическую маржу, чтобы центрировать элемент.
body {
height: 100vh;
margin: 0;
}
svg#picture {
max-height: 15cm;
max-width: 15cm;
height:100%;
width:100%;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin:auto;
}
<svg id="picture" preserveAspectRatio="xMidYMid meet" viewBox="0 0 100 100">
<circle cx=50 cy=50 r=50></circle>
</svg>
Ответ 5
Вы пытались добавить изображение в качестве фона в свой svg-контейнер?
.svg-container {
height:100%;
width:100%;
max-height:15cm;
max-width:15cm;
margin: 0 auto;
background-image:url('yourSVG.svg');
background-repeat: no-repeat;
background-size: contain;
}
Ответ 6
Вы все еще хотите вертикальную вертикаль? посмотрите это
.vertical-align {
height:1000px;
display: flex;
align-items: center;
justify-content: center;
}
.svg-container {
max-height:15cm;
max-width:15cm;
height: 100%;
width: 100%;
}
<div class="vertical-align">
<div class="svg-container">
<svg id="picture" preserveAspectRatio="xMidYMid meet" viewBox="0 0 100 100">
<circle cx=50 cy=50 r=50></circle>
</svg>
</div>
</div>