Is it possible to check the code of a vector design? - svg

I understand that all vector drawings (even others) are made of codes. I was wondering if its possible to check the code of the same. For instance, if I have a rectangle in .svg or .eps format, how do I check the code that makes this rectangle ?

Try opening it in a text editor?
For instance, this image should look like this:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%" viewBox="0 0 100 100">
<title>SVG Logo</title>
<a xlink:href="http://www.w3.org/Graphics/SVG/" target="_parent"
xlink:title="W3C SVG Working Group home page">
<rect
id="background"
fill="#FF9900"
width="100"
height="100"
rx="4"
ry="4"/>
...

Related

SVG patterns rasterised when printing to PDF

I'm trying to create a SVG file what when printed to PDF maintains all of its parts in vector. This file uses a pattern as a fill to a path, or in the example bellow as the fill to the rect element:
<svg
width="200"
height="200"
viewBox="0 0 200 200"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
className="productWrapper"
>
<defs>
<pattern id="pattern" x="0" y="0" width="1" height="1">
<path
fill="#fcc"
d="[vector path here]"
/>
</pattern>
</defs>
<rect fill="url(#pattern)" stroke="black" width="200" height="200" />
</svg>
The issue I'm facing is that when printed to PDF the rect element or any path at the top level of the SVG file stays vector, but all vector content inside the pattern is rasterized.
A very minimal example of this can be found here:
https://6j8953j8rn.codesandbox.io/
Any way to get the SVG to render in vector when printing to PDF?
One tool that kept vector info after converting from SVG (including <pattern>) to PDF (I used it as CLI) is https://github.com/typst/svg2pdf
Some online converters also could do it while the most of other tools I tried make content inside <pattern> raster.

Is it possible to center a SVG pattern image fill without using JavaScript?

