how can I Create a popup ballon on an SVG image? - javascript

I have an SVG image that is a map and I would like to apple on some parts of the map the hover action that will show a popup balloon with some information about that part and also a button to redirect the client to another page.
I got the map parts with CSS classes that I added and I tried to make a div with the absolute display but it does not look responsive and changes the position based on the screen size.
there are somehow make it responsible on top of SVG image?

You can use <title>content</title> as part of the SVG code, to include text data as hints (the browser will show a standard tooltip).
Also, you can add events to track the pointer position and put some custom tooltip over there.
var elements=document.getElementsByClassName("hint");
var tooltip=document.getElementById("tooltip");
for(var i=0; i<elements.length; i++){
elements[i].addEventListener('mousemove', function(ev){
//console.log('move',ev.offsetX,ev.offsetY);
tooltip.innerHTML=ev.target.firstChild.textContent;
tooltip.style.left=ev.pageX+"px";
tooltip.style.top=(ev.pageY+20)+"px";
tooltip.style.display='block';
})
elements[i].addEventListener('mouseout', function(ev){
//console.log('out',ev.offsetX,ev.offsetY);
tooltip.innerHTML=ev.target.firstChild.textContent;
})
};
circle{
border: 1px solid #ff0;
}
#tooltip{
position: absolute;
background-color: #fff;
padding:4px;
width: 50px;
z-index: 1;
display: none;
}
<div>
<div>Interactive SVG Example</div>
<div id="tooltip"></div>
<svg version="1.1"
baseProfile="full"
width="300" height="200"
xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" fill="black" ><title>Black</title></rect>
<circle class="hint" cx="150" cy="100" r="30" fill="blue" ><title>blue</title></circle>
<circle class="hint" cx="250" cy="100" r="20" fill="red" ><title>red</title></circle>
</svg>
</div>

So if you put some div in absolute position you can just react on window resize. After pop up just hook function position you balloon and update position on windows resize event, (you can throttle it by lodash/throttle).If you don't want use js, you can try by css calc with width of window or you're svg container. Give us code example then some one can tell you more.

Related

How to make a full width overlay with masked portions

I'm trying to make a massive overlay for a site using css masks. It doesn't seem to work however. I have created a div to be the overlay and then made an svg with some cut-outs to be my masked portions. I expect to see the specified shape cut-out, but I can't see anything of the sort.
body{
background: red;
}
.overlay{
width: 100%;
height: 100%;
background-color: white;
position: fixed;
top: 0;
left: 0;
z-index: 1000;
opacity: 0.8;
}
<svg width="0" height="0">
<defs>
<mask id="hole">
<rect width="100" height="100" fill="blue"/>
<rect x="200" y="100" width="100" height="100" fill="yellow"/>
</mask>
</defs>
</svg>
<div class='overlay'
mask="url(#hole)"></div>
Does anyone know what I'm missing here?
PS: I think this is the most straightforward approach for my use-case. I'm trying to insert page markers into third party sites and then create a whole page overlay which fades out the website background, but leaves only my markers fully visible. I considered using clip-path, but it seems that does the reverse of what I need. I want something that shows my image, except for the positions/shapes specified.

Centering icon inside SVG circle chart

