SVG tooltip on background element - svg

I need to display a tooltip message (defined with tag) over a rect element that's partially overlapped by above another (transparent) rect:
https://jsfiddle.net/nkeLcxga/1/
<svg width="300" height="300">
<rect x="100" y="100" width="100" height="100" stroke="black" fill="green">
<title>I'm a tootip</title>
</rect>
<rect x="150" y="150" width="150" height="150" stroke="red" stroke-width="3" fill="transparent"></rect>
</svg>
Is there a way to display tooltip on mouseover event even on lower-right green corner although it is overlapped by another element?

Setting fill="none" almost fixes it and you shouldn't ever use fill="transparent".
To prevent the tooltip from being absent when the mouse is over the thin red line I've added pointer-events="none" too.
<svg width="300" height="300">
<rect x="100" y="100" width="100" height="100" stroke="black" fill="green">
<title>I'm a tootip</title>
</rect>
<rect x="150" y="150" width="150" height="150" stroke="red" stroke-width="3" fill="none" peointer-events="none"></rect>
</svg>

Related

SVG element with clippath prevents events on underlying element

Edit: Maybe I need to test my assumption...
Is there a way to render svg so an element underlying another element can receive events?
The red circle does not respond to its hover event where it is under the clipped circle.
The rectangle iindicates the masked and clipped area of the green circle.
I want the visible red and green areas to both receive pointer events.
How would I get the whole red circle to respond - It has to underly the green circle.
Fiddle
<svg id="svg_wrp" width="600" height="600" style='z-index:2'>
<defs>
<mask id="green_mask">
<circle cx="300" cy="300" r="200" fill="#fff"></circle>
<rect x="100" y="50" width="400" height="200" fill="#000"></rect>
</mask>
<clipPath id="green_clip">
<rect x="100" y="50" width="400" height="200" fill='#000'></rect>
</clipPath>
</defs>
<!-- Following for reference only -->
<rect x="100" y="50" width="400" height="200" stroke="#080" fill="none"></rect>
<circle cx="300" cy="300" r="200" fill="rgba(0 0 255 /.2)" stroke="#080"></circle>
<!-- Above for reference only -->
<g>
<circle cx="300" cy="50" r="100" fill="rgba(255 0 0 /1)" class="hover_it" ></circle>
<!-- Following circle will have top part hidden, but mask does not prevent events -->
<circle id="green_hide_area"
cx="300" cy="300" r="200" fill="rgba(0 255 0 /1)" class="hover_it" mask="url(#green_mask)" ></circle>
</g>
<g>
<!-- Following circle will prevent events -->
<circle id="green_event_stop"
cx="300" cy="300" r="200" fill="transparent" clip-path="url(#green_clip)" ></circle>
</g>
</svg>
.hover_it{opacity:.5}
.hover_it:hover{opacity:1}

How to mask a portion of a stroked path in SVG?

I'm looking to mask a portion of a straight line in SVG and can really only figure out how to do it one way, but would rather do another because the line lengths will be dynamically generated and the mask portion won't.
Let me explain.
Assume I have a line that is <path d="M0,0 L0,100" stroke="blue" stroke-width="20"/>, I would like to mask with transparency the first 10 pixels, meaning just the d="M0,0 L0,10" portion.
I can do this, which produces the results I'd like:
<svg width="100" height="100">
<rect stroke="black" stroke-width="2" width="100" height="100" fill="yellow"/>
<svg x="10" y="0" width="200" height="200" >
<defs>
<rect x="0" y="0" width="20" height="10" stroke="none"/>
<mask id="chopmask" maskUnits="userSpaceOnUse">
<rect width="20" height="90" x="0" y="10" fill="white"/>
</mask>
</defs>
<path d="M0,0 L0,100" mask="url(#chopmask)" stroke="blue" stroke-width="20"/>
</svg>
</svg>
But the issue is that I can't seem to do the opposite with the rect in the mask, wherein I simply define the it as <rect width="20" height="10" x="0" y="0" fill="white"/> (notice only height and y are different).
Am I missing something on how do define a 10x20 rectangle and have it's mask simply hide a portion of a stroked path, or is this impossible?
If I understood the question correctly, then you need to have a mask in the form of a rectangle of fixed size 10Х20, which will be applied to the line with variable length.
In this case, you can try on a combined mask, one part of which will be opaque fill = "black" and the second part will be transparent fill = "white" and show the rest of the line.
<svg width="100" height="100">
<rect stroke="black" stroke-width="2" width="100" height="100" fill="yellow"/>
<svg x="10" y="0" width="200" height="200" >
<defs>
<mask id="chopmask" maskUnits="userSpaceOnUse">
<rect width="20" height="100" x="0" y="0" fill="white"/>
<rect width="20" height="10" x="0" y="0" fill="black"/>
</mask>
</defs>
<path d="M0,0 L0,100" mask="url(#chopmask)" stroke="blue" stroke-width="20"/>
</svg>
</svg>
An example of animating the line masking process with a rectangle 10 x 20px
<svg width="100" height="100">
<rect stroke="black" stroke-width="2" width="100" height="100" fill="yellow"/>
<svg x="10" y="0" width="200" height="200" >
<defs>
<rect x="0" y="0" width="20" height="10" stroke="none"/>
<mask id="chopmask" maskUnits="userSpaceOnUse">
<rect width="20" height="100" x="0" y="0" fill="white"/>
<rect width="20" height="10" x="0" y="0" fill="black">
<animate attributeName="y" dur="2s" values="-10;0" fill="freeze" />
</rect>
</mask>
</defs>
<path d="M0,0 L0,100" mask="url(#chopmask)" stroke="blue" stroke-width="20"/>
</svg>
</svg>
Works for me ... am I misunderstanding what you're trying to do?
<svg width="100" height="100">
<rect stroke="black" stroke-width="2" width="100" height="100" fill="yellow"/>
<svg x="10" y="0" width="200" height="200" >
<defs>
<rect x="0" y="0" width="20" height="10" stroke="none"/>
<mask id="chopmask" maskUnits="userSpaceOnUse">
<rect width="20" height="10" x="0" y="0" fill="white"/>
</mask>
</defs>
<path d="M0,0 L0,100" mask="url(#chopmask)" stroke="blue" stroke-width="20"/>
</svg>
</svg>

