Rollover overlays with SVG - svg

i want to acheive the effect on this page using SVG. As you can see it uses a series of PNG transparent overlays when the user mouses over a polygonal hotspot drawn on a product.
What i want to achieve is the same thing with SVG, but without messing about with creating a load of PNGs, so that when the user mouses over an area the transparent shape (with link on it) appears over the top. The SVG shape would be built from a set of coordinates exactly as a polygonal hotspot would on an image map.
So i guess my first question is, can this be done with plain old SVG or do i need to use something like Raphael to achieve this? Never seen this effect before with SVG so if anyone has an example like that would be very useful.
Thanks in advance.

There are several ways to get this effect with plain old SVG. Probably the simplest is to use CSS within the SVG. For example:
<style>
.overlay:hover
{
opacity: 0.5;
}
</style>
<svg>
<a xlink:href="http://www.wherever/you/want/to/link/to.com">
<path class="overlay" d="Coordinates of your shape..." />
</a>
</svg>
I've written about various other methods at:
http://www.petercollingridge.co.uk/data-visualisation/mouseover-effects-svgs

Yes it can be done with SVG only, with or without javascript.
One way to get the effect would be to overlay a white semi-transparent path on top of the image that you want to whiten. Another way would be to use an SVG filter to process the image directly, similar to what I've done here or here to recolor a PNG (view page source and feel free to reuse that in any way you like).
You'll want to make use of the 'pointer-events' property most likely. Here's an example showing how to detect mouse-events on the fill and/or stroke of an svg shape, even if the shape is invisible.

Related

How can I place a geo-referenced SVG over an openlayers map (not as image)

How can I place a complex SVG image (with css-styles!) geo-referenced over an openlayers map so that the document's CSS styles are used with rendering the SVG.
A regular ImageLayer does a fine job of showing the georeferenced svg on the map as an image. But because it is an image, the CSS of the document has no effect on the rendered SVG
The SVG Layer example on the other hand places the SVG into the DOM and makes it react to the document's CSS and reacts when you change the CSS. But it always maps the SVG over the whole planet and seems to hide any layer I place under it.
To give you an idea of the use case: we have an externally generated SVG with several 'groups or layers' in it representing different aspects of infrastructure. This svg has to be put correctly over a map (like we can do with the imagelayer), but we want to be able to selectively show/hide the different 'groups or layers' that are within the SVG.
I guess in the end we would be needing something similar to ol/layer/Image/ImageLayer to happen in the SVG-layer example.
Any suggestions about how to approach this would be very welcome, but working code is also OK ;-)
In the example the image width is 360 degrees and the center is at [0, 0]. For a smaller extent you would need to use the appropriate width and adjust the center used in the transform https://codesandbox.io/s/lucid-poitras-i1qyb?file=/main.js Use an opacity setting to avoid completely hiding the base layer.

cairo + librsvg: draw svg icons forcing the colour at runtime

I'm using a set of svg icons in my applications, and I'm painting them using librsvg. These icons are all single-colour black drawings, and I can only draw them black because that is the colour written in the svg file.
There is a way I can to choose, at runtime, the colour (and possibily the alpha channel) of the icon just before painting them, without making a dedicated svg file for any colour I need? Can I make librsvg to ignore the colours written in the svg file and use only the one of my choice? Or any other workaround to have the same effect?
I'm thinking about loading the svg file content and modify in-memory the colour declarations, it should work, but I'm looking for a cleaner way.
Thanks.
You may want to monitor https://gitlab.gnome.org/GNOME/librsvg/issues/379 for a clean way to do this. In summary, librsvg needs an API to let you pass in an extra CSS stylesheet; this way your shapes can obtain their colors from that CSS.
https://gitlab.gnome.org/GNOME/gtk/issues/1471 mentions the way in which GTK hacks around this, and you may be able to use something similar. In short, it creates a wrapper SVG like this:
<svg ...>
<style type="text/css">
... extra styling here ...
</style>
<xi:include href="... original SVG encoded as a data:URL ..."/>
</svg>
(but check the actual source code in the comments there for the correct syntax!)

Is there a way I can modify my page background color to show as random shades with svg?