I'm trying to put an icon inside an SVG circular graph so that it will display like this: SVG graph example.
No matter what I do, there's always a slight gap between one side of the inner icon and the SVG path that displays like this. I think the issue has to do w/the fact that the arc degree for the SVG circular graph isn't a perfect circle
Here's everything I've already tried:
Created a static png of the inner icon image so that it wasn't a perfect circle + then wrapped the SVG around it
Created SVG in illustrator with the inner icon as a png with two outer paths: one for the grey fill all around and one for the green fill to represent 50%. When I export the file, the d parameter is displaying based on coordinates, not percentages.
<path d="M82,153.53C122.23,153.41,153.2,121,153.46,82,153.69,43.3,122.59,10.94,82,10.49"
fill="none" stroke="#7aef93"
stroke-miterlimit="10" stroke-width="15" />
I started playing around w/this on CodePen, but didn't get very far.
Is this even possible to achieve? I'd really appreciate any and all help/feedback!
This is a fast solution, I don't know is it good. You should add class circle to the second svg like this:
<svg class="circle" width="120" height="120" viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<circle cx="60" cy="60" r="59" fill="#F07C7C" stroke="#D0CFCF" stroke-width="2"/>
<rect x="22" y="22" width="75" height="75" fill="url(#pattern2)"/>
<defs>
<pattern id="pattern2" patternContentUnits="objectBoundingBox" width="1" height="1">
<use xlink:href="#image2" transform="scale(0.00390625)"/>
</pattern>
<image id="image2" width="256" height="256"
xlink:href="data:image/png;base64,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"/>
</defs>
</svg>
And then you should add this css:
.circle {
position: absolute;
top: 25px;
left: calc(50% - 108px);
}
This should make a second svg inside first svg.

How can I change an SVG color without using an ID in the SVG file itself?

Newbie to working with SVGs and I've run into a problem. Basically I'm using the Noun Project API pro version ( https://api.thenounproject.com/ ) to scrape icons as SVGs. Right now, I save the SVGs in a local folder. I want to be able to change the color of the icon (right now they download as black, and I want to change the color). I am loading the SVGs via the tag with a reference to the folder where the SVGs are being saved. I know it's fairly simple to change the color using vanilla JS (using document.getElementById('svgObject').contentDocument, and then accessing the inner document using a unique id). The problem is that the SVGs I save don't have any ID, and I don't know how to give them an ID. Right now, I'm looping through the folder and displaying the folder contents in a webpage. That's all working fine, but I can't manage to figure out how to change the color.
Basically, I just want all the icons in the folder to be set to a different color (for example, they could all be set to "red." They don't need to each have a different color). How do I do that without specifying the actual ID (since the SVG doesn't include an ID upon download), or else how do I add an ID to the SVG tag itself?
Assuming you have a bunch of svgs on your page and you'd like to change the color of each to the same color, you could do the following:
function changeSvgColors() {
const svgs = document.getElementsByTagName('svg')
for (let i = 0; i < svgs.length; i++) {
svgs[i].setAttribute('fill', 'red')
}
}
This will loop through every svg on your page and set their fill attribute to red.
Essentially, this is equivalent to doing this:
<svg viewBox="0 0 512 512" fill="red">
...
</svg>
Here's a quick demo:
JSFiddle
Alternatively, if you're using something like the img tag to load your svgs onto your page, using object instead would let you do the same thing as above.
Assuming your html looks like the following:
<div>
<object
data="http://localhost:5000/image.svg"
type="image/svg+xml"
></object>
</div>
Then,
function changeSvgColors() {
const objects = document.getElementsByTagName('object')
for (let i = 0; i < objects.length; i++) {
const object = objects[i]
const svg = object.contentDocument.rootElement
svg.setAttribute('fill', 'red')
}
}
One option would be using the svg as an image (or as an object if you prefer) and filters to change the color.
#theImage{filter: invert(27%) sepia(51%) saturate(2878%) hue-rotate(346deg) brightness(104%) contrast(97%);}
<img id="theImage" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/bone300.svg" >
Please read this article: Solved with CSS! Colorizing SVG Backgrounds
Yet another option is using the svg as a mask. Keep in mind that the support for mask is not that good.
#theDiv{
display: inline-block;
width:300px;
height:134px;
-webkit-mask: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/bone300.svg);
mask: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/bone300.svg);
mask-size: cover;
background:red;
}
<div id="theDiv"></div>
But the best option would be to use the svg inline. You may save all your icons in a root svg element with width="0"; height="0"; position="absolute". Next you can use the icons with <use> and you change the color using the fill attribute <use fill="red" xlink:href="..... or styling it in CSS
You can give the SVGs a class instead of an id & set the color using javascript's getElementsByClassName
This Mozilla article explains:
https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName
Your best shot in achiveing this is to make use of the fill attibute for svg elements. Now, you can work this out two ways
Method 1:
Using img tag like this <img src="your_file.svg" />. In this case, you will need to edit the file directly, and that's it, it should reflect everywhere you reference the svg.
Method 2:
You can use svg as inline like below. The advantage in this approach is that if you have varying instance of the same svg, then this is the way to go. On the other side, if your svg stays same throughout the app, this goes against the DRY principle.
svg {
max-width: 200px;
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<path d="M25,7l28,36l40-18l-36,25l19,44l-27-37l-41,17l36-26z" fill="#cfc"/>
<ellipse cx="50" cy="50" rx="32" ry="30" stroke="#fc0" fill="none" stroke-width="11"/>
<path d="M63,2l-7,43l42,17l-45-6l-16,42l7,-45l-42-16l45,6z" fill="#3cc"/>
</svg>
If you don't mind having the svg all one color, you could set the fill attribute of the svg to currentcolor. Then it will take on the color of the element that it is in.
#span1 {
color: red;
}
#span2 {
color: blue;
}
#span3 {
color: green;
}
<body>
<span id=span1>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="150" height="150" fill-rule="evenodd" fill="currentcolor">
<title>HTML5 Logo</title>
<path d="M12,0 188,0 172,180 100,200 28,180Z M45,37 156,37 154,59 69,59 71,81 152,81 146,149 100,162 54,149 52,114 74,114 76,132 100,139 124,132 127,103 51,103Z"/>
</svg>
</span>
<span id=span2>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="150" height="150" fill-rule="evenodd" fill="currentcolor">
<title>HTML5 Logo</title>
<path d="M12,0 188,0 172,180 100,200 28,180Z M45,37 156,37 154,59 69,59 71,81 152,81 146,149 100,162 54,149 52,114 74,114 76,132 100,139 124,132 127,103 51,103Z"/>
</svg>
</span>
<span id=span3>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="150" height="150" fill-rule="evenodd" fill="currentcolor">
<title>HTML5 Logo</title>
<path d="M12,0 188,0 172,180 100,200 28,180Z M45,37 156,37 154,59 69,59 71,81 152,81 146,149 100,162 54,149 52,114 74,114 76,132 100,139 124,132 127,103 51,103Z"/>
</svg>
</span>
</body>

