Mouseover on SVG circles - javascript

I'm very new to SVG, so please forgive me if this is a basic question.
I would like to draw circles on the screen and respond whenever the user mouses over each circle.
From what I can tell, when listening to mouse events on an svg, we are actually listening to mouse events on the whole canvas and not on the shapes.
If I want to handle events on the shapes, I have to use a library like D3.
Is it possible to listen to mouseOver event that are triggered when the mouse pointer passes over a specific circle?

No library is needed for this. Given the following SVG:
<svg width="500" height="500">
<circle id="circle1" cx="50" cy="50" r="20" fill="red"/>
<circle id="circle2" cx="150" cy="50" r="20" fill="green"/>
</svg>
You could use CSS or Javascript to have these circles change in some way related to the mouse.
For a simple hover in css you can do something like:
#circle1:hover {
fill: blue;
}
Or any JavaScript mouse event like so:
document.getElementById('circle2').addEventListener('click', function(e) {
e.currentTarget.setAttribute('fill', '#ff00cc');
});
Here is a demo for you to check out:
http://codepen.io/ZevanRosser/pen/bdYyLp

If you want this to only be svg and be able to open this in a browser and see the effect (although Zevan's answer can be embedded in svg), use something like:
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="500" height="500">
<circle id="circle1" cx="50" cy="50" r="20" fill="red" onmouseover="evt.target.setAttribute('fill', 'blue');" onmouseout="evt.target.setAttribute('fill','red');"/>
<circle id="circle2" cx="150" cy="50" r="20" fill="green" onmouseover="evt.target.setAttribute('fill', 'blue');" onmouseout="evt.target.setAttribute('fill','green');"/>
</svg>
the CSS option shared is cleaner, but this pattern may offer more flexibility for future mouse handling, especially if needing a function to figure out how long you want to let a user "pause" over the circle before actually modifying the property.

Try this...
<circle onmousemove={() => console.log('foo') }/>

Related

Scaling down paths/elements on an svg with very high coordinates that have many decimal points

Let's say you have a list of coordinates like so:
2942852.602193035 472992.4195375803
How would you go about scaling these down so that they fit in an svg. Coordinates like 294.2852602193035 472.9924195375803 would fit, but scaling my lines to (.0001) with the scale property on my lines doesnt seem to work. It is fairly intricate linework. Does anyone have any suggestions?
Here's where you can check out some code:
https://snack.expo.io/_-0M6dRP5
<Svg
height="1920"
width="1080"
fill="none"
viewBox="294.2852602193035 472.9924195375803 897.8977111047134 1329.2074627304683"
preserveAspectRatio='none'>
{//this rectangle shows up }
<Rect x="294.285534094599" y="472.6193465770291" width="300" height="300"
fill="blue" onPress={()=>{alert('achoo!')}}/>
{//this one doesn't, even without the transform matrix}
<G transform="matrix(1,0,0,-1,0,0)" scale="0.0001">
<Rect x="2942855.34094599" y="472619.3465770291" width="300" height="300"
fill="red" onPress={()=>{alert('achoo!')}}/>
</G>
</Svg>

How would I add custom SVG shapes to an equation generated with MathJax?

I'd like to use MathJax to write various equations that include SVG shapes along the lines of the following:
(2 * [red box]) + [red box] = [three red boxes]
Where each item in brackets would be a custom SVG element defined in the HTML ranging from simple (a single box) to more complex (multiple shapes). The reason for needing this is that I want to use MathJax's ability to format math equations while replacing some symbols with SVG shapes. I may need to specify other HTML as well.
I suspect this can be achieved by using MathJax's HTML snippets but I don't know how to take the sample code they provide and make it work for any given equation.
Any help would be greatly appreciated.
If you are using MathML input, you can use the <mglyph> element to include an svg image into your expression, as in:
<math>
<mglyph src="dice.svg" height="42px" width="42px" valign="-14px" alt="Dice showing five dots"></mglyph>
</math>
or even
<math>
<mglyph src='data:image/svg+xml,
<svg xmlns="http://www.w3.org/2000/svg" height="42px" width="42px">
<rect stroke="black" fill="none" x="1px" y="1px" stroke-width="2px" rx="5px" width="40px" height="40px"></rect>
<circle stroke="black" fill="black" cy="30px" cx="30px" r="5px"></circle>
<circle stroke="black" fill="black" cy="30px" cx="10px" r="5px"></circle>
<circle stroke="black" fill="black" cy="20px" cx="20px" r="5px"></circle>
<circle stroke="black" fill="black" cy="10px" cx="30px" r="5px"></circle>
<circle stroke="black" fill="black" cy="10px" cx="10px" r="5px"></circle>
</svg>'
valign="-14px"
alt="Dice showing five dots">
</mglyph>
</math>
If you are using TeX input, you can create the mglyph using the \mmlToken macro:
\mmlToken{mglyph}[src="dice.svg" width="42px" height="42px" valign="-14px" alt="Dice showing five dots"]{}
You can also use the "img" extension from the third-party extension library. This defines an \img macro that makes loading the image a bit easier:
\img[-14px][42px][42px]{dice.svg}
I think you should be able to do what you want using one of those.
(This is my response to the cross-post on the MathJax User's Forum)

How to stop SVG animateMotion on hover?

I am using a path:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%" viewBox="0 0 400 400" xml:space="preserve">
<g class="path path--1">
<path class="path_layer" id="path1" d="M200,240c-80,0 -80,-80 0,-80c80,0 80,80 0,80" stroke="#333333" stroke-width="2" fill="none"/>
</g>
<circle r="5" fill="white" id="planet">
<title>Computer Science</title>
<animateMotion dur="15s" repeatCount="indefinite" keyPoints="0.5;0;1;0.5" keyTimes="0;0.5;0.5;1" calcMode="linear">
<mpath xlink:href="#path1" />
</animateMotion>
</circle>
along which I will be animating the circle as shown above.
Now, I would like to stop the animation on hover, any idea how to do this?
When I hover on the circle, I want to stop the animation and later resume it from wherever I stopped it. The CSS way does not work for this. Should I use JS, if so, how?
You can use the SVG DOM to pause and unpause the animation timeline. The <svg> element's interface has the following useful methods:
pauseAnimations(); // pauses the SMIL animation
unpauseAnimations(); // resumes the SMIL animation
setCurrentTime(); // changes the timeline thereby allowing you to rerun an animation

Changing Clickable Area of an Image without Resizing Image

I am currently working on a PHP/Javascript project where an action occurs when an image is clicked. The image is small, so I would like to expand the clickable area to further around the image without enlarging the image itself. Is this possible? Below is a general idea of the structure of what I'm working on.
<g id="pictures">
<image id="marker_image" cx="145" cy="460" r="1" preserveAspectRatio="none"
x="136" y="451" width="18" height="18"
xmlns:xlink="http://www.w3.org/1999/xlink"
xlink:href="//link.thislink.com/image_assets/markers/pool.png"
style="opacity: 1" fill="#000000" fill-opacity="1" stroke="#000000"
stroke-opacity="1" stroke-width="2" stroke-linecap="round" stroke-
linejoin="round"></image>
</g>
I'm new to working with SVGs, but from what I've read, I think I can use the <g> to add padding?
Wrap you image in a div, make the div as big as you want using padding, and bind your action on the div instead of the img

Toggle layer in SVG

I am trying to create a HTML page with a check list that we can also make it large without losing quality. As a result I want to use SVG.
I would like to have a script to operate on the SVG so that I can toggle the group svg_2 (a check mark) on or off so that we have checked and unchecked box. It doesn't have to change when loaded, just need like an inline command that will do it.
<svg width="20%" height="20%" xmlns="http://www.w3.org/2000/svg">
<rect id="svg_1" fill="#ffffff" stroke="#000000" stroke-width="10%" x="2.5%" y="2.5%" width="85%" height="85%" />
<g id="svg_2">
<line fill="none" stroke="#ff0000" stroke-width="10%" x1="43.5%" y1="77.5%" x2="10.5%" y2="49.5%" id="svg_3" stroke-linecap="round" stroke-linejoin="bevel"/>
<line fill="none" stroke="#ff0000" stroke-width="10%" x1="95%" y1="9.5%" x2="44.5%" y2="78.5%" id="svg_4" stroke-linecap="round" stroke-linejoin="bevel"/>
</g>
</svg>
You can use JavaScript to toggle the svg_2 on or off depending on its previous state (example using JQuery):
$("svg").click(function() {
if ( $('#svg_2').css('visibility') == 'hidden' )
$('#svg_2').css('visibility','visible');
else
$('#svg_2').css('visibility','hidden');
});
You could also use some other CSS attribute (such as display).
See and try it here: JSFiddle

Categories