Como escalonar um SVG teimoso incorporado com a tag <object>?


114

Tenho alguns arquivos SVG que especificam widthe heighttambém viewboxassim:

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

mas como exibi-los no navegador em um tamanho que eu decido? Eu os quero menores e tentei:

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

mas então recebo barras de rolagem visíveis.

Funciona se eu alterar os arquivos SVG para definir widthe heightpara 100%, mas quero decidir o tamanho no HTML, independentemente dos tamanhos usados ​​no arquivo SVG. Isso é possível ?


Estou confuso, a última frase parece a solução que você está procurando? Definir a largura / altura do SVG como 100% / 100% deixa a cargo do HTML definir a área para desenhá-lo?
marque

3
O problema é que não encontrei nenhuma maneira de mudar isso na biblioteca que uso para gerar os arquivos svg. E faria sentido para mim se eu pudesse substituir isso do html. Então, basicamente, eu me pergunto se há outra solução do que alterar os arquivos SVG.
Zitrax

Respostas:


161

Você pode adicionar os atributos "preserveAspectRatio" e "viewBox" à <svg>tag para fazer isso.

Abra o arquivo .svg em um editor e encontre a <svg>tag. nessa tag, adicione os seguintes atributos:

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

Substitua {width} e {height} por alguns padrões para o viewBox. Usei os valores dos atributos "largura" e "altura" da tag SVG e pareceu funcionar.

Salve o SVG e ele deverá ser dimensionado conforme o esperado.

Encontrei esta informação aqui:

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


2
#protip tudo que você precisa para adicioná-lo this preserveAspectRatio = "xMinYMin meet"
samccone

4
@samccone: Parece que preserveAspectRatio="xMinYMin meet"não foi o suficiente para mim. Também precisei fornecer um viewBoxconforme mencionado na resposta. Pena!
Frerich Raabe

1
Você também pode fazer isso preserveAspectRatio="none"se quiser esticar o SVG de maneiras arbitrárias.
Matt Crinklaw-Vogt

5
Não caia no mesmo problema que eu: "viewbox"! = "ViewBox" :)
Dr.Ü

Além disso, tive que definir os atributos reais de largura e altura 100%conforme esta resposta afirmava.
ComFreek de

35

Nenhuma das respostas fornecidas aqui funcionou para mim quando perguntei isso em 2009. Como agora eu tinha o mesmo problema novamente, percebi que usar a <img>tag e a largura junto com um svg funciona bem.

<img width="400" src="image.svg">

6
Isso é muito mais simples do que as outras opções! Caso alguém esteja curioso, aqui está uma tabela de quais navegadores podem lidar com SVGs nas tags <img> .
dimo414

5
Esse pode ser o melhor caminho se não houver hiperlinks em SVG, caso contrário, img é insuficiente e ainda deve-se usar uma alternativa como embed.
sdupton

12
Ao usar <img>você perde toda a interatividade com links, javascript, etc.
gilly3

5
Menor: O elemento img deve ser auto fechado, isto é <img width="400" src="image.svg"/>.
Jan Aagaard

4
@JanAagaard: Não é necessário fechar a tag img, exceto em XHTML.
Peter V. Mørch

9

Você pode acessar o svg incorporado usando JavaScript:

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

Como seu svg já tem um viewBox, o Firefox deve dimensionar a largura de 576 pixels no viewBox para a largura de 400 pixels em seu documento. Outros SVGs podem se beneficiar de um novo viewBox derivado da largura e altura anunciadas (geralmente são os mesmos números). Outros navegadores podem se beneficiar de diferentes ajustes de svg.


1
Isso me deu:Security error: attempted to read protected variable
Zitrax

1
O svg está hospedado no mesmo domínio de sua página da web?
joeforker de

1
Não era (localhost to external), então provavelmente é isso, porém acabei usando a minha resposta abaixo por ser mais simples.
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" />

Esta configuração funcionou para mim.


Isso realmente funciona muito bem! O que é realmente importante é definir de fato viewBox="0 0 640 80". Aparentemente, se isso não for definido, você não pode realmente dimensioná-lo ou deixar que o CSS o dimensione para você usando, por exemplo, width: 100%etc.
Igor

8

Eu encontrei um problema em que o iOS em um iPad não redimensionava corretamente as imagens SVG em um <object> tag.

O estilo CSS aumentaria ou diminuiria o tamanho do <object>contêiner, mas a imagem dentro dele não seria modificada (no iPad, iOS 7).

As imagens SVG foram exportadas do Adobe Illustrator, e a solução acabou sendo substituir a largura e a altura neste:

<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">

com:

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

Eu precisei usar a <object>tag porque <img>ela não suporta a incorporação de imagens de bitmap em SVGs.


Esta é a resposta correta, especialmente se você tiver SVG embutido e não usar a tag <img! Perfeito!
Greg Ellis

5
  1. Defina a caixa de visualização ausente e preencha os valores de altura e largura dos atributos definidos de altura e altura na tag svg

  2. Em seguida, dimensione a imagem simplesmente definindo a altura e a largura para os valores percentuais desejados . Boa sorte.

  3. Você pode definir uma proporção fixa com preserveAspectRatio = "x200Y200 meet, mas não é necessário

por exemplo

 <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">

3

Basta usar CSS para fazer o navegador redimensionar o SVG! Da mesma forma: <object style="width:30%"> Veja http://www.vlado-do.de/svg_test/ para mais detalhes. Eu também tentei localmente com um SVG que tem sua largura e altura fornecidas em "pt". Funciona bem no Firefox.


1

Vamos ver. Tive que refrescar a memória no SVG, não o tenho usado muito nesses anos.

Pelo que descobri hoje, parece que se você especificar dimensão de objetos sem unidades, eles têm um tamanho fixo (em pixels, eu acho). Aparentemente, então, não há como redimensioná-los quando você redimensiona o SVG (isso apenas altera o tamanho da janela de visualização / tela).

A menos que, conforme indicado, você especifique o tamanho do SVG em porcentagem OU especifique um viewBox (por exemplo, viewBox = "0 0 600 500").

Agora, se você não tem como alterar o SVG exportado, você está sem sorte, eu temo. Que biblioteca você usa?


O backend svg em matplotlib. Eu tentei funções como set_figwidth (val), mas não parece funcionar, mas não estou muito familiarizado com esta biblioteca, então posso estar olhando para as funções erradas.
Zitrax

1

Aqui está uma solução PHP usando QueryPath com base na resposta de Jim Keller.

Assim que o QueryPath for carregado, basta passar seu script svg para a função.

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();
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.