SVG how to set max width for group

I have some SVG elements grouped together in a <g> element (exactly the barcode 1D, PHP generates a barcode).
<g
style="fill:#000000;stroke:none"
id="barcode1D"
transform="matrix(1.2083333,0,0,0.8247805,62.027778,573.54235)">
<rect
x="0"
y="0"
width="4"
height="30"
id="xyz" />
....
<rect
x="224"
y="0"
width="0"
height="30"
id="xyzn" /> </g>
The barcode is generated in various widths, lengths. How can I set the width permanently ?
Based on this example, I am asking for a hint. Thank you for your help in advance.
SVG g element does not have width and height attributes. Therefore, you can not set height and width on it.
You should use a foreignObject with a svg inside of it to do so.
<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
<foreignObject id="G" width="300" height="200">
<svg>
<!-- Barcode here -->
<rect fill="black" stroke-width="2" height="112" width="84" y="55" x="55" stroke="#000000"/>
<circle fill="#FF0000" stroke="#000000" stroke-width="5" cx="155" cy="65" id="svg_7" r="50"/>
</svg>
</foreignObject>
</svg>

Cut off half of the SVG's text element

How can I make this
to look like this
So I want to halve the text element. I don't want to hide half of the text outside of SVG. Hiding it outside of g would be ok, but haven't found solution.
<svg width="500" height="500">
<g transform="translate(50,50)">
<rect width="80" height="50" style="fill:rgb(0,0,255);"/>
<text font-size="40" x="0" y="15" fill="black">SVG</text>
</g>
</svg>
JSFIDDLE:
http://jsfiddle.net/64nkLcdy/
Use the clip-path property :
<svg width="500" height="500">
<defs>
<clipPath id="myClip">
<rect width="80" height="50" />
</clipPath>
</defs>
<g transform="translate(50,50)">
<rect width="80" height="50" style="fill:rgb(0,0,255);" />
<text font-size="40" x="0" y="15" fill="black" clip-path="url(#myClip)">SVG</text>
</g>
</svg>
Use an <svg> element rather than a <g> as the svg element will clip its contents by default. The overflow property controls clipping i.e overflow="visible" doesn't clip but overflow="hidden" does.
<svg width="500" height="500">
<svg transform="translate(50,50)" width="80" height="50" overflow="hidden">
<rect width="80" height="50" style="fill:rgb(0,0,255);"/>
<text font-size="40" x="0" y="15" fill="black">SVG</text>
</svg>
</svg>

How to Exclude Area inside of clippath in Svg

I want to hide anything that outside a rectangle. (this i have achieved with clipping successfully). but another condition is that, 'also hide anything that comes inside the black big circle'. Now how i can achieve that?
in below example, 'yellow circle' must be eliminated'.
see below images for detail
Original:-
Desired:-
Below is my Svg code:-
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="500" height="500">
<g>
<rect x="50" y="50" width="200" height="200" stroke="1" fill="red"/>
<circle cx="180" cy="150" r="30" stroke="blue" />
</g>
<g clip-path = "url(#clip1)">
<circle cx="180" cy="150" r="10" stroke="blue" fill="yellow" />
</g>
<clipPath id = "clip1">
<rect x="50" y="50" width="200" height="200" stroke="1" fill="red"/>
</clipPath>
</svg>
Erik Dahlström is right, your clip can include the entire rectangle and the cutout for the circle. This way, anything you associate with #clip1 as the clip-path will not be visible inside your circle area. Here is what it looks like for your example:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="500" height="500">
<g>
<rect x="50" y="50" width="200" height="200" stroke="1" fill="red"/>
<circle cx="180" cy="150" r="30" stroke="blue" />
</g>
<g clip-path = "url(#clip1)">
<circle cx="180" cy="150" r="10" stroke="blue" fill="yellow" />
</g>
<clipPath id = "clip1">
<path d="M 50,50 l200 0 l0 200 l-200 0z M150,150 a30,30 1 0,0 60,0z M210,150 a30,30 1 0,0 -60,0z"/>
</clipPath>

Resources