Jak skalować uparty SVG osadzony za pomocą tagu <object>?

114

Mam kilka plików SVG, które określają, widtha heighttakże viewboxtak:

<svg width="576pt" height="432pt" viewBox="0 0 576 432" > ...

ale jak wyświetlić je w przeglądarce w wybranym przeze mnie rozmiarze? Chcę, żeby były mniejsze i próbowałem:

<object width="400" data="image.svg"></object>

ale wtedy widoczne są paski przewijania.

To działa, jeśli zmienię plików SVG do zbioru widthi heightaby 100%zamiast tego, ale chcę, aby zdecydować, rozmiar w HTML niezależnie od tego, jakie rozmiary są używane w pliku SVG. Czy to możliwe ?

Zitrax
źródło
Jestem zdezorientowany, ostatnie zdanie brzmi jak rozwiązanie, którego szukasz? Ustawić szerokość / wysokość SVG na 100% / 100%, pozostawiając HTMLowi określenie obszaru do narysowania?
znak
3
Problem polega na tym, że nie znalazłem sposobu, aby to zmienić w bibliotece, której używam do generowania plików svg. Miałoby to dla mnie sens, gdybym mógł zastąpić to z html. Więc w zasadzie zastanawiam się, czy istnieje inne rozwiązanie niż zmiana plików svg.
Zitrax

Odpowiedzi:

161

Aby to osiągnąć, możesz dodać do <svg>znacznika atrybuty „preserveAspectRatio” i „viewBox” .

Otwórz plik .svg w edytorze i znajdź <svg>tag. w tym tagu dodaj następujące atrybuty:

preserveAspectRatio="xMinYMin meet"
viewBox="0 0 {width} {height}"

Zastąp {szerokość} i {wysokość} niektórymi wartościami domyślnymi dla viewBox. Użyłem wartości z atrybutów „width” i „height” znacznika SVG i wydawało się, że działa.

Zapisz plik SVG i powinien teraz skalować się zgodnie z oczekiwaniami.

Znalazłem te informacje tutaj:

https://blueprints.launchpad.net/inkscape/+spec/allow-browser-resizing

Jim Keller
źródło
2
#protip wszystko, czego potrzebujesz, aby to dodać to preserveAspectRatio = "xMinYMin meet"
samccone
4
@samccone: Wygląda na to, że to preserveAspectRatio="xMinYMin meet"mi nie wystarczyło. Musiałem również podać viewBoxjak wspomniano w odpowiedzi. Szkoda!
Frerich Raabe
1
Możesz także zrobić, preserveAspectRatio="none"jeśli chcesz rozciągnąć plik SVG na dowolny sposób.
Matt Crinklaw-Vogt,
5
Nie daj się nabrać na ten sam problem, co ja: „viewbox”! = „ViewBox” :)
Dr. Ü
Ponadto musiałem ustawić rzeczywiste atrybuty szerokości i wysokości 100%zgodnie z tą odpowiedzią .
ComFreek
35

Żadna z udzielonych tutaj odpowiedzi nie zadziałała, gdy zadałem to pytanie w 2009 roku. Ponieważ teraz znowu miałem ten sam problem, zauważyłem, że użycie <img>tagu i szerokości razem z plikiem svg działa dobrze.

<img width="400" src="image.svg">
Zitrax
źródło
6
Jest to o wiele prostsze niż inne opcje! Jeśli ktoś jest ciekawy, poniżej znajduje się tabela przeglądarek, które mogą obsługiwać pliki SVG w tagach <img> .
dimo414
5
Może to być najlepsza ścieżka, jeśli w SVG nie ma hiperłączy, w przeciwnym razie img jest niewystarczające i nadal należy użyć alternatywnej metody, takiej jak embed.
sdupton,
12
Kiedy używasz <img>, tracisz całą interaktywność z linkami, JavaScriptem itp.
gilly3
5
Minor: element img powinien zamykać się samoczynnie, tj <img width="400" src="image.svg"/>.
Jan Aagaard
4
@JanAagaard: Zamknięcie tagu img nie jest wymagane, z wyjątkiem XHTML.
Peter V. Mørch
9

Możesz dotrzeć do osadzonego pliku SVG za pomocą JavaScript:

var svg = document.getElementsByTagName('object')[0].\
  contentDocument.getElementsByTagName('svg')[0];
svg.removeAttribute('width');
svg.removeAttribute('height');

Ponieważ twój svg ma już viewBox, Firefox powinien przeskalować szerokość 576 pikseli w viewBox do szerokości 400 pikseli w dokumencie. Inne pliki SVG mogą skorzystać z nowego ViewBox pochodzącego z reklamowanej szerokości i wysokości (często są to te same liczby). Inne przeglądarki mogą skorzystać na różnych poprawkach SVG.

