Embed SVG into HTML - html

I need to embed a SVG file into HTML file, the SVG's dimensions are bit larger. so, I need the SVG to be re-sized to the screen resolution. Is there any way to do that? Thanks.

If you want an SVG file to fit in a container the first thing to do is to set a viewBox attribute and remove width and height attributes from the root <svg> element:
<svg viewBox="0 0 100 200" ... >
The values of a viewBox are: x y width height. Read more in the SVG specification.

I dont know how complex is that SVG, but at least you can put whole description under one group , and then use transform="scale(SF)" whereas "SF" stands for scaling factor. Default is 1 (100%), so use little script:
TransFrm = "scale(" + SF + ")";
yourElement.setAttributeNS(null, "transform", TransFrm);
Or if you mean resizing by viewBox then <rect x="0" y="0" width="100%" height="100%"/>.
Or if you mean something else take a look at: http://janistoolbox.typepad.com/blog/2009/12/svgauto-resize-svg-on-an-html-page.html
Good luck.

Related

Loading large images into svg component

I created an svg pattern which I feel with image. The thing is that the image is quite large (over 2mb) and it takes long to load (I keep it in assets folder in my app). However I checked that it works similarly with images that are large and downloaded from the web.
Is there a way to make big images load faster (so that this yellow svg pattern behind the image is not visible, while images did not finish loading) in svg?
<pattern id="pattern0" patternContentUnits="userSpaceOnUse" width="100%" height="100%">
<image xlink:href="https://images.hdqwalls.com/download/blue-light-buildings-architecture-8k-dv-7680x4320.jpg" x="0" y="0" width="100%" />
</pattern>
Example provided here
https://codepen.io/pokepim/pen/bGeMmNB
So as you can see the image laods slowly and the yellow black gradient is clearly visible at the beginning when page is loading.
One or more things you could do:
Reduce the resolution. 7680x4320 is way larger than you need for typical screen sizes.
Approx 15-20% of the image at the bottom is never visible. It could be trimmed.
Increase the compression ratio.
Just by reducing the size to 1600x700 (steps 1 & 2), I was able to reduce the file size to 250k, even with minimum JPEG compression.
Other things you could do:
Embed the image in the SVG as a Data URI (data://), so that the image loads as part of the SVG
Display a low resolution version of the image while the larger image is loading (eg BlurHash)
You can make the SVG hidden during the load and display it when finished loading with javascript.
You will need to add and reference ID to the SVG and make it hidden.
Then on image loaded, change to display block.
Here and example (not elegant one, don't use in production)
<svg
id="image-bg"
style="display: none;"
...
>
...
<pattern ...>
<image
...
onload="document.getElementById('image-bg').style.display='block'"/>
</pattern>
...
</svg>
https://css-tricks.com/illustrator-to-svg/
Here is a good website with some details.
Saving the svg with the image "embedded" in the svg as data rather than referencing it like that in the svg will vastly improve your load times.

Equivalent of "background-repeat: round" in SVG?

CSS has a handy option for background images in HTML elements: If I have a pattern that is 20 pixels high, but my HTML element has a height that isn't evenly divisible by 20 (e.g. 150px or 35px), background-repeat: round will tile the pattern to make it appear seamless, stetching/squeezing the tiles as needed.
Is there an equivalent styling option for patterns within an SVG element? For example:
<defs>
<pattern id="myPattern" width="200" height="100" patternUnits="userSpaceOnUse">
... some pattern ...
</pattern>
</defs>
<rect width="200" height="230" fill="#myPattern"/>
I'd like to have two whole repetitions of the pattern in my rectangle (stretched to 115px each), not two whole repetitions and a partial third.
EDIT
The solution by ccprog (below) works fine for this particular example. However, it requires the pattern to define how many times it will be repeated. I'm still holding out hope for a general solution for cases where the elements using the pattern are of different heights (and hence will require different numbers of pattern repetitions).
You can set a viewBox for patterns and define pattern units in terms of the object bounding box:
<defs>
<pattern id="myPattern" width="50%" height="50%"
viewBox="0 0 200 100" preserveAspectRatio="none"
patternUnits="objectBoundingBox">
... some pattern ...
</pattern>
</defs>
<rect width="200" height="230" fill="#myPattern"/>
It's not completely equivalent to CSS round, as you implicitely give the absolute number of repetitions with the width/height attributes, no matter how large the filled area is.

Animate a DIV element along a SVG path by clicking a button

I have a SVG path:
<path d="M124 442 L124 442 L166 393 L162 332 L200 251 L179 76" stroke="red" stroke-width="2" fill="none" fill-opacity="0.1"></path>
And I want that a DIV element move along this path when I click a "next-button".
It's like:
*startpoint (beginning of the path) + DIV element
*click next-button* + DIV element moves to station 1
*station 1
*click next-button* + DIV element moves to station 2
*station 2
*click next-button* + DIV element moves to the end of the path
endpoint (end of the path)
Does anyone have an idea how I could do that?
Found a very helpful tools. Its called path animator.
That could be your friend.
https://github.com/yairEO/pathAnimator
If you really want to animate an HTML element using SVG, then you might want to have a look at animateMotion and foreignObject.
However, this might not be the ideal and most widely supported solution in your situation. Why not use the "traditional" JavaScript way, animating the style attribute? As long as your path is restricted to simple straight line segments, this should not be too hard.

best/shortest way to draw 1px grid in SVG

I need to draw a 1px grid (10px spacing) using the SVG canvas embedded within a webpage. There are many SVG tags to choose from and I was hoping someone could suggest what tags would be best suited for the job and produce the least amount of code.
For instance, is there a shorter alternative to plotting the path using the <path> tag? Perhaps by defining a square 10px x 10px then somehow repeating it accross the canvas.
Anyway, open to suggestions please.
Thanks
You can make a <pattern> (essentially the tile in your question) and fill any shape with that.
Here's an example of that technique.
I'm not an expert (day 3!), but I do know that Google uses rects to do this on Google charts, with either a width or a height equal to 1. Nothing fancy, just write the grid with lots of stuff like this:
<rect x="86" y="61" width="1" height="198" stroke="none" stroke-width="0" fill-opacity="1" stroke-opacity="1" stroke-dasharray="0" fill="#cccccc"></rect>
Why do they do this? Don't know. Their graphics are good, so someone has presumably thought about it. My own inclination is to do this with paths, using 'h' and 'v' for relative horizontal and vertical lines. It's more compact, but the output may not be so good.

Can I use mixed units with 'path' element?

SVG has a rectangle element which dimensions could be specified in percent of dimensions of its owner and radius in pixels. So by doing the following
<div style="position: relative;">
<object class="AIRound" type="image/svg+xml"
data="data:image/svg+xml,<svg
xmlns='http://www.w3.org/2000/svg'><rect x='0' y='0' width='100%'
height='100%' rx='10px' ry='10px' fill='#99ff99'
opacity='0.9'/></svg>" style="position:absolute; left:0px; top:0px;
width:100%; height:100%; z-index:-100;"></object>
Sample text<br>Sample text
Sample text<br>Sample text
</div>
I can get a with rounded corners with the constant radius which doesn't depends on the block size. But a simple rectangle with rounded corners it's boring and sometimes you want something fancy (e. g. http://my.opera.com/). I've tried to use 'path' element but it seems to me we can't use mixed units with 'path' (pixels & percents). I can't use a combination of shapes either because it won't work semitransparents and gradient fill.
So my qeustion is can I use 'path' element with mixed units? Maybe there's another work around which I overlooked?
Paths and point-lists can only be specified in user units. By having a container (e.g an svg or symbol element) that specifies a new coordinate system with 'viewBox' it's possible to affect what the user units resolve to. That still doesn't solve all cases.
To fix a few more cases you can build the image using multiple shapes each with a different clip-path to clip away the parts that are undesirable. You can have a look at the Rounded Corner Generator SVG output for an example of that approach.
Unfortunately, path coordinates can only be expressed with a single unit, Viewport Coordinates.
There is a workaround:
<svg width='100%' height='100%' viewBox='0 0 100 100'>
<!-- Now in here, a coordinate (25,50) corresponds to
(25%,50%) of the outer viewport. -->
<path d="M36,96 C 54,100 94,73 97,61 ..."/>
</svg>
Ref:
http://mozilla.6506.n7.nabble.com/Specyfing-paths-with-percentages-unit-td247474.html