image inside svg width and height not working as expected - html

I am try to make image gray-scale work on IE 10, after some search use svg can archive it, but now I meet another problem, here is the code make image gray-scale work on IE 10
<svg xmlns="http://www.w3.org/2000/svg" id="svgroot" viewBox="0 0 400 377" width="400" height="377">
<defs>
<filter id="filtersPicture">
<feComposite result="inputTo_38" in="SourceGraphic" in2="SourceGraphic" operator="arithmetic" k1="0" k2="1" k3="0" k4="0" />
<feColorMatrix id="filter_38" type="saturate" values="0" data-filterid="38" />
</filter>
</defs>
<image filter="url("#filtersPicture")" x="0" y="0" width="400" height="377" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://thecybershadow.net/misc/stackoverflow.png" />
</svg>
the problem is the image not scale by size I give, for example, if the image's size is 200 X 1000 and I give the size 200 X 500, it will scale the image to something like 100 X 500
I tried preserveAspectRatio http://www.w3.org/TR/SVG/coords.html#PreserveAspectRatioAttribute seem not work
so my question is how to make the image resize to the size I given?
thanks in advance

If you want the image to stretch to fill the width and height you specify exactly (horizontally and vertically), use preserveAspectRatio="none".
<image x="0" y="0" width="400" height="377" xlink:href="blah" preserveAspectRatio="none" />

not find the absolute solution but this work around fit our needs
use preserveAspectRatio can make image almost fit the size I give and beyond part will be croped, so is I can let image's proportion similar to the size I given, it will be fine
<image preserveAspectRatio="xMidYMid slice" filter="url("#filtersPicture")" x="0" y="0" width="400" height="377" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://192.168.0.10:3000/uploads/photo/609/address/a219c3c5eb8fdce852a61385ae31bc7ee270fc73.jpg" />

Related

SVG images not rendering in Safari

<svg id="button-svg" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 40 40" xml:space="preserve">
<defs>
<pattern id="pattern1" height="100%" width="100%">
<filter id="shadow">
<feDropShadow dx="0" dy="0" stdDeviation="2.2" />
</filter>
<rect height="100%" width="100%" fill=${backgroundColor}></rect>
<image id="image" xlink:href=${backgroundImage}></image>
</pattern>
</defs>
<circle id="circle" cx="20" cy="20" r="20" filter="url(#shadow)" fill="url(#pattern1)"/>
</svg>
I have tried multiple solutions from stackoverflow but none seem to work. Can anybody please help me on this?
Note: both filter and the fill color are showing. It’s only the image that’s missing.
Demo: https://codesandbox.io/s/svg-safari-image-t9ng3?file=/src/index.js
Edit: Thank's to Robert Longson's answer I found out that you need to set the height and width explicitly in the image tags 'height/width' attribute for the image to show in Safari. Now I have another problem if the height/width is supposed to be 'auto', removing the attribute from the image tag works in Chrome but the image again disappears in Safari. Is there any fix for this?
Safari needs the image to have height and width values.
Using the image's native width and height i.e. a default value of auto is a change in the new SVG 2 specification. Firefox and Chrome have implemented this and I imagine Safari will too at some point.

Svg does not scale