joeforker
źródło
1
To dało mi:Security error: attempted to read protected variable
Zitrax
1
Czy plik SVG jest hostowany w tej samej domenie co Twoja strona internetowa?
joeforker
1
To nie było (localhost to external), więc prawdopodobnie tak, jednak skorzystałem z poniższej odpowiedzi, ponieważ była prostsza.
Zitrax
9
<body>

<div>
<object type="image/svg+xml" data="img/logo.svg">
   <img src="img/logo.svg" alt="Browser fail" />
</object>
</div>

img / logo.svg ...

<svg
   width="100%" 
   height="100%"
   viewBox="0 0 640 80"
   xmlns="http://www.w3.org/2000/svg"
   version="1.1" />

Ta konfiguracja zadziałała dla mnie.

H Titan
źródło
To działa całkiem nieźle! Naprawdę ważna jest faktyczna definicja viewBox="0 0 640 80". Najwyraźniej jeśli nie jest to zdefiniowane, nie możesz tak naprawdę tego skalować lub pozwolić CSS skalować go za Ciebie, używając np. width: 100%Itp.
Igor
8

Napotkałem problem polegający na tym, że iOS na iPadzie nie zmieniał poprawnie rozmiaru obrazów SVG w <object>tagu.

Styl CSS zwiększyłby lub zmniejszył rozmiar <object>kontenera, ale znajdujący się w nim obraz nie zostałby zmodyfikowany (na iPadzie, iOS 7).

Obrazy SVG zostały wyeksportowane z Adobe Illustrator, a rozwiązaniem okazało się zastąpienie szerokości i wysokości w tym:

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="481.89px" height="294.843px" viewBox="0 0 481.89 294.843" 
enable-background="new 0 0 481.89 294.843"
xml:space="preserve">

z:

width="100%" height="100%"

Musiałem użyć <object>tagu, ponieważ <img>tag nie obsługuje obecnie osadzania obrazów bitmapowych w plikach SVG.

Andrew Swift
źródło
To jest poprawna odpowiedź, zwłaszcza jeśli masz wbudowany SVG i nie używasz tagu <img! Idealny!
Greg Ellis
5
  1. Ustaw brakujące pole widoku i wypełnij wartości wysokości i szerokości ustawionych atrybutów wysokości i wysokości w tagu svg

  2. Następnie przeskaluj obraz, ustawiając wysokość i szerokość na żądane wartości procentowe . Powodzenia.

  3. Możesz ustawić stały współczynnik proporcji za pomocą preserveAspectRatio = "x200Y200 meet, ale nie jest to konieczne

na przykład

 <svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:xlink="http://www.w3.org/1999/xlink"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   width="10%" 
   height="10%"
   preserveAspectRatio="x200Y200 meet"
   viewBox="0 0 350 350"
   id="svg2"
   version="1.1"
   inkscape:version="0.48.0 r9654"
   sodipodi:docname="namesvg.svg">
Lorenz Lo Sauer
źródło
3

Po prostu użyj CSS, aby przeglądarka zmieniła rozmiar SVG! Na przykład: <object style="width:30%"> zobacz http://www.vlado-do.de/svg_test/, aby uzyskać więcej informacji. Po prostu wypróbowałem to również lokalnie z plikiem SVG, którego szerokość i wysokość są podane w „pt”. Działa dobrze w przeglądarce Firefox.

Vlado
źródło
1

Pokazać. Musiałem odświeżyć pamięć na SVG, nie używałem go zbyt wiele przez te lata.

Z tego, co znalazłem dzisiaj, wydaje się, że jeśli określisz wymiary obiektów bez jednostek, mają one stały rozmiar (chyba w pikselach). Wygląda więc na to, że nie ma możliwości zmiany ich rozmiaru podczas zmiany rozmiaru SVG (zmienia to tylko rozmiar widoku / obszaru roboczego).

Chyba że, jak wskazano, określasz rozmiar SVG w procentach LUB określisz viewBox (np. ViewBox = "0 0 600 500").

Jeśli nie możesz zmienić wyeksportowanego pliku SVG, obawiam się, że nie masz szczęścia. Z jakiej biblioteki korzystasz?

PhiLho
źródło
Backend SVG w matplotlib. Próbowałem funkcji takich jak set_figwidth (val), ale wydaje się, że nie działają, ale nie jestem zaznajomiony z tą biblioteką, więc mogę patrzeć na niewłaściwe funkcje.
Zitrax,
1

Oto rozwiązanie PHP wykorzystujące QueryPath na podstawie odpowiedzi Jima Kellera.

Po załadowaniu QueryPath po prostu przekaż swój skrypt svg do funkcji.

function scaleableSVG($svg){
    $qp = qp($svg, 'svg');
    $width = $qp->attr('width');
    $height = $qp->attr('height');
    $qp->removeAttr('width')->removeAttr('height');                       
    $qp->attr('preserveAspectRatio', "xMinYMin meet");
    $qp->attr('viewBox', "0 0 $width $height");
    return $qp->html();
}
Dieter Gribnitz
źródło