I have a problem for which made simplified code for express it. In few words I need to build code in Javascript for painting connected SVG lines. The simple example:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" >
<line x1="50" y1="50" x2="200" y2="50" stroke="steelblue" stroke-width="20" onclick="fillWall(evt)" />
<line x1="100" y1="100" x2="400" y2="100" stroke="steelblue" stroke-width="20" onclick="fillWall(evt)" />
<line x1="300" y1="300" x2="200" y2="300" stroke="steelblue" stroke-width="20" onclick="fillWall(evt)" />
<line x1="100" y1="50" x2="100" y2="400" stroke="steelblue" stroke-width="20" onclick="fillWall(evt)" />
<line x1="300" y1="100" x2="300" y2="300" stroke="steelblue" stroke-width="20" onclick="fillWall(evt)" />
<line x1="200" y1="300" x2="200" y2="200" stroke="steelblue" stroke-width="20" onclick="fillWall(evt)" />
<script type="text/javascript">
<![CDATA[
function fillWall(evt) {
var tgt=evt.target;
tgt.setAttributeNS(null, "stroke", "firebrick");
}
]]>
</script>
</svg>
This is labyrinth of few walls when you click on some it changes color, so I need to do it with one click to paint all connected, no matter on which wall click is applied. In full sized scale there are almost thousand of these walls, and some are connected, some aren't. I tried to learn recursive functions, but easily exceeded stack size.
Please help, I'll appreciate that a huge.
there is a function on purpose: getIntersectionList that paired with getBBox
could help you to solve your problem. Pseudo code:
fillWall(evt) {
fillConnected(evt.target, [])
}
fillConnected(node, filled) {
if (!filled.contains(node)) {
fill(node);
filled.append(node);
foreach(n in document.getIntersectionList(node.getBBox()))
fillConnected(n, filled)
}
}
I'll try to craft actual code using jsFiddle, and will post the address later...
edit see this fiddle, but it seems that Firefox doesnt' still implements the required getIntersectionList. Then if we must craft our own, it's surely best if we cache the lists, because it's going to be a rather costly method...
edit I've modified the fiddle' code, that worked just on local files, now in Chrome run fine, but where the walls just touch, the getIntersectionList doesn't work. So we must anyway implement our own version... See you later...
edit well, at last the fiddle seems to work. Please note that walls must have their endpoints sorted (x2 >= x1, y2 >= y1), You can see on that walls coloured yellow (corrected) and green (still wrong) the effect of that sort.
Pseudo-code version of mine:
function doWall(I_oWall) {
if I_oWall.painted then return;
I_oWall.paint();
for each wall in walls
if I_oWall.isAdjacentTo(wall) then
doWall(wall);
end if
loop
}
Sorry, I know it is not a full and complete answer but I think it will really help you in how to figure out your issue.
cheers
Related
I am having a very weird issue that I have no idea whatsoever how to debug.
I have a html file with a div that has the jquery UI draggable enabled:
$(function() {
$(".ideanode").draggable({ containment: "parent" });
});
this is working fine and dandy until I include this in my html:
<svg id="connectors" height="100%" width="100%">
<defs>
<marker id="markerArrow" markerWidth="13" markerHeight="13" refX="2" refY="6"
orient="auto">
<path d="M2,2 L2,11 L10,6 L2,2" />
</marker>
</defs>
<line x1="0" y1="0" x2="200" y2="100" class="arrow" />
</svg>
This just completely removes the draggable functionality of my div and I can't even begin to understand why. I will link to a full example as well.
https://codepen.io/ricodon1000/pen/XWmqxeB
If any additional information is needed please ask, I'm still learning how to post really good questions here. Thank you!
add a global style
svg{
background:red;
opacity:.5;
}
and you will see the SVG is covering the whole screen, thus blocking every element underneath
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
Hello I am writing a lib. for creating composition of texts, internal customisation. - d3-fusiontext.
I want to support
text-align: Justify
The user say provides me a long text. Mentions the height and width it would like to be rendered. The lib. wraps it up, and provides a good visual with wrapped texts. They are all svg text elements so that it can be exported too.
Now I would be to curious to know how the browser internally aligns in a justified manner? Any source/ links/ topics to start with. Any help/ guidance is highly appreciated.
This is a good example of how things might look.
codepen.io/anon/pen/zxNJKE
P.S: Sorry about no gh-pages and docs as the stuff is under dev. Will update.
Just a generalized curiosity how does the browser determines the spacings in justified alignment?
There are other answers on SO which provide information on how you can do text wrapping.
Word Wrap in Raphael JS / SVG
How to either determine SVG text box width, or force line breaks after 'x' characters?
Once you work out which characters/words fit on the line, you can use the textLength and lengthAdjust attributes to get SVG to stretch the line to fit the width.
<svg width="10cm" height="3cm" viewBox="0 0 1000 300"
xmlns="http://www.w3.org/2000/svg" version="1.1">
<line x1="200" y1="0" x2="200" y2="300" stroke="red"/>
<line x1="800" y1="0" x2="800" y2="300" stroke="red"/>
<text x="200" y="100"
font-family="Verdana" font-size="55" fill="blue" >
Hello, out there
</text>
<text x="200" y="170"
font-family="Verdana" font-size="55" fill="blue"
textLength="600" lengthAdjust="spacing">
Hello, out there
</text>
<text x="200" y="240"
font-family="Verdana" font-size="55" fill="blue"
textLength="600" lengthAdjust="spacingAndGlyphs">
Hello, out there
</text>
<!-- Show outline of canvas using 'rect' element -->
<rect x="1" y="1" width="998" height="298"
fill="none" stroke="blue" stroke-width="2" />
</svg>
How can I draw a line connecting 2 images using SVG?. For example I want to draw a line to connect $1 and $2 (assuming $1 and $2 are images):
$1
$2
And is Javascript required?
Thanks!
You can easily draw a line with SVG and position it between your images:
<img src="http://placehold.it/100x100">
<svg width="100" height="100" viewPort="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<line x1="0" y1="20" x2="100" y2="80" stroke-width="2" stroke="black" />
</svg>
<img src="http://placehold.it/100x100">
Try this :
<svg height="210" width="500">
<line x1="0" y1="0" x2="200" y2="200" style="stroke:rgb(255,0,0);stroke-width:2" />
</svg>
For more SVG tag info here
Note that SVG tag may not work properly on IE, Edge and Firefox
Also you can use jsPlumb library Here
You can Draw a line between the two images like
<img scr="http://www.belutics.com/wp-content/uploads/2016/01/sample-placeholder.png" alt="$1"/>
<svg height="210" width="500">
<line x1="0" y1="0" x2="200" y2="200" style="stroke:rgb(255,0,0);stroke-width:2" />
Sorry, your browser does not support inline SVG.
</svg>
<img scr="http://www.belutics.com/wp-content/uploads/2016/01/sample-placeholder.png" alt="$2"/>
and if you want to link line with images?
try to get it done with CSS relative property
you can find help here
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.