Draw arrows between two circles using svg - javascript

I am using svg to draw several arcs with arcs on the end between 2 circles with the help of Bezier quadratic path.
Here is the final effect I want to achieve.
http://www.apcjones.com/arrows/
I already had some idea about how to draw several arcs(without arrows) between two circles.
But when I tried to draw several arcs(with arrows on the end) between 2 circles, something weird happened.
I am using here and I set refX to "radius" of the circle to offset the line inside the circle. But I soon realized that simply using refX does not solve the problem, the angle of the marker should also be adjusted(I do not know how).
current effect
Thanks for the help!

In this case you may need to use markers.
<svg width="200" height="100" viewBox="0 0 200 100">
<defs>
<desc>Define the marker</desc>
<marker id="arrow" refX="4" refY="3" markerWidth="6" markerHeight="6" orient="auto" stroke="black">
<path d="M 0 0 L 4 3 L 0 6 Z"></path>
</marker>
</defs>
<desc>Use the markers</desc>
<circle cx="160" cy="50" r="20" />
<circle cx="50" cy="50" r="20" />
<line x1="70" y1="50" x2="140" y2="50" fill="none" stroke="black" stroke-width="2" marker-end="url(#arrow)"></line>
</svg>
If you need more help please edit your question and add your SVG code

Related

How to draw a flickering circle in JavaScript

I have no idea how to draw this circle. Please give me a direction that how to proceed this question. Thank everyone for helping me.
I try to draw a flickering circle by using blink(), but it was nothing happened. And i find that the blink() function is no longer work.
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="50">
<animate
attributeName="fill"
values="black;white;black"
dur="1s"
repeatCount="indefinite" />
</circle
</svg>

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

Is it possible to extend the height and width of a child element beyond its container?

I have a zoomable svg that's provided by 3rd a party API. It's basically a drawing that's mapped to a grid. The problem is the API doesn't include the grid in the provided svg file so I have to hack it to include one. Basically, the markup is like this:
<svg>
<g>
<line>....
<rect>....
etc...
</g>
</svg>
The zoom functionality is done and now I'd like to add the grid. I'm thinking I should add it like so:
<svg>
<g>
<rect x="0" y="0" width="100%" height="100%" fill="black" />
<defs>
<pattern id="grid" width="20" height="20" patternUnits="userSpaceOnUse">
<path d="M 1 1 L 0 0 0 0" fill="none" stroke="green" stroke-width="1" />
</pattern>
</defs>
<rect x="-100%" y="-100%" width="200%" height="200%" fill="url(#grid)" />
<line>....
<rect>....
etc...
</g>
</svg>
The grid is drawn but it's bound within the <g> tag. Is it possible to extend the grid beyond it but still zoomable? Or are there other better ways to achieve this?

Mouse handling for overlapping SVG elements not working as expected

I have several SVG path elements, each of which is inside a parent svg element, like so:
<svg class="connector" style="position:absolute;left:277.5px;top:65px" position="absolute" pointer-events:"none" version="1.1" xmlns="http://www.w3.org/1999/xhtml" height="152.5px" width="410.015625px">
<path fill="none" stroke="#ff0000" stroke-width="6" pointer-events="visibleStroke" d="M0 3C100 3 310.015625 149.5 410.015625 149.5" id="path1"></path>
</svg>
<svg style="position:absolute;left:277.5px;top:109px" position="absolute" pointer-events:"none" version="1.1" xmlns="http://www.w3.org/1999/xhtml" height="108.5px" width="410.015625px">
<path fill="none" stroke="#880000" stroke-width="6" pointer-events="visibleStroke" d="M0 3C100 3 310.015625 105.5 410.015625 105.5" id="path2"></path>
</svg>
The svg elements (and thus their child paths) are visually overlapping.
I want to have a hover effect, so I've setup a mouseenter and mouseleave event on each of the paths.
When the mouse is overtop of an area that doesn't overlap, the hovering works as expected, however, when the mouse is over top of an area where the bounding rects of the svg elements overlap, the mouse events are not triggered correctly.
If, however, I place the same two path elements into a single svg as shown below, then the mouse hovering works as expected, even where the bounding rectangles overlap.
<svg class="connector" style="position:absolute;left:277.5px;top:265px" position="absolute" pointer-events:"none" version="1.1" xmlns="http://www.w3.org/1999/xhtml" height="152.5px" width="410.015625px">
<path fill="none" stroke="#00ff00" stroke-width="6" pointer-events="visibleStroke" d="M0 3C100 3 310.015625 149.5 410.015625 149.5" id="path3"></path>
<path fill="none" stroke="#008800" stroke-width="6" pointer-events="visibleStroke" d="M0 3C100 3 310.015625 105.5 410.015625 105.5" id="path4"></path>
</svg>
JSFiddle
Here is a jsfiddle showing the two cases. The red lines are in separate svg elements and the green lines are in a single svg element. The green lines work as I expect. The red lines do not.
Notes
The paths only look different because the two SVG elements had different "top" attributes in the first example.
Some similar questions mention the need to set pointer-events, but I think I've got those set correctly (to none on the svg element, and to visibleStroke on the paths).
Question
How can I make the mouse handle of the first case, with two svg elements, behave the same way as for the second case with a single svg element?
Adding pointer-events="none" with the correct syntax (you are using a : instead of an =) to the svg on top seems to work for me at least on Firefox. Like so...
<svg class="connector" style="position:absolute;left:277.5px;top:65px" height="152.5px" width="410.015625px">
<path fill="none" stroke="#ff0000" stroke-width="6" pointer-events="visibleStroke" d="M0 3C100 3 310.015625 149.5 410.015625 149.5" id="path1"></path>
</svg>
<svg style="position:absolute;left:277.5px;top:109px;" pointer-events="none" height="108.5px" width="410.015625px">
<path fill="none" stroke="#880000" stroke-width="6" pointer-events="visibleStroke" d="M0 3C100 3 310.015625 105.5 410.015625 105.5" id="path2"></path>
</svg>
<svg class="connector" style="position:absolute;left:277.5px;top:265px" position="absolute" height="152.5px" width="410.015625px">
<path fill="none" stroke="#00ff00" stroke-width="6" pointer-events="visibleStroke" d="M0 3C100 3 310.015625 149.5 410.015625 149.5" id="path3"></path>
<path fill="none" stroke="#008800" stroke-width="6" pointer-events="visibleStroke" d="M0 3C100 3 310.015625 105.5 410.015625 105.5" id="path4"></path>

Creating SVG markers for PolyLine in alternative points. (Step curve)

I am creating a polyline as a step curve. I want the markers to placed on at the point of significance and not at every end of the lines of the steps. How do i accomplish this?
<polyline points="0,0 140,125 160,140 180,220 220,240 300,280 400,450 500,500 900,900"
style="fill: none;"
stroke="blue"
stroke-width="5"
marker-start="url(#point)"
marker-mid="url(#point)"
marker-end="url(#point)"
clip-path="url(#clip)" />
<defs>
<marker id="point" viewbox="0 0 10 10" refx="5" refy="5" markerwidth="10" markerheight="10"
orient="auto" markerUnits = "userSpaceOnUse">
<circle cx="5" cy="5" r="1" stroke="red" stroke-width="1" fill="black">
</circle>
</marker>
</defs>
</g>
I do not want to use two different SVG PolyLines to create the proper markers.
There is no way to control which of the points in a line get markers, other than the coarse control provided by marker-start, marker-mid and marker-end.
Finer control is proposed for SVG2, but that doesn't help you now.
Your only solution is to add separate elements to the file for each of your points of interest.

Categories