Placing multiple tooltips at the same position in a HTML page - javascript

A HTML page contains 2 SVG shapes, each with a tooltip (created with Tippy).
How could I make the tooltips appear at the same position in the page (let's say in the red rectangle below - right side of the page)?
tippy('#circle_1', {
content: `That's a circle !`,
arrow: false,
});
tippy('#rect_1', {
content: 'Here is a rectangle !',
arrow: false,
});
<script src="https://unpkg.com/#popperjs/core#2"></script>
<script src="https://unpkg.com/tippy.js#6"></script>
<svg width="250" height="250">
<circle id="circle_1" cx="30" cy="45" r="25" />
<rect id="rect_1" x="80" y="25" width="60" height="40" />
<rect id="placeholder" x=150 y=25 width="100" height="50" fill-opacity="0" stroke="red" stroke-width="1" />
</svg>

A tooltip by definition is something that pops up where the cursor is.
If you need to set the popup text to show in other place, just use plain js/jquery
$(".tooltip-elem").hover(function(){
var tooltipText = $(this).data("tooltip");
//console.log(tooltipText);
$("#placeholder1").html( tooltipText );
});
$(".tooltip-elem").on("mouseleave", function(){
$("#placeholder1").html( "" );
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<svg style="display: inline-block;" width="250" height="150">
<circle class="tooltip-elem" id="circle_1" cx="30" cy="45" r="25" data-tooltip="That's a circle !" />
<rect class="tooltip-elem" id="rect_1" x="80" y="25" width="60" height="40" data-tooltip="Here is a rectangle !" />
</svg>
<div style="display: inline-block;" id="placeholder1"></div>

Related

Center elements inside SVG relative to each other-

Couldn't find it anywhere else to I might ask here :
I have svg rectangle which inside has other rectangles.
What I want to achieve is to center each of these rectangles in the centre of it's parent and in relation to each other.
If I drag rectangle 1 down I want the other one to move up to keep both of them centered - and same thing happening if I drag the other element down (should push upper one up).
Problem here is that I might have different width/heights and there would be 2 or more elements. Is there any mathematical equationfor that? Or a name that I can look for?
I would put the 3 rects inside a group and use the group as in the following example
svg{
border:1px solid;
width: 30vh;
}
<svg viewBox="0 0 100 280">
<defs>
<g id="rects">
<rect width="80" height="80" />
<rect width="60" height="25" x="10" y="10" />
<rect width="60" height="25" x="10" y="45" />
</g>
</defs>
<use xlink:href="#rects" x="10" y="10" stroke="black" fill="none" />
<use xlink:href="#rects" x="10" y="100" stroke="black" fill="none" />
<use xlink:href="#rects" x="10" y="190" stroke="black" fill="none" />
</svg>

Having real images on top of svg

I am working on svg rectangles which represent a farmer's field. Is it possible to have an image of a field on it, just to give it a true sense and view.
Here's a sample code of one of the rectangles
<!DOCTYPE html>
<html>
<body>
<svg width="400" height="110">
<rect width="300" height="100" style="fill:green; stroke: black; stroke-width:3;" />
</svg>
</body>
</html>
I used clipPath to cut and place the picture in a rectangle.
<svg width="600" height="200" viewBox="0 0 600 200" >
<defs>
<clipPath id="field">
<rect x="25" y="5" width="550" height="190" rx="25" ry="25" style="fill:none; stroke: black; stroke-width:1;" />
</clipPath>
</defs>
<image xlink:href=" https://i.stack.imgur.com/MJkK0.jpg" width="600" height="200" clip-path="url(#field)" />
</svg>
If you want to use a different border form instead of a rectangle, for example a circle, then this will be easy to do, replacing the rectangle with a circle in the clipPath.
Option, as suggested by Paulie_D, but it needs a little refinement
If you need a frame around the picture, you will need to add a second transparent rectangle with a border
<rect width="300" height="100" style="fill:none; stroke: black; stroke-width:3;" />
<svg width="400" height="110">
<defs>
<pattern id="field" patternUnits="userSpaceOnUse" width="300" height="100">
<image xlink:href=" https://i.stack.imgur.com/MJkK0.jpg" x="-20" y="0" width="350" height="130" />
</pattern>
</defs>
<rect width="300" height="100" fill="url(#field)" />
<rect width="300" height="100" style="fill:none; stroke: black; stroke-width:3;" />
</svg>
UPDATE
With a black frame looks grim, let's replace it with a shadow.
To create a shadow, the Gauss filter is used, blurring the edges of the bottom rectangle
<filter id="filtershadow" width="120%" height="120%">
<feGaussianBlur in="SourceAlpha" stdDeviation="4"/>
</filter>
<body>
<svg width="400" height="110">
<defs>
<filter id="filtershadow" width="120%" height="120%">
<feGaussianBlur in="SourceAlpha" stdDeviation="4"/>
</filter>
<pattern id="field" patternUnits="userSpaceOnUse" width="300" height="100">
<image xlink:href=" https://i.stack.imgur.com/MJkK0.jpg" x="0" y="0" width="350" height="130" />
</pattern>
</defs>
<rect class="rect-shadow" x="10" y="14" width="290" height="90" filter="url(#filtershadow)" style="fill:black; " />
<rect width="300" height="100" fill="url(#field)" />
</svg>
</body>

SVG image not show when set display none

I code a web app, in this have some images tag and I set it display to none. Like example code . My issue is when I run on some device image cannot load. When i set image show only blank display.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<svg>
<g id="gimg">
<image id="img" display="none" xlink:href="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png" x="0" y="0" height="50px" width="50px"/>
</g>
<rect id="myrect" x="100" y="100" width="20" height="20"></rect>
</svg>
<script>
$("#myrect").on("click",function(){
$("#img").show();
});
</script>
If the problem is in phones try this:
$("#myrect").on("click",function(){
$("#img").show();
return false;
});
Can you add style=display: none to your image element
<image id="img" style="display:none" xlink:href="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png" x="0" y="0" height="50px" width="50px"/>.
This should load the image
Have you tried this way?
<svg>
<defs>
<symbol id="my-icon" viewBox="0 0 30 30">
<rect id="myrect" x="25" y="25" width="20" height="20" />
</defs>
</symbol>
<image id="img" display="none" xlink:href="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png" x="0" y="0" height="50px" width="50px" />
</svg>
$("#myrect").on("click", function() {
$("#img").show();
});
Just change the viewBox, etc to your requirements.
I hope this helps.

Changing SVG colors

I'm starting to learn JS and i have this (probably very easy) task that I'm having problems with.
So the main task is to make the lower green triangle change it's color depending on which color i click on upper object.
I made something like this:
<!DOCTYPE html>
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>SVG, JavaScript</title>
<script type="text/javascript">
function changeColor("triangle"){
document.getElementById("group").getAttributeNS("fill");
evt.target.setAttributeNS("fill");
}
</script>
</head>
<body>
<svg height="500" width="500">
<g id="group">
<rect x="0" y="0" width="200" height="200" style="fill:gray;stroke:none;stroke-width:0"/>
<rect id="red_triangle" x="0" y="0" width="100" height="100" style="fill:red;stroke:none;stroke-width:0"/>
<rect id="yellow_triangle"x="100" y="0" width="100" height="100" style="fill:yellow;stroke:none;stroke-width:0"/>
<rect id="blue_triangle"x="0" y="100" width="100" height="100" style="fill:blue;stroke:none;stroke-width:0v"/>
<rect id="green_triangle"x="100" y="100" width="100" height="100" style="fill:lime;stroke:none;stroke-width:0"/>
<ellipse cx="100" cy="100" rx="100" ry="100" style="fill:gray;stroke:none;stroke-width:0"/>
<polygon id="triangle" points="100,225 150,300 50,300" style="fill:lime;stroke:none;stroke-width:0" onclick="changeColor("triangle")"/>
</g>
</svg>
</body>
</html>
but obviously it's not working. Could somebody help me with some suggestion?
// the string instead of argument name raises Error: unexpected string
function changeColor("triangle"){
// you get the attribute but don't do anything with it.
// and the group doesn't even have a fill attribute
document.getElementById("group").getAttributeNS("fill");
// here you try to set an attribute but setAttributeNS requires 3 arguments: namespace, attribute and value
// simpler setAttribute would be enough, but the value would still be overwriten by style="fill:whatever"
// and evt.target is undefined, there's no evt object
evt.target.setAttributeNS("fill");
}
then in your SVG:
// the quotes are broken,
// and here you pass a string which I'd assume to be the ID of an element you want to change
onclick="changeColor("triangle")"
So, all in all:
The onclick should be on the source rectangles, not the target triangle: <rect onclick="changeColor('triangle', this)" /> where 'triangle' is the ID of element you want to change, and this is a reference to the clicked rectangle.
SVG:
<svg height="500" width="500">
<g id="group">
<rect x="0" y="0" width="200" height="200" style="fill:gray;stroke:none;stroke-width:0"/>
<rect id="red_triangle" x="0" y="0" width="100" height="100" style="fill:red;stroke:none;stroke-width:0" onclick="changeColor('triangle', this)"/>
<rect id="yellow_triangle"x="100" y="0" width="100" height="100" style="fill:yellow;stroke:none;stroke-width:0" onclick="changeColor('triangle', this)"/>
<rect id="blue_triangle"x="0" y="100" width="100" height="100" style="fill:blue;stroke:none;stroke-width:0v" onclick="changeColor('triangle', this)"/>
<rect id="green_triangle"x="100" y="100" width="100" height="100" style="fill:lime;stroke:none;stroke-width:0" onclick="changeColor('triangle', this)"/>
<ellipse cx="100" cy="100" rx="100" ry="100" style="fill:gray;stroke:none;stroke-width:0"/>
<polygon id="triangle" points="100,225 150,300 50,300" style="fill:lime;stroke:none;stroke-width:0" />
</g>
</svg>
JS:
function changeColor( target, source ){
var color = source.style.fill;
document.getElementById( target ).style["fill"] = color;
}
Fiddle: http://jsfiddle.net/harg5kyz/1/

Can't change SVG rect properties in three containers

After several tries, and code changes, I am unable to make rectangle inside SVG to change his position - don't even ask for animating. Obviously using jQuery SVG plugin plus animation extension.
The problem: A SVGs wrapped inside three <div>, an inside y have a rectangle that need to be at y:0 after the document loads. And this is the code:
var rect = jQuery('div.post-image').children('svg').svg().svg('get');
jQuery(rect).each(function(){
jQuery(this).change('.b1', {y:0});
});
Well, nothing happens with the rectangle, it keeps the original coordinate. Chrome console doesn't says anything either.
Added: the HTML in question
<a href="#" class="post-image" title="title">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="250" height="140" viewBox="0,0,250,140" overflow="hidden">
<switch>
<g>
<defs>
<filter id="innershadow">
<feOffset dx="0" dy="0"></feOffset>
<feGaussianBlur stdDeviation="7" result="offset-blur"></feGaussianBlur>
<feComposite operator="out" in="SourceGraphic" in2="offset-blur" result="inverse"></feComposite>
<feFlood flood-color="#000" flood-opacity="0.3" result="color"></feFlood>
<feComposite operator="in" in="color" in2="inverse" result="shadow"></feComposite>
<feComposite operator="over" in="shadow" in2="SourceGraphic"></feComposite>
</filter>
<pattern xmlns="http://www.w3.org/2000/svg" id="image-771" patternUnits="userSpaceOnUse" width="250" height="202">
<image href="example-310x250.jpg" xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="250" height="202"></image>
</pattern>
<clipPath id="clip">
<polygon points="0,0 235,0 250,70 235,140 0,140 15,70"></polygon>
</clipPath>
</defs>
<polygon points="0,0 235,0 250,70 235,140 0,140 15,70" style="fill: url(#image-771); filter:url(#innershadow);"></polygon>
<rect class="b1" width="100%" height="100%" style="fill:rgb(0,92,148); opacity: 0.9;" clip-path="url(#clip)" x="0" y="98"></rect>
<rect class="b2" width="60" height="25" style="fill:rgb(0,92,148); opacity: 0.9;" clip-path="url(#clip)" x="190" y="0"></rect>
<rect class="b3" width="100" height="25" style="fill:rgb(0,0,0); opacity: 0.75;" clip-path="url(#clip)" x="0" y="0"></rect>
</g>
<foreignObject width="250" height="140">
<img width="250" height="125" src="example-fallback.jpg" alt="example" title="title"> </foreignObject>
</switch>
</svg>
</a>
I'm willing to use <canvas> for this, but I don't know what are the outcomes.
Found out what wast the problem:
var rect = jQuery('a.post-image').children('svg').find('.b2, .b3');
jQuery(rect).each(function(){
jQuery(this).attr('y','-25');
});
Done, and without a plugin. Okey, not the best way (find instead of most direct selector), but it will cut it.

Categories