I have the following SVG:
<?xml version="1.0" encoding="UTF-8"?>
<svg width="480" height="1080" version="1.1" viewBox="0 0 480 1080" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<pattern id="wpi" width="100%" height="100%" patternUnits="userSpaceOnUse">
<image width="100%" height="100%" preserveAspectRatio="none" xlink:href="h_img.jpg" x="0" y="0"/>
</pattern>
</defs>
<rect class="wallpaper" width="100%" height="250" fill="url(#wpi)"/>
</svg>
The h_img jpg might vary on time, loading different images, so I can't be aware of its size in advance, yet I know that, most of the time, its height value is greater than its width but I need to apply it to a rect element that has a smaller height compared to its own width and this is for sure (despite I'm using a relative 100% value for that one). I need the pattern to fill that rect with the image maintaining its aspect ratio and the height being crop (or hide overflow) centered. I know I can use JavaScript to calculate the image relative width, resize the height accordingly to maintain the aspect ratio and calculate the offset needed to provide the centering (and I did) but... Do you know maybe is there a way to do what I need simply using the right parameters on the SVG element and no JavaScript?
I tried with:
<pattern id="wpi" width="100%" height="100%" patternContentUnits="objectBoundingBox">
<image width="1" height="1" preserveAspectRatio="xMidYMid" xlink:href="h_img.jpg" x="0" y="0"/>
</pattern>
But that doesn't get me the desired effect I need...
Thanks for your help
SOLVED EDIT:
Thanks to #ccprog for his suggestion took me on the right direction, I managed to find a way to solve like this:
<?xml version="1.0" encoding="UTF-8"?>
<svg width="480" height="1080" viewBox="0 0 480 1080" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<defs>
<pattern id="wpi" width="1" height="1">
<image width="100%" height="250" preserveAspectRatio="xMidYMid slice" xlink:href="h_img.jpg"/>
</pattern>
</defs>
<rect class="wallpaper" width="100%" height="250" fill="url(#wpi)"/>
</svg>
Notice: you need to set for the <image> just the same height and width values used for the pattern image container area (= that means the size of the element on which the pattern is going to be applied, in this case it's a <rect>).
As final words I'll say there are at least a couple of reasons for I wanted the image to stay applied within a pattern:
one is that, in this way, I can be able to use javascript code to shift the centering of the image by y and x attributes values while letting the rectangle stay in its position;
and another reason is I could change the rectangle fill to a solid color easily if I need doing it.
If you want to display an image once in a rectangular area, you do not need a pattern. Patterns are for repeating content more than once.
The attribute you were searching for is preserveAspectRatio="xMidYMid slice". See the spec.
<svg width="480" height="1080" viewBox="0 0 480 1080"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<image class="wallpaper" width="100%" height="250"
preserveAspectRatio="xMidYMid slice" xlink:href="h_img.jpg"/>
</svg>

Transforming <svg> element in SVG behaves differently in Chrome, Firefox

I have a fairly simple SVG which I've converted into a SSCCE. Here's the SVG (and a fiddle you can see for yourself):
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<rect id="leader" width="100%" height="100%" stroke="red" fill="none" />
<svg id="left" x="5%" y="5%" width="40%" height="85%">
<rect width="100%" height="100%" fill="blue"/>
</svg>
<svg id="left" x="55%" y="5%" width="40%" height="85%" transform="scale(.5)">
<rect width="100%" height="100%" fill="red"/>
</svg>
</svg>
I'm expecting a large, empty red rectangle containing two smaller rectangles: one blue one which takes up quite a bit of space and another one (red) which is half the size of the blue one. There is a translation which occurs as well, but that's not terribly important for this question.
In Firefox, I get the expected image, which is this:
However, when I view the same image in Chrome (or Safari), it seems to be ignoring my transformation, and the two rectangles are both the same size:
Is there something wrong with my SVG, is this a bug in either of these browsers, or is this an unsupported part of SVG in Chrome/Safari? There is an old bug from early 2017 which is reported to be fixed, so I'm thinking that I'm missing something about the way SVG transforms are supposed to work.
The transform attribute for an <svg> element has only been introduced for SVG 2. For now it is not supported in all browsers. (Setting a version attribute on the root element has no effect.)
You can achieve the same effect if you wrap the <svg> element with a <g> and define the transformation there. The percentage values for the positioning will still be relative to the nearest parent element establishing a viewport, which is the outer <svg>.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<rect id="leader" width="100%" height="100%" stroke="red" fill="none" />
<svg id="left" x="5%" y="5%" width="40%" height="85%">
<rect width="100%" height="100%" fill="blue"/>
</svg>
<g transform="scale(.5)">
<svg id="left" x="55%" y="5%" width="40%" height="85%">
<rect width="100%" height="100%" fill="red"/>
</svg>
</g>
</svg>
The bug you referenced, btw, does not apply. It's not easy to see at first glance, but the attached test case shows this refers to setting a transformation on a <g> element via script.

How to reuse <image> tags in SVG <defs>?

I have a situation where to save on memory and loading, I am trying to reuse a single <image> tag in an SVG, instead of referencing the same xlink:href in several <image> tags.
My research has shown that <use> is the tag to reference a defined object.
However, when I try to reference an image, particularly inside a pattern (which is what I am trying to do), I get nothing, where using an image tag works fine.
What am I doing wrong? Is this even possible? I tried searching, but could not find any examples of the <use> tag with an image, just rects, paths, groups, etc.
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px" y="0px" viewBox="0 0 1024 600" >
<style type="text/css">
.fillme{fill:url(#tsmall)}
</style>
<defs>
<image id="texture" xlink:href="texture.tiny.png" />
<pattern id="tsmall" patternUnits="userSpaceOnUse" width="486" height="402">
<use xlink:href="#texture" x="0" y="0" width="486" height="402" />
</pattern>
<pattern id="tlarge" patternUnits="userSpaceOnUse" width="972" height="804">
<use xlink:href="#texture" x="0" y="0" width="972" height="804" />
</pattern>
</defs>
<rect x="0" y="0" width="1024" height="600" class="fillme"/>
</svg>
SVG image elements must have width and height attributes, yours doesn't.
An image is a graphics element and if you point a <use> at a graphics element the <use> width and height are ignored per the SVG specification (since it's not a symbol or an svg element it falls into the Otherwise case in the specification)

Text Wrap inside SVG Shape

I need to wrap text inside a shape. This is the code I found in a reference, but itself is not working. Can anyone help me?
<svg xmlns:svg="http://www.w3.org/2000/svg" version="1.2"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="600px" height="400px" viewBox="0 0 300 310">
<title>Basic textflow</title>
<rect x="0" y="0" width="100%" height="100%" fill="yellow"/>
<flowRoot font-size="16" fill="black" color="black">
<flowRegion>
<path d="M100,50L50,300L250,300L300,50z"/>
<flowText>Tomorrow, and tomorrow, and tomorrow; creeps in this
petty pace from day to day, until the last syllable of recorded time.
And all our yesterdays have lighted fools the way to dusty death.
</flowText>
</flowRegion>
</flowRoot>
<path d="M90,40L40,270L260,270L210,40z" fill="none" stroke="black" stroke-width="5"/>
</svg>
My Requirement:
This is not the answer you want but it is the best I've found. Both FireFox and to lesser extent Chrome support the foreignObject tag. With this you can add text. This generally works well but you are limited to a rectangle for wrapping this way. The xmlns attribute is required.
<foreignObject x="225" y="630" width="157" height="125">
<div class="plain-text" xmlns="http://www.w3.org/1999/xhtml">
You can put really long lines of text here and they will wrap as you would hope they would. The problem is that Chrome doesn't support <ul><li> tags in side the foreignObject.
</div>
</foreignObject>
The desired flow region is just not supported by any browser. Here's a link to Stackoverflow answer that gives more detail.
Auto line-wrapping in SVG text

Resources