I have an svg file and use it in my HTML code. For some reason, it does not scale. What I mean by that is that I can only change the width and height of the image ( so it just becomes a larger box taking more space, but the vector image inside that box does not scale ). In the svg file I have viewbox attribute, but when I change its values, it still does not scale (actually it does not do anything). Any ideas?
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="50px"
height="50px"
viewbox="0 0 64 64">
<defs>
<filter id="blur" width="200%" height="200%">
<feGaussianBlur in="SourceAlpha" stdDeviation="3"/>
<feOffset dx="0" dy="4" result="offsetblur"/>
<feComponentTransfer>
<feFuncA type="linear" slope="0.05"/>
</feComponentTransfer>
<feMerge>
<feMergeNode/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
<style type="text/css"><![CDATA[ .... ( data is here )
HTML:
<img id="icon">
( I specify the img src in a separate js file )
As #Robert Longson comment mentions viewBox not viewbox. SVG is case sensitive
Methods To Resize SVG:
1st
Use the this code:
<g transform="scale(0.1)">
...
</g>
2nd
The viewbox should describe the full width and height of the SVG.
The viewbox should go like this 0 0 widt height
<svg preserveAspectRatio="xMidYMid meet" viewBox="0 0 700 550"></svg>
3rd
you can resize it by screening svg in image tag and give size in attribute form.
<img width="200px" src="yoursvg.svg"></img>

SVG symbol currently not displaying in chrome

I've been having problems with symbols in SVG files. They are currently not displaying in browsers.
For example I created this basic SVG file in inkscape to show the problem:
<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="100" width="100" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100" xmlns:dc="http://purl.org/dc/elements/1.1/">
<defs>
<symbol id="circle">
<circle style="color-rendering:auto;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;image-rendering:auto" stroke-width="3.257" stroke="#008000" cy="1000.1" cx="34.598" r="12.879"/>
</symbol>
</defs>
<g transform="translate(0 -952.36)">
<use xlink:href="#circle"/>
</g>
</svg>
And it should look like this:
But for some reason its not displaying as such in chrome, does anyone know why?
You're drawing the initial symbol mostly outside the viewbox - your viewBox is 100 x 100, but your cy is 100.1. This seems to disable drawing completely, so when you bring it back into the viewbox with the translate, there's nothing there. Adjust your cy so you're drawing inside the viewbox and reduce your translate to compensate.

How can I make a responsive parallelogram in SVG keep it's angles?

Let's start with the end-result I'm trying to achieve:
Where the length and height of the parallelogram can change independently of each other, but where the angle of the sides do not change.
With that out of the way, let's talk about why and what I've already done.
I'm fairly inexperienced with SVG, but I already know that CSS isn't enough to do what I want to do, which is to make responsive buttons that look like the above image - except that sometimes the left or right side is straight.
Initially, for those, I designed a massively wide SVG that could be used as a background and then scaled up and aligned to the left or right (as a background) so that the excess gets cut off but so that the aspect ratio does not change. For some reason that I haven't spent any time debugging, that does not work as designed.
Then, I learned a little bit more about SVG and learned about preserveAspectRatio. I used this nifty feature to make SVGs that themselves were responsive:
<?xml version="1.0" encoding="utf-8"?>
<svg id="main-box" viewBox="0 0 200 50" preserveAspectRatio="xMinYMin slice" xmlns="http://www.w3.org/2000/svg">
<rect x="22" height="50" width="178" style="fill:green;">
</rect>
<svg id="left-corner" viewBox="0 0 27 50" preserveAspectRatio="xMinYMin meet">
<polygon points="22,0 27,0 27,50 0,50" style="fill:green;"/>
</svg>
</svg>
and
<?xml version="1.0" encoding="utf-8"?>
<svg id="main-box" viewBox="0 0 200 50" preserveAspectRatio="xMaxYMin slice" xmlns="http://www.w3.org/2000/svg">
<rect height="50" width="178" style="fill:green;">
</rect>
<svg id="right-corner" viewBox="0 0 27 50" preserveAspectRatio="xMaxYMin meet">
<polygon points="0,0 27,0 5,50 0,50" style="fill:green;"/>
</svg>
</svg>
These two very easily maintain the aspect ratio of the triangle making up the side (meet) while forcing the rectangle to expand to fill the remaining space. Perfect! It does this using xMaxYMin when the triangle is on the right and xMinYMin when the triangle is on the left.
However, and fairly obviously, this approach doesn't work when you want one on the left AND one on the right!
My first attempt was a fairly silly trial of xMidYMin, which put the viewport on the center of the rectangle, but as the height expanded the edges went further outward and the triangles never showed themselves - instead rendering one gigantic rectangle!
My next attempt was very close, by removing the rectangle I achieve nearly my desired effect!
<?xml version="1.0" encoding="utf-8"?>
<svg id="main-box" viewBox="0 0 50 50" preserveAspectRatio="xMinYMin slice" xmlns="http://www.w3.org/2000/svg">
<svg id="left-corner" viewBox="0 0 27 50" preserveAspectRatio="xMinYMin meet">
<polygon points="22,0 27,0 27,50 0,50" style="fill:green;"/>
</svg>
<svg id="right-corner" viewBox="0 0 27 50" preserveAspectRatio="xMaxYMin meet">
<polygon points="0,0 27,0 5,50 0,50" style="fill:green;"/>
</svg>
</svg>
The problem here though, is that while it does expand up and down, the longer it gets the more it indents from the end!
I've also tried embedding both the start and end cuts as separate SVG into one SVG with a width of 50% (one on each side) but the embedded SVGs are stretched instead of resized when preserveAspectRatio is off for the main image, and it doesn't expand to fill space the way I need it when it's on.
<?xml version="1.0" encoding="utf-8"?>
<svg id="main-box" viewBox="0 0 200 50" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none">
<svg id="start-cut" viewBox="0 0 200 50" width="50%" height="100%" preserveAspectRatio="xMinYMin slice" xmlns="http://www.w3.org/2000/svg">
<rect x="22" height="50" width="178" style="fill:green;">
</rect>
<svg id="left-corner" viewBox="0 0 27 50" preserveAspectRatio="xMinYMin meet">
<polygon points="22,0 27,0 27,50 0,50" style="fill:green;"/>
</svg>
</svg>
<svg id="end-cut" viewBox="0 0 200 50" width="50%" x="50%" preserveAspectRatio="xMaxYMin slice" xmlns="http://www.w3.org/2000/svg">
<rect height="50" width="178" style="fill:green;">
</rect>
<svg id="right-corner" viewBox="0 0 27 50" preserveAspectRatio="xMaxYMin meet">
<polygon points="0,0 27,0 5,50 0,50" style="fill:green;"/>
</svg>
</svg>
</svg>
What can I do to keep both the left and right corners in their proper place, with their proper angle (so they must keep their aspect ratio) while the middle expands (does not need to keep it's aspect ratio)?
Here's code for a responsive SVG parallelogram:
<svg id="main-box" viewBox="0 0 2000 500" preserveAspectRatio="none"
xmlns="http://www.w3.org/2000/svg">
<style>
rect {
fill:black;
}
</style>
<rect x="190" y="0" width="90%" height="100%" transform="skewX(-20)" />
</svg>
Note the use of the skewX transform and the rect and width values to give the SVG its shape. It works fine. However, the only issue I had was when trying to use this as a background image on the body tag. There was an issue with incorrect sizing in Firefox. Researching the issue, it seems to be caused by different interpretations of the spec, rather than an unintentional bug.
You can see the use of this parallelogram on a side project I created: https://thisisa.lockdownchemz.link/
I'm not sure I understand what you want to achieve. Is it something like this :
<svg id="main-box" viewBox="0 0 100 40" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
<polygon points="0,0 73,0 100,40 27,40" />
</svg>

How to render svg elements with crisp edges while still keeping anti-aliasing?

Is there a way to render svg elements with crisp edges while still keeping anti-aliasing?
I'm creating a browser-based tool that works in modern browsers.
Playing around with the shape-rendering attribute doesn't give me the results I'm looking for.
I want my elements to have nice anti-aliasing so that the paths look smooth like below with shape-rendering: auto:
But I also want elements that don't require anti-aliasing, like the start box to look sharp and crisp, such as when rendered with shape-rendering: crispEdges:
Is this possible? Am I looking to have my cake and eat it too?
Perhaps you set shape-rendering property for root svg element.
You should set shape-rendering property for each shape elements, like this.
<?xml version="1.0" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<rect x="10" y="10" width="150" height="20" shape-rendering="crispEdges"
fill="none" stroke="black"/>
<path d="M80,30l100,100" shape-rendering="optimizeQuality"
stroke="black" stroke-width="5"/>
</svg>
If you want your boxes to appear sharp without any blurring due to antialiasing, and without using crispEdges mode, make sure the line edges are on pixel boundaries. So, for example, if your lines are an odd number of pixels wide, give them coordinates that are at 0.5 of a pixel.
<rect x="10.5" y="10.5" width="150" height="20"
stroke-width="1px" fill="none" stroke="black"/>
And on the boundary if the stroke width is even.
<rect x="10" y="10" width="150" height="20"
stroke-width="2px" fill="none" stroke="black"/>
Of course, this only really works if your SVG is being rendered at 1:1. That is, it's not being rescaled by the browser. And only for lines that are horizontal and vertical.
[I'm posting this as an answer rather than a comment, because I want to post a picture. Otherwise, this is a comment on the useful post by #defghi1977 . +1 to him, by the way.]
<?xml version="1.0" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<rect x="10" y="10" width="150" height="20" shape-rendering="crispEdges"
fill="none" stroke="black" />
<rect x="10" y="50" width="150" height="20" shape-rendering="auto"
fill="none" stroke="black" />
<path d="M40,30l100,100" shape-rendering="crispEdges"
stroke="black" stroke-width="5" />
<path d="M80,30l100,100" shape-rendering="auto"
stroke="black" stroke-width="5" />
</svg>
Produced
This was rendered by Firefox 38.0.5 .
In Internet Explorer 11, both shape-rendering setting produces the same result with anti-aliasing and not crisp.