Cutting out a text shape from background that can be resized dynamically

I'm trying to create a box that is opaque, but has a block of text in it that you can see through (to like the background image of the page or some element underneath).
It's hard to explain so I've made some crude diagrams:
I am attempting to use SVG files to do this and use Javascript/jquery to modify the rectangle width and height but I'm not proficient at the SVG format... I've managed to piece this together using the evenodd filter:
https://jsfiddle.net/PhoenixFieryn/sqvLgqbq/
<svg id="coverimage" width="80pcm" height="30cm" viewBox="0 0 2000 2000" version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<desc>Example fillrule-evenodd - demonstrates fill-rule:evenodd</desc>
<defs>
<rect x="1" y="1" width="2000" height="1000"
fill="white" stroke="blue" />
</defs>
<g fill-rule="evenodd" fill="white" >
<path d="M0 0 h1000 v1000 h-1000z M841,396.8c-2.4-4-1.6-8.8,2.4-11.2c68-44,95.2-105.6,95.2-172.8c0-116-96.8-205.6-211.2-205.6H610.6H469.8
h-6.4c-4,0-5.6,1.6-8.8,6.4L315.4,320c-4,6.4-8,6.4-11.2,0l-140-306.4c-2.4-4.8-4.8-6.4-8.8-6.4H9c-5.6,0-8.8,4-6.4,9.6l264,554.4
c1.6,4,5.6,6.4,9.6,6.4h66.4c4,0,7.2-1.6,8.8-5.6l110.4-230.8v228.4c0,4.8,3.2,8,8,8h146.4c4.8,0,8-3.2,8-8V426.4c0-4.8,3.2-8,8-8
h42.4c4,0,8,1.6,9.6,5.6l76,148c1.6,4,5.6,5.6,9.6,5.6h158.4c5.6,0,8.8-4,5.6-9.6L841,396.8z M701.8,276h-69.6c-4.8,0-8-3.2-8-8
V158.4c0-4.8,3.2-8,8-8h75.2c36.8,0,68,28.8,68,62.4C775.4,244,750.6,276,701.8,276z"/>
</g>
I don't know how to modify the size/position of the text and rectangle independently well. I can barely understand what I wrote and why the margin is so big.
If anyone could help me, through this or any other method, thank you!
Edit: someone pointed out that there may be a duplicate, but that solution does not work in Firefox unfortunately. I am looking for a cross “platform” solution. But thanks for the link, it’s very helpful nonetheless.
My suggestion is to create a mask using the text. We then create a blue rectangle that we mask with the our text mask.
We can postion the SVG and have it size the way we want using SVG width and height. But we also make the blue rectangle very large and have the SVG set to overflow: visible. This allows us to easily have the SVG size be responsive and also have the blue extend to all the way to the edges of the screen.
body {
background-image: url('http://austinhou.com/img/cover.jpg');
background-size: cover;
margin: 0;
padding: 0;
}
#coverimage {
width: 40%;
height: 100vh;
overflow: visible;
}
<body>
<svg id="coverimage" viewBox="0 0 950 600" preserveAspectRatio="xMinYMid meet">
<defs>
<mask id="vr">
<rect x="0" y="-1000%" width="1000%" height="3000%" fill="white"/>
<path fill="black" d="M841,396.8c-2.4-4-1.6-8.8,2.4-11.2c68-44,95.2-105.6,95.2-172.8c0-116-96.8-205.6-211.2-205.6H610.6H469.8
h-6.4c-4,0-5.6,1.6-8.8,6.4L315.4,320c-4,6.4-8,6.4-11.2,0l-140-306.4c-2.4-4.8-4.8-6.4-8.8-6.4H9c-5.6,0-8.8,4-6.4,9.6l264,554.4
c1.6,4,5.6,6.4,9.6,6.4h66.4c4,0,7.2-1.6,8.8-5.6l110.4-230.8v228.4c0,4.8,3.2,8,8,8h146.4c4.8,0,8-3.2,8-8V426.4c0-4.8,3.2-8,8-8
h42.4c4,0,8,1.6,9.6,5.6l76,148c1.6,4,5.6,5.6,9.6,5.6h158.4c5.6,0,8.8-4,5.6-9.6L841,396.8z M701.8,276h-69.6c-4.8,0-8-3.2-8-8
V158.4c0-4.8,3.2-8,8-8h75.2c36.8,0,68,28.8,68,62.4C775.4,244,750.6,276,701.8,276z" transform="translate(-210 0)"/>
</mask>
</defs>
<rect x="0" y="-1000%" width="1000%" height="3000%" fill="#09f" mask="url(#vr)"/>
</svg>
</body>
JSFiddle version

Border for svg elements

I am working with svg and its dom manipulation. I want to create a border for a group of svg elements positioned inside the <g> tag. How do I do this? Is it possible to create circular / elliptical boundaries also? I am using the jQuery SVG library. Thanks in advance
<g>
<rect x="20" y="30" width="200" height="300" fill = "red"/>
<circle cx="40" cy="50" r="25" fill="blue"/>
</g>
You cannot add a border to containers like <g> or <svg>, since they are not supposed to render anything directly by themselves. You may want to look how this demo is implemented using the cross browser implementation of getScreenBBox();
In your CSS you could add:
rect {border: 1px solid #00f;}

Categories

Resources