I have a black #000 page background on my web page.
Is there a way that I can change this with SVG to show a random effect of small #111 and #222 colored squares. I was told I could do this with SVG but I don't have any idea where to start. Even a really simple example would be a great help.
I'm looking for a solution for IE9+ browsers.
SVGs can be used as background images they same way that a PNG or JPG can. Create an SVG with any suitable editor - such as Inkscape - and include it the way you normally would.
background-image: url(../images/mybackground.svg);

Issue with SVG display / rendering in Fabric.js

I'm using FabricJS and I encounter a problem with the display of my SVG in the canvas:
the result is displayed outside the selection box of fabricJS (due to a translation ?)
the anchors of the selection disappear after a transformation and then it's impossible to find them back.
Here is a screenshot :
I'm using an output SVG of Potrace and I think it's the origin of my issue.
Here is the code of the SVG: SVG code in pastebin
You can test it with FabricJS on this page: FabricJS Kitchensing example.
Just paste the code of the SVG in the "Load SVG" area, then resize and rotate the section box to display the SVG.
Do you know the part of my SVG code or the part of the fabricjS code that causes the issue ?
If so, can I change it easily by myself ? If not, is it possible for anybody to correct or locate the possible mistake?
Thank you very much for your help.
EDIT: seemingly, FabricJS doesn't like this line of the SVG:
<g transform="translate(0,648) scale(0.098780,-0.098780)" fill="#000000" stroke="none">
And more especially the translate and scale attributes… How to fix it?
EDIT2: the solution would be that the translate and the scale are respectively equal to (0,0) and (1,1) or, better, that they're applied to the coordinates.
Does anybody have an idea to do that with Potrace or JS script?
2 years after, fabricJs is now able to fully parse and manage this SVG.
Just paste the old pasteBin SVG code in the kitchenSink demo and you will see that it loads fine.
Lots of improvement happened recently in the SVG parsing area.
I know this is not an answer as stackoverflow user would expect, but better to know that to think this is may still be a problem.

How to properly display multiline text in SVG 1.1?

I would like to take a multiline block of text and display it in SVG. I would like to keep the lines as lines. Is there a proper way to do this?
I am using Inkscape for my base drawing and Batik for my rendering. It seems the two do not agree on how to do this.
Inkscape is creating a structure like this:
<flowRoot
xml:space="preserve"
id="flowRoot3089"
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
transform="translate(19.71875,334.88681)">
<flowRegion id="flowRegion3091">
<rect id="rect3093" width="50.78125" height="75" x="34.765625" y="155.89932"/>
</flowRegion>
<flowPara id="flowPara3123">Item 1</flowPara>
<flowPara id="flowPara3137">Item 2</flowPara>
<flowPara id="flowPara3139">Item 3</flowPara>
</flowRoot>
However, this is not acceptable to Batik for some reason.
Inkscape sets the SVG version of the document to 1.1 instead of 1.2, but still uses flowing text.
The simple solution for you is to edit your svg document and change the SVG version attribute to 1.2. Inkscape will not change it back to 1.1 and it handles the 1.2 version specifier fine.
Batik will then be happy to provide most functionality, however you'll also run into another Inkscape bug if you mess with pretty much any of the text attributes within the flow root that Inkscape creates. It sets the background color to the selected foreground color for the text, which means if you set the text color to red in Inkscape, when batik renders it, you'll see a red square ... the text is there, but its red too, so not really visible. This an Inkscape bug and is clearly visible in the code for the flowRegion -> rect element.
The solution is to manually edit your flowRect attributes after tweaking them with inkscape.
Batik also seems to do better if you use the standard svg output rather than inkscape svg output.
This is not acceptable since flow* elements are non-standard elements. It comes from an SVG1.2 draft that has never been accepted and it is designed to wrap text in custom shapes. Only Inkscape and some builds of Opera support it. So, don't use it, at least for the moment.
If you don't need text wrapping (and you don't seem to, but I don't understand what you mean by "I would like to keep the lines as lines"), I suggest you use the basic <text/> element.
I'd suggest <text> with <tspan> children. Inkscape can generate that for you quite easily, just don't click and drag an area but instead just click where you want the text and start writing, press return where you want a new line.
Alternatively, foreignObject will allow you to include html:
<svg:foreignObject><html:body><div>text here</html:div></html:body></svg:foreignObject>
Doesn't seem to work in Opera or IE, though.

Resources