Inline svg showing black in safari but works perfectly on chrome - javascript

I am trying to use a inline svg above a canvas element as grid. The problem is that svg grid is showing black in safari while it works fine on chrome. I have tried actual url for fill, tried viewbox but nothing is working. I have tested by using object tag but the problem with that I doesn't catch my right click events which I need above the svg grid. Here is my code
<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="grid10" width="10" height="10" patternUnits="userSpaceOnUse">
<path
d="M 10 0 L 0 0 0 10"
fill="none"
stroke="gray"
stroke-width="0.5"
/>
</pattern>
<pattern
id="grid100"
width="100"
height="100"
patternUnits="userSpaceOnUse"
>
<rect width="100" height="100" fill="url(#grid10)" />
<path
d="M 100 0 L 0 0 0 100"
fill="none"
stroke="gray"
stroke-width="1"
/>
</pattern>
</defs>
<rect width="100%" height="100%" fill="url(#grid100)" />
</svg>

I have the same issue on our project. Generally it's an issue with url referencing. In Angular 8 it's caused by <base href="/">. The simplest solution is to use <img src="image-path/your-image.svg"> instead of the inline svg. Another possible solution is to read the current url with window href or define it absolutely.

Related

How to know if the user's face/boundry box is within an ellipse in a canvas

I'm working on application the make checks for a user in front of camera, I used the FaceApi to detect the face and draw a bounding box arround it. I want to make sure that face/bounding box is within an ellipse(an svg). Basically, I think I will compute the intersection between the bounding box and the ellipse. And let the check passes only if the intersection is above a predefined threshold(say 0.5, the half part of the face is within the ellipse).
<svg
width="100%"
height="100%"
className="svg"
viewBox="0 0 260 200"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink">
<defs>
<mask id="overlay-mask" x="0" y="0" width="100%" height="100%">
<rect x="0" y="0" width="100%" height="100%" fill="#fff"/>
<ellipse id="ellipse-mask" cx="50%" cy="45%" rx="60" ry="85" />
</mask>
</defs>
<rect x="0" y="0" width="100%" height="100%" mask="url(#overlay-mask)" fillOpacity="0.7"/>
</svg>
is there any way to compute/know the area of the ellipse to use it to compute the intersection with the bounding box arround the face detected with Javascript ?
Any help of advice will be appreciated. Thank you.

How can I apply a pattern to an SVG element that ignores the element's transform values?

I have a JavaScript application that modifies an inline SVG. I have multiple elements within the SVG that all need to have the same background image applied to them. Elements (paths) are positioned in the SVG via transform attributes. Presently I am using a pattern fill on the elements. Is there any way to achieve the effect of the pattern staying stationary irrespective to element transforms?
Currently I have this:
I want this:
(note: I hard-baked the path in the second photo, which can't be used in the application)
Edit:
The patterns are currently applied like so:
<defs>
<pattern id="metallicgold" x="0" y="0" width="1240" height="775" patternUnits="userSpaceOnUse">
<image xlink:href="img/gold-texture.png" />
</pattern>
</defs>
The transforms on elements look like this:
<path transform="translate(-445.0000396775016 -1950.3326958481455) rotate(317.2309439443859 2926.326416015625 2926.32666015625) scale(1 1)" style="fill: url('#metallicgold'); stroke: none;" d="M1951.326416015625,1951.32666015625L3901.326416015625,1951.32666015625L3901.326416015625,3901.32666015625L1951.326416015625,3901.32666015625L1951.326416015625,1951.32666015625Z" x="0" y="0"></path>
If you want a constant background as you transform shapes, you should consider using a filter with userSpaceOnUse filterUnits, unless the transforms are easy and apply to all elements filled, in which case, you can use patternTransform on the pattern to reverse the transform on the elements.
<svg width="800px" height="600px" viewBox="0 0 4000 4000">
<defs>
<filter id="brick" x="0" y="0" width="4000" height="4000" filterUnits="userSpaceOnUse">
<feImage xlink:href="https://s-media-cache-ak0.pinimg.com/originals/c9/97/81/c99781a0ab356681cb038f70b1df68f1.jpg" x="0" y="0" width="4000" height="4000" preserveAspectRatio="xMinYMin meet"/>
<feComposite operator="in" in2="SourceGraphic"/>
</filter>
</defs>
<g filter="url(#brick)">
<path transform="translate(-445.00 -1950.33) rotate(317.23 2926.32 2926.32) scale(1 1)" stroke="none" fill="red" d="M1951.326416015625,1951.32666015625L3901.326416015625,1951.32666015625L3901.326416015625,3901.32666015625L1951.326416015625,3901.32666015625L1951.326416015625,1951.32666015625Z" x="0" y="0"></path>
</g>
<rect x="1250" y="500" width="300" height="300" fill="blue"/>
<g filter="url(#brick)">
<circle cx="1000" cy="1000" r="500"/>
</g>
</svg>

Multiple javascript animation of masks of a svg

I am trying to animate the radius of the circle #mask-hole-2 with javascript. So that it animates the radius from 0 to 175px. But i dont know how to do this in a common way. I cant use css cause there seems to be another specification used on firefox for animating masks with css.
<svg width="400" height="300">
<defs>
<mask id="hole">
<circle id="mask-hole-1" cx="165" cy="156.5" r="165" fill="white" />
<rect id="mask-hole-3" width="100%" height="100%" fill="white"/>
<circle id="mask-hole-2" cx="165" cy="156.5" r="145" />
</mask>
</defs>
<image width="400" height="300"
xlink:href="http://lorempixel.com/400/300/sports/"
mask="url(#hole)"/>
</svg>
I want #mask-hole-1 to change its radius within 2 seconds from 0 to 175. After 2s #mask-hole-2 should change its radius from 0 to 175 also.
Would be nice if the animation works smooth. Any help is appreciated.

SVG Grid lines are Blurred in Google Chrome while zooming but its work fine in Mozilla firefox

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1300" height="900" viewBox="0 0 750 300" id="mainsvg">
<g>
<defs>
<pattern x="0" y="0" width="1.6" id="smallGrid" height="1.6" patternUnits="userSpaceOnUse">
<path d="M 10 0 L 0 0 0 10" id="smallgridbox" fill="none" stroke="rgb(8,24,77)" stroke-width="1"></path>
</pattern>
<pattern width="16" id="grid" height="16" patternUnits="userSpaceOnUse" x="687.47" y="0" shape-rendering="geometricPrecision">
<rect fill="url(#smallGrid)" width="16" height="16" fill-opacity="0.5"></rect>
<path d="M 100 0 L 0 0 0 100" id="largegridbox" fill="none" stroke="rgb(8,24,77)" stroke-width="1"></path>
</pattern>
</defs>
<rect fill="url(#grid)" width="1375" height="773" x="0" y="0" fill-opacity="0.5"></rect>
</g>
</svg>
Here is the JS Fiddle: http://jsfiddle.net/KashifMKH/L46j18fo/6/
It works fine in Mozilla Firefox, but not in Chrome. Zoom it at large and then compare the results in Mozilla and Chrome: you will see the difference clearly. How can I fix it?
I played around with your fiddle in chromium. That the gridlines become blurry if one zoomes in, appears also to me.
So I »manually« changed the viewBox in the html code so that the svg is scaled initially. Fiddle
Result: No blurry Gridlines.
So I think it is quiet obvious that chrom - e/ium does not rerender the pattern if the viewBox changes. You could try to update the viewBox by using the direct DOM-Binding:
var vb = a.viewBox.baseVal;
vb.x = ...
vb.y = ...
If that does not work I would try to use transforms and if that does not work, I think you cannot use <pattern> to create the grid and <use> elements, created by Javascript are the next option.

Is it possible to extend the height and width of a child element beyond its container?

I have a zoomable svg that's provided by 3rd a party API. It's basically a drawing that's mapped to a grid. The problem is the API doesn't include the grid in the provided svg file so I have to hack it to include one. Basically, the markup is like this:
<svg>
<g>
<line>....
<rect>....
etc...
</g>
</svg>
The zoom functionality is done and now I'd like to add the grid. I'm thinking I should add it like so:
<svg>
<g>
<rect x="0" y="0" width="100%" height="100%" fill="black" />
<defs>
<pattern id="grid" width="20" height="20" patternUnits="userSpaceOnUse">
<path d="M 1 1 L 0 0 0 0" fill="none" stroke="green" stroke-width="1" />
</pattern>
</defs>
<rect x="-100%" y="-100%" width="200%" height="200%" fill="url(#grid)" />
<line>....
<rect>....
etc...
</g>
</svg>
The grid is drawn but it's bound within the <g> tag. Is it possible to extend the grid beyond it but still zoomable? Or are there other better ways to achieve this?

Categories