HTML, SVG, and Javascript with XML - DOMParser not reading every other element - javascript

I'm working on a program that saves and loads SVG data to and from an xml file and it does work, but for some reason whenever the DOMParser runs, every other element is not being read.
The XML file I am trying to read is formatted like this:
<?xml version="1.0" encoding="utf-8"?>
<marks>
<path xmlns="http://www.w3.org/2000/svg" class="mark" d="M736 264 L736 264 L736 264 L736 265 L736 268 L736 269 L736 272 L736 277 L736 280 L736 288 L736 304 L736 312 L737 318 L740 356 L740 364 L740 376 L741 398 L742 430 L742 474 L744 488" fill="none" stroke="#000000" stroke-width="2" id="A"></path>
<path xmlns="http://www.w3.org/2000/svg" class="mark" d="M1230 426 L1230 428 L1230 428 L1229 428 L1228 429 L1228 430 L1228 430 L1226 432 L1224 432 L1218 434 L1216 436 L1209 436 L1194 440 L1186 440 L1180 440 L1158 444 L1092 445 L1018 446 L928 446 L902 446" fill="none" stroke="#000000" stroke-width="2" id="AA"></path>
</marks>
In this example, the first element is not read but the second one is. Here's the javascript code:
var e = '<?xml version="1.0" encoding="utf-8"?><marks><path xmlns="http://www.w3.org/2000/svg" class="mark" d="M736 264 L736 264 L736 264 L736 265 L736 268 L736 269 L736 272 L736 277 L736 280 L736 288 L736 304 L736 312 L737 318 L740 356 L740 364 L740 376 L741 398 L742 430 L742 474 L744 488" fill="none" stroke="#000000" stroke-width="2" id="A"></path><path xmlns="http://www.w3.org/2000/svg" class="mark" d="M1230 426 L1230 428 L1230 428 L1229 428 L1228 429 L1228 430 L1228 430 L1226 432 L1224 432 L1218 434 L1216 436 L1209 436 L1194 440 L1186 440 L1180 440 L1158 444 L1092 445 L1018 446 L928 446 L902 446" fill="none" stroke="#000000" stroke-width="2" id="AA"></path></marks>';
var parser = new DOMParser();
var xmlDoc = parser.parseFromString(e, "text/xml");
console.log(xmlDoc);
Even at this point the XML is not being parsed correctly. Please let me know if you have a solution.

Try to use "application/xml" instead of "text/xml".

Related

How to align a group (instead of text) along a path in svg?

Lets assume I have programmatically created a circle and some text,
that I want to align along the circle.
I am able to do so using the textPath element.
In addition I have a rectangular image (or any svg group <g>),
that I also would like to align to the circle
(the red rectangle in the image below is just an example; actually I would like to be able to align arbitrary svg groups <g> as image labels on the nodes of a chord diagram.).
However, textPath only seems to work for text elements.
=> Is there something similar that works for group elements?
Or do I need to manually calculate the transformation for my group
(following from some tangent of the circle)?
(A workaround could be to create some hidden text with a single letter and
the same size as my group ... align it and grab its transformation. However, that feels ugly.)
In addition I have a rectangular image (or any svg group ), that I
also would like to align to the circle (see red rectangle in the
example image below).
However, textPath only seems to work for text elements.
You can use the rectangle unicode character ▮
In this case you will be able to include it in one textPath command along with other words
<svg width="400" height="400" viewBox="0 0 400 400">
<path id="pathChain" d="M87 199C87 114 141 64 200 64 258 64 310 122 313 199 315 273 258 335 200 335 141 335 87 279 87 199Z" style="fill:#089421;"/>
<text font-size="36" font-family="Times New Roman" fill="grey" >
<textPath id="result" startOffset="7%" xlink:href="#pathChain">
<tspan dx="0" dy="-5" fill="black" font-size="48px"> Hello World </tspan> <tspan dx="-20" dy="-10" fill="red" font-size="72px"> ▮</tspan>
</textPath>
</text>
</svg>
You can use any unicode character that suits you
<svg width="400" height="400" viewBox="0 0 400 400">
<path id="pathChain" d="M87 199C87 114 141 64 200 64 258 64 310 122 313 199 315 273 258 335 200 335 141 335 87 279 87 199Z" style="fill:#089421;"/>
<text font-size="36" font-family="Times New Roman" fill="grey" >
<textPath id="result" startOffset="7%" xlink:href="#pathChain">
<tspan dx="0" dy="-5" fill="black" font-size="48px"> Hello World </tspan> <tspan dx="-5" fill="red" font-size="72px"> ⮔</tspan>
</textPath>
</text>
</svg>
If necessary, you can make the animation of the letters
<svg width="400" height="400" viewBox="0 0 400 400">
<path id="pathChain" d="M87 199C87 114 141 64 200 64 258 64 310 122 313 199 315 273 258 335 200 335 141 335 87 279 87 199Z" style="fill:#089421;"/>
<text font-size="36" font-family="Times New Roman" fill="grey" >
<textPath id="result" xlink:href="#pathChain">
<tspan dx="0" dy="-5" fill="black" font-size="48px"> Hello World </tspan> <tspan dx="-5" fill="red" font-size="72px"> ⮔</tspan>
<animate dur="10s" repeatCount="5" attributeName="startOffset" values="5%;50%;50%;5%;5%"/>
</textPath>
</text>
</svg>
As #Paul LeBeau commented:
No there is no automatic way to do that. You have to position it
yourself
Consider adding svg images to text using absolute positioning
Since any text in SVG is a vector object, it has absolute coordinates x, y, as the first character of the word and the last.
Using this you can position an icon or any other vector image to the beginning or end of the text.
I put the icon in the <symbol> tag and position it at the end of the word using the <use> tag
<use xlink:href="#speaker" x="245" y="35" />
<svg width="400" height="400" viewBox="0 0 400 400">
<symbol>
<g id="speaker" style="transform-origin:center;transform-box: fill-box;transform:rotate(15deg);" >
<path fill="#089421" d="M28,7.1v2c7.3,1,13,7.3,13,14.9s-5.7,13.9-13,14.9v2c8.4-1,15-8.2,15-16.9S36.4,8.1,28,7.1z"/>
<path fill="#546E7A" d="M14,32H7c-1.1,0-2-0.9-2-2V18c0-1.1,0.9-2,2-2h7V32z"/>
<polygon fill="#78909C" points="26,42 14,32 14,16 26,6"/>
<path fill="#089421" d="M28,17.3v2.1c1.8,0.8,3,2.5,3,4.6s-1.2,3.8-3,4.6v2.1c2.9-0.9,5-3.5,5-6.7S30.9,18.2,28,17.3z"/>
<path fill="#089421" d="M28,12.2v2c4.6,0.9,8,5,8,9.8s-3.4,8.9-8,9.8v2c5.7-1,10-5.9,10-11.8S33.7,13.1,28,12.2z"/>
</g>
</symbol>
<path id="pathChain" d="M87 199C87 114 141 64 200 64 258 64 310 122 313 199 315 273 258 335 200 335 141 335 87 279 87 199Z" style="fill:#089421;"/>
<text font-size="36" font-family="Times New Roman" fill="grey" >
<textPath id="result" xlink:href="#pathChain">
<tspan dx="0" dy="-5" fill="black" font-size="48px"> Hello Wordl </tspan>
</textPath>
</text>
<use xlink:href="#speaker" x="245" y="35" />
</svg>
An example with a growing line on which text and an icon are located
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="400" viewBox="0 0 400 400" version="1">
<symbol id="grow">
<g>
<circle fill="#FF9800" cx="28" cy="9" r="5"/>
</g>
<path fill="#00796B" d="M29,27.3l-9.2-4.1c-1-0.5-1.5,1-2,2c-0.5,1-4.1,7.2-3.8,8.3c0.3,0.9,1.1,1.4,1.9,1.4c0.2,0,0.4,0,0.6-0.1 L28.8,31c0.8-0.2,1.4-1,1.4-1.8C30.2,28.4,29.7,27.6,29,27.3z"/>
<path fill="#009688" d="M26.8,15.2l-2.2-1c-1.3-0.6-2.9,0-3.5,1.3L9.2,41.1c-0.5,1,0,2.2,1,2.7c0.3,0.1,0.6,0.2,0.9,0.2 c0.8,0,1.5-0.4,1.8-1.1c0,0,9.6-13.3,10.4-14.9s4.9-9.3,4.9-9.3C28.7,17.4,28.2,15.8,26.8,15.2z"/>
<path fill="#FF9800" d="M40.5,15.7c-0.7-0.8-2-1-2.8-0.3l-5,4.2l-6.4-3.5c-1.1-0.6-2.6-0.4-3.3,0.9c-0.8,1.3-0.4,2.9,0.8,3.4 l8.3,3.4c0.3,0.1,0.6,0.2,0.9,0.2c0.5,0,0.9-0.2,1.3-0.5l6-5C41.1,17.8,41.2,16.6,40.5,15.7z"/>
<path fill="#FF9800" d="M11.7,23.1l3.4-5.1l4.6,0.6l1.5-3.1c0.4-0.9,1.2-1.4,2.1-1.5c-0.1,0-0.2,0-0.2,0h-9c-0.7,0-1.3,0.3-1.7,0.9 l-4,6c-0.6,0.9-0.4,2.2,0.6,2.8C9.2,23.9,9.6,24,10,24C10.6,24,11.3,23.7,11.7,23.1z"/>
</symbol>
<path id="txtPath" d="m22 366c0 0 59-24 74-50C132 253 129 213 128 161 125 33 200 2 200 2" style="fill:none;stroke:#00796B;stroke-width:3"/>
<use xlink:href="#grow" x="123" y="10" />
<text dx="0" dy="-10px" font-size="20" font-family="Times New Roman" fill="#414141" >
<textPath id="result" startOffset="5%" xlink:href="#txtPath"> Stock growth in the first half of the year </textPath>
</text>
</svg>
One more example
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="400" viewBox="0 0 400 400" version="1">
<symbol id="Cactus" style="transform-origin:center;transform-box: fill-box;transform:rotate(15deg);">
<path fill="#7CB342" d="M35.3,9.6c-1.6-0.2-1.3,0.9-1.9,2.7l-1,4.3c-0.3,1-0.7,1.4-2,1.3L25,17.3c-1.6-0.2-3.1,1-3.2,2.6 c-0.2,1.6,1,3.1,2.6,3.2l6.3,0.7c3,0.3,5.5-0.9,6-5.4c0,0,0.6-4.7,0.3-6.6C36.7,10.2,36.6,9.7,35.3,9.6z"/>
<path fill="#7CB342" d="M12.2,13.6c1.6-0.1,1.3,0.9,1.9,2.8l1.3,6.3c0.3,1,0.7,1.4,2,1.3l5.4-0.4c1.6-0.1,3,1.1,3.2,2.7 c0.1,1.6-1.1,3-2.7,3.2l-6.3,0.5c-3,0.2-5.5-1-5.9-5.5c0,0-0.8-6.7-0.5-8.5C10.7,14.2,10.8,13.7,12.2,13.6z"/>
<path fill="#8BC34A" d="M24,5c-2.4,0-4,0.6-4.5,3.2c0,0-2.1,16.9,0,32.1c0.3,3.2,2,1.2,4.4,1.2s3.8,2.7,4.4-0.8 c2.5-15.1,0-32.6,0-32.6C27.7,5.2,26.4,5,24,5z"/>
<path fill="#FFB74D" d="M38.8,43H9.2c0,0,4.9-2.3,14.8-2.3S38.8,43,38.8,43z"/>
</symbol>
<path id="txtPath" d="m200 2c0 0 36 31 57 42 15 8 34 6 47 16 15 11 26 27 33 43 8 18 2 41 11 58 9 17 41 40 41 40" fill="none" stroke="green" stroke-width="2"/>
<use xlink:href="#Cactus" x="355" y="150" />
<text font-size="20" font-family="Times New Roman" fill="grey" >
<textPath id="result" startOffset="7%" xlink:href="#txtPath">
<tspan dx="0" dy="-5" fill="black" >Decrease in stocks per year </tspan>
</textPath>
</text>
</svg>
As a starting point here is the workaround I mentioned.
It uses some invisible placeholder text and extracts the transformation information with
placeHolder.getBoundingClientRect();
and
placeHolder.getRotationOfChar(0);
The result is only an approximation that depends on the font size and on the character of the placeholder.
var svg = document.getElementById('svg');
var text = document.createElement('text');
text.setAttribute('fill','black');
svg.appendChild(text);
var placeHolder = document.getElementById('placeholder');
var placeHolderBounds = placeHolder.getBoundingClientRect();
var angle = placeHolder.getRotationOfChar(0);
var group = document.getElementById('my-group');
var groupBounds = group.getBoundingClientRect();
var dx = 0; //groupBounds.width/2;
var dy = -groupBounds.height;
var x = placeHolderBounds.x;
var y = placeHolderBounds.y;
var transform = 'translate(' + x +','+ y +') '+
'rotate('+ angle +') '+
'translate('+ dx +','+ dy +')';
group.setAttribute('transform', transform);
<svg id='svg' width="400" height="400" viewBox="0 0 400 400">
<path id="my-path" d="M87 199C87 114 141 64 200 64 258 64 310 122 313 199 315 273 258 335 200 335 141 335 87 279 87 199Z" style="fill:#089421;"/>
<g id="my-group">
<rect width="30" height="20" style="fill:red"/>
</g>
<text font-size="12px" >
<textPath startOffset="10%" xlink:href="#my-path">
<tspan>Hello World</tspan><tspan id='placeholder' visibility="hidden" >-</tspan>
</textPath>
</text>
</svg>

Svg path not closing correctly

I'm trying to create a bridge-like shape with an svg using javascript. With the following html I get the overall shape, but the close path is wrong:
<svg height="897" width="414" xmlns:xlink="http://www.w3.org/1999/xlink" viewbox="0 0 414 897">
<path stroke-width="3" stroke="blue" style="fill:transparent; fill-opacity: 1"
d="M 0 0 V 207 H 30
M 30 207 q 0 -177 177 -177
M 207 30 q 177 0 177 177
H 414 V 0 H 0 z">
</path>
</svg>
This produces the following shape:
It is closing in a strange way which means that it isn't filling correctly. The strange vertical line from the top of the arch to the top left shouldn't be there. How do I get it to close properly and fill properly?
The path will close from your last point to the last declared M. You can fix this by removing all the M calls except the first one. Since you are making a continuous line you don't need to move to a new point every time.
<svg height="897" width="414" xmlns:xlink="http://www.w3.org/1999/xlink" viewbox="0 0 414 897">
<path stroke-width="3" stroke="blue" style="fill:transparent; fill-opacity: 1"
d="M 0 0 V 207 H 30
q 0 -177 177 -177
q 177 0 177 177
H 414 V 0 H 0 z">
</path>
</svg>

How to get the DOM content as seen in inspect element window after rendering?

I am trying to get the SVG generated using MathJax using JS and animate it like here
In my code, I have
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
SVG: {
useGlobalCache: true,
useFontCache: false
}
})
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.4/MathJax.js?config=TeX-AMS_SVG"></script>
<div id="sup">$$a$$</div>
When I check the rendered DOM using inspect element, i get the contents of div with id sup as
<span class="MathJax_Preview" style="color: inherit; display: none;"></span>
<div class="MathJax_SVG_Display" style="text-align: center;">
<span style="font-size: 100%; display: inline-block; position: relative;" class="MathJax_SVG" id="MathJax-Element-1-Frame" tabindex="0" data-mathml="<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><mi>a</mi></math>" role="presentation">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" width="1.23ex" height="1.454ex" style="vertical-align: -0.227ex;" viewBox="0 -528.2 529.5 625.9" role="img" focusable="false" aria-hidden="true">
<g stroke="currentColor" fill="currentColor" stroke-width="0" transform="matrix(1 0 0 -1 0 0)">
<path stroke-width="1" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path>
</g>
</svg>
<span class="MJX_Assistive_MathML MJX_Assistive_MathML_Block" role="presentation">
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><mi>a</mi></math>
</span>
</span>
</div>
<script type="math/tex; mode=display" id="MathJax-Element-1">a</script>
But when I try to get the innerHTML of the div with id sup using
window.addEventListener('load', function(){
console.log(document.getElementById("sup").innerHTML);
})
I get $$a$$ as output.
How can I get the output same as that shown in inspect element?
Your problem is that MathJax is never loaded when you console.log on window.load.
First, you need to wait until MathJax is loaded and rendered in order to get the desired output result.
I've found This question which might help you
The way to synchronize with MathJax's startup actions it to register a StartupHook that will fire when the startup is complete. For example, you can use
MathJax.Hub.Register.StartupHook("End",function () {
console.log(document.getElementById("sup").innerHTML);
});

Why is HTML5 text measuring with offsetWidth giving two different results for Arabic text at two different points in time

I just logged these values for measuring Arabic text with el.offsetWidth:
t1 t2
-----
35 87 "بِسْمِ بِسْمِ"
77 114 "بِسْمِ ٱللَّهِ ٱللَّهِ"
150 224 "بِسْمِ ٱللَّهِ ٱلرَّحْمَنِ ٱلرَّحْمَنِ"
215 279 "بِسْمِ ٱللَّهِ ٱلرَّحْمَنِ ٱلرَّحِيمِ ٱلرَّحِيمِ"
221 227 "بِسْمِ ٱللَّهِ ٱلرَّحْمَنِ ٱلرَّحِيمِ ‎ ‎"
281 341 "بِسْمِ ٱللَّهِ ٱلرَّحْمَنِ ٱلرَّحِيمِ ‎ ٱلْحَمْدُ ٱلْحَمْدُ"
312 344 "بِسْمِ ٱللَّهِ ٱلرَّحْمَنِ ٱلرَّحِيمِ ‎ ٱلْحَمْدُ لِلَّهِ لِلَّهِ"
351 390 "بِسْمِ ٱللَّهِ ٱلرَّحْمَنِ ٱلرَّحِيمِ ‎ ٱلْحَمْدُ لِلَّهِ رَبِّ رَبِّ"
429 508 "بِسْمِ ٱللَّهِ ٱلرَّحْمَنِ ٱلرَّحِيمِ ‎ ٱلْحَمْدُ لِلَّهِ رَبِّ ٱلْعَلَمِينَ ٱلْعَلَمِينَ"
436 442 "بِسْمِ ٱللَّهِ ٱلرَّحْمَنِ ٱلرَّحِيمِ ‎ ٱلْحَمْدُ لِلَّهِ رَبِّ ٱلْعَلَمِينَ ‎ ‎"
509 582 "بِسْمِ ٱللَّهِ ٱلرَّحْمَنِ ٱلرَّحِيمِ ‎ ٱلْحَمْدُ لِلَّهِ رَبِّ ٱلْعَلَمِينَ ‎ ٱلرَّحْمَنِ ٱلرَّحْمَنِ"
573 122 "ٱلرَّحِيمِ ٱلرَّحِيمِ"
64 70 "ٱلرَّحِيمِ ‎ ‎"
112 161 "ٱلرَّحِيمِ ‎ مَلِكِ مَلِكِ"
149 185 "ٱلرَّحِيمِ ‎ مَلِكِ يَوْمِ يَوْمِ"
204 260 "ٱلرَّحِيمِ ‎ مَلِكِ يَوْمِ ٱلدِّينِ ٱلدِّينِ"
211 217 "ٱلرَّحِيمِ ‎ مَلِكِ يَوْمِ ٱلدِّينِ ‎ ‎"
258 305 "ٱلرَّحِيمِ ‎ مَلِكِ يَوْمِ ٱلدِّينِ ‎ إِيَّاكَ إِيَّاكَ"
304 350 "ٱلرَّحِيمِ ‎ مَلِكِ يَوْمِ ٱلدِّينِ ‎ إِيَّاكَ نَعْبُدُ نَعْبُدُ"
362 420 "ٱلرَّحِيمِ ‎ مَلِكِ يَوْمِ ٱلدِّينِ ‎ إِيَّاكَ نَعْبُدُ وَإِيَّاكَ وَإِيَّاكَ"
443 524 "ٱلرَّحِيمِ ‎ مَلِكِ يَوْمِ ٱلدِّينِ ‎ إِيَّاكَ نَعْبُدُ وَإِيَّاكَ نَسْتَعِينُ نَسْتَعِينُ"
449 456 "ٱلرَّحِيمِ ‎ مَلِكِ يَوْمِ ٱلدِّينِ ‎ إِيَّاكَ نَعْبُدُ وَإِيَّاكَ نَسْتَعِينُ ‎ ‎"
501 553 "ٱلرَّحِيمِ ‎ مَلِكِ يَوْمِ ٱلدِّينِ ‎ إِيَّاكَ نَعْبُدُ وَإِيَّاكَ نَسْتَعِينُ ‎ ٱهْدِنَا ٱهْدِنَا"
571 132 "ٱلصِّرَطَ ٱلصِّرَطَ"
159 254 "ٱلصِّرَطَ ٱلْمُسْتَقِيمَ ٱلْمُسْتَقِيمَ"
165 171 "ٱلصِّرَطَ ٱلْمُسْتَقِيمَ ‎ ‎"
221 278 "ٱلصِّرَطَ ٱلْمُسْتَقِيمَ ‎ صِرَطَ صِرَطَ"
277 332 "ٱلصِّرَطَ ٱلْمُسْتَقِيمَ ‎ صِرَطَ ٱلَّذِينَ ٱلَّذِينَ"
348 419 "ٱلصِّرَطَ ٱلْمُسْتَقِيمَ ‎ صِرَطَ ٱلَّذِينَ أَنْعَمْتَ أَنْعَمْتَ"
408 468 "ٱلصِّرَطَ ٱلْمُسْتَقِيمَ ‎ صِرَطَ ٱلَّذِينَ أَنْعَمْتَ عَلَيْهِمْ عَلَيْهِمْ"
445 481 "ٱلصِّرَطَ ٱلْمُسْتَقِيمَ ‎ صِرَطَ ٱلَّذِينَ أَنْعَمْتَ عَلَيْهِمْ غَيْرِ غَيْرِ"
547 650 "ٱلصِّرَطَ ٱلْمُسْتَقِيمَ ‎ صِرَطَ ٱلَّذِينَ أَنْعَمْتَ عَلَيْهِمْ غَيْرِ ٱلْمَغْضُوبِ ٱلْمَغْضُوبِ"
607 114 "عَلَيْهِمْ عَلَيْهِمْ"
85 116 "عَلَيْهِمْ وَلَا وَلَا"
165 246 "عَلَيْهِمْ وَلَا ٱلضَّآلِّينَ ٱلضَّآلِّينَ"
172 178 "عَلَيْهِمْ وَلَا ٱلضَّآلِّينَ ‎ ‎"
203 235 "عَلَيْهِمْ وَلَا ٱلضَّآلِّينَ ‎ الٓمٓ الٓمٓ"
210 216 "عَلَيْهِمْ وَلَا ٱلضَّآلِّينَ ‎ الٓمٓ ‎ ‎"
256 302 "عَلَيْهِمْ وَلَا ٱلضَّآلِّينَ ‎ الٓمٓ ‎
The code is essentially this:
var measurer = document.createElement('span')
document.body.appendChild(measurer)
var strings = [
'arabic string 1...',
'arabic string 2...',
...
]
next()
function next() {
var string = strings.shift()
var s1 = measure(string)
setTimeout(function(){
var s2 = measure(string)
console.log(s1, s2, string)
next()
}, 300)
}
function measure(string) {
measurer.innerHTML = string
return measurer.offsetWidth
}
Why is it doing this? Why is the final value "after I've waited for a little while" usually greater than the initially calculated offsetWidth value? How do I accurately calculate these?
I wasn't able to reproduce your findings (using a simplified version of your code with a sample of the strings you provided).
const measurer = document.createElement('span');
document.body.appendChild(measurer);
const strings = [
"بِسْمِ ٱللَّهِ ٱلرَّحْمَنِ ٱلرَّحْمَنِ",
"بِسْمِ ٱللَّهِ ٱلرَّحْمَنِ ٱلرَّحِيمِ ‎ ٱلْحَمْدُ لِلَّهِ رَبِّ ٱلْعَلَمِينَ ‎ ٱلرَّحْمَنِ ٱلرَّحْمَنِ",
"ٱلرَّحِيمِ ‎ مَلِكِ يَوْمِ ٱلدِّينِ ‎ إِيَّاكَ نَعْبُدُ نَعْبُدُ",
"ٱلصِّرَطَ ٱلْمُسْتَقِيمَ ‎ صِرَطَ ٱلَّذِينَ ٱلَّذِينَ"
];
console.log("t1 t2 string\n--------------------------");
strings.forEach(next);
function next(str) {
const s1 = measure(str);
setTimeout( () => console.log(s1, measure(str), str), 300);
}
function measure(string) {
measurer.innerHTML = string;
return measurer.offsetWidth;
}

How can this path stroke set the opacity of the group behind it?

I have this code which shows my current output when the snippet is run.
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 300 300" viewBox="0 0 300 300" x="0px" y="0px" xmlns:xml="http://www.w3.org/XML/1998/namespace" xml:space="preserve" version="1.1">
<g fill-opacity=".2">
<path fill="#f79820" d="M 150 0 c 82.8 0 150 67.2 150 150 s -67.2 150 -150 150 S 0 232.8 0 150 S 67.2 0 150 0" />
<circle fill="#f5f4b7" cx="150" cy="150" r="141.9" />
<path fill="#f79820" d="M 135.7 103.3 c 3.5 18.3 4 19 7.8 19.2 c 3.8 0.2 10.4 -4.1 13.6 -12.1 c 3.1 -8 5 -20.2 7.8 -27.9 s 15.4 -29.6 18.7 -39.2 s 0.2 -19.2 -3.1 -23.6 c -3.3 -4.4 -10.7 -4.4 -23.5 -3.4 c -12.7 1 -33.4 -0.1 -40.8 3.4 c -8.4 3.9 -12.1 4.8 -8.9 15.5 C 110.2 45.9 132.2 84.9 135.7 103.3 Z" />
<path fill="#f79820" d="M 153.9 124.2 c -1.7 2.9 3.3 5.6 5.3 5.6 c 2 0 10.1 -2.9 23 -10.4 c 12.9 -7.5 49.9 -25.1 60.2 -35.2 c 10.2 -10 4.3 -22.8 0 -28.9 c -4.3 -6.1 -21 -22.8 -34.4 -29.7 c -13.4 -7 -16.7 1.2 -19.2 12.4 c -2.5 11.2 -12.1 31.1 -15.4 38.2 C 170 83.4 155.5 121.3 153.9 124.2 Z" />
<path fill="#f79820" d="M 213.5 108.7 c -23.7 12.8 -50.5 24.7 -50.4 27.2 c 0.1 3.1 11.1 6.5 27.4 9.9 c 16.4 3.4 29.1 2.5 44.6 9 c 15.5 6.5 36.7 9.9 45 -5.4 s 0.5 -47.6 -8.3 -58.1 c -8.8 -10.5 -10.9 -15.1 -25.6 -3.6 C 240.8 92 227.6 101.1 213.5 108.7 Z" />
<path fill="#f79820" d="M 283.6 167.2 c -2.2 -8.7 -11.1 1.4 -55.9 -8.5 c -44.8 -9.9 -60.7 -13.6 -63 -10.2 c -1.3 1.9 13.4 14.1 36 25.1 c 22.5 11 34.6 21.6 43.7 27.9 c 9.1 6.3 20.2 6.3 26.9 0 C 278.1 195.2 285.8 175.8 283.6 167.2 Z" />
<path fill="#f79820" d="M 226.6 194.7 c -16 -3.6 -35.4 -19 -42.1 -23.8 c -6.8 -4.8 -21.2 -17.1 -25.4 -13.3 c -2.6 2.4 -0.7 15.6 8.4 38.7 s 18.7 56.7 21.6 73.6 c 3 16.8 10.9 9.5 19 2.5 c 8.1 -7 26.4 -21.4 40 -30.7 c 13.6 -9.3 11.6 -19 10.1 -21.7 S 242.6 198.2 226.6 194.7 Z" />
<path fill="#f79820" d="M 157.9 178.9 c -4.1 -13.1 -5.2 -20.5 -9 -20.4 c -4.5 0.2 -9.1 18.7 -12.4 27.4 c -3.3 8.7 -12.7 52.3 -16.7 72.4 c -4 20 -1.8 25.8 15.2 26.7 s 36.7 4.9 42.8 -1 c 6.1 -5.9 5.3 -23.1 0 -44.5 C 172.5 217.9 161.9 192 157.9 178.9 Z" />
<path fill="#f79820" d="M 135.5 171.9 c 2.5 -9.2 3.2 -13.5 -2 -14.3 c -7.1 -1 -17.5 10.5 -25.3 22.1 S 77.5 213.4 63 228.7 c -14.5 15.3 -4 23.8 16 36.2 c 20 12.4 27.9 13.8 31.6 10.9 c 3.6 -2.9 6.6 -26.3 11.1 -43.8 C 126.1 214.4 133 181.1 135.5 171.9 Z" />
<path fill="#f79820" d="M 61.1 227.1 c 5.1 -6.8 32.2 -34.3 40 -44.8 c 7.8 -10.5 26.3 -28.2 27.9 -29.2 c 1.7 -1 -1.1 -4 -3.8 -6.8 c -2.1 -2.1 -2.8 -1.2 -11.1 0 c -8.3 1.2 -39 13.4 -53.4 17.7 c -14.4 4.2 -22.5 3.9 -31.1 7.5 c -8.6 3.6 -11.7 12.4 -1.7 26.8 c 10.1 14.4 6.3 18.9 13.6 28.9 C 48.9 237.1 56 233.9 61.1 227.1 Z" />
<path fill="#f79820" d="M 25.8 169.4 c 9.1 -1 41.5 -11.6 59.2 -18.9 c 17.7 -7.3 40.9 -11.4 40.7 -13.9 c -0.5 -5.6 -29.9 -17 -40.5 -22.6 c -10.6 -5.6 -25 -19.9 -35.4 -25.1 c -10.4 -5.3 -23.3 -4.8 -25.4 8.2 c -2.1 12.9 -8.8 27.9 -11.4 48 C 10.2 165.1 16.7 170.4 25.8 169.4 Z" />
<path fill="#f79820" d="M 54.5 88.3 c 16 5.4 37.5 19.7 43.1 24 c 5.6 4.2 31.2 20.9 35.2 17.5 c 3.4 -2.9 0.3 -21.1 -6.3 -31.8 c -6.6 -10.7 -9.1 -29.4 -14.5 -45.2 c -5.5 -15.8 -17.7 -28.4 -34 -18 s -33.4 24.8 -37.8 36 C 35.7 82 38.5 82.9 54.5 88.3 Z" />
</g>
<svg style="display: block; width: 100%;" viewBox="0 0 100 100">
<path stroke="#f79820" stroke-opacity=".4" fill-opacity="0" style="stroke-dasharray: 157.698, 157.698; stroke-dashoffset: 55;" stroke-width="49.81" d="M 50,50 m 0,-25.095 a 25.095,25.095 0 1 1 0,50.19 a 25.095,25.095 0 1 1 0,-50.19" />
</svg>
</svg>
My goal is to get everything covered by the stroke to be shown "darker" than the remaining portion of the circle. However the effect that is happening is the opacity of the stroke is compounding with the groups opacity so it doesn't have the contrast it needs to have.
Ideally it would look something like this...
Would inverting the pieces be an option? Instead of darkening the section, lighten the inverse? I removed the fill-opacity on the outer svg, changed the stroke of the inner path to white and increased the opacity to .6. I did not change the path, though, this was just to demonstrate the concept.
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 300 300" viewBox="0 0 300 300" x="0px" y="0px" xmlns:xml="http://www.w3.org/XML/1998/namespace" xml:space="preserve" version="1.1">
<g>
<path fill="#f79820" d="M 150 0 c 82.8 0 150 67.2 150 150 s -67.2 150 -150 150 S 0 232.8 0 150 S 67.2 0 150 0" />
<circle fill="#f5f4b7" cx="150" cy="150" r="141.9" />
<path fill="#f79820" d="M 135.7 103.3 c 3.5 18.3 4 19 7.8 19.2 c 3.8 0.2 10.4 -4.1 13.6 -12.1 c 3.1 -8 5 -20.2 7.8 -27.9 s 15.4 -29.6 18.7 -39.2 s 0.2 -19.2 -3.1 -23.6 c -3.3 -4.4 -10.7 -4.4 -23.5 -3.4 c -12.7 1 -33.4 -0.1 -40.8 3.4 c -8.4 3.9 -12.1 4.8 -8.9 15.5 C 110.2 45.9 132.2 84.9 135.7 103.3 Z" />
<path fill="#f79820" d="M 153.9 124.2 c -1.7 2.9 3.3 5.6 5.3 5.6 c 2 0 10.1 -2.9 23 -10.4 c 12.9 -7.5 49.9 -25.1 60.2 -35.2 c 10.2 -10 4.3 -22.8 0 -28.9 c -4.3 -6.1 -21 -22.8 -34.4 -29.7 c -13.4 -7 -16.7 1.2 -19.2 12.4 c -2.5 11.2 -12.1 31.1 -15.4 38.2 C 170 83.4 155.5 121.3 153.9 124.2 Z" />
<path fill="#f79820" d="M 213.5 108.7 c -23.7 12.8 -50.5 24.7 -50.4 27.2 c 0.1 3.1 11.1 6.5 27.4 9.9 c 16.4 3.4 29.1 2.5 44.6 9 c 15.5 6.5 36.7 9.9 45 -5.4 s 0.5 -47.6 -8.3 -58.1 c -8.8 -10.5 -10.9 -15.1 -25.6 -3.6 C 240.8 92 227.6 101.1 213.5 108.7 Z" />
<path fill="#f79820" d="M 283.6 167.2 c -2.2 -8.7 -11.1 1.4 -55.9 -8.5 c -44.8 -9.9 -60.7 -13.6 -63 -10.2 c -1.3 1.9 13.4 14.1 36 25.1 c 22.5 11 34.6 21.6 43.7 27.9 c 9.1 6.3 20.2 6.3 26.9 0 C 278.1 195.2 285.8 175.8 283.6 167.2 Z" />
<path fill="#f79820" d="M 226.6 194.7 c -16 -3.6 -35.4 -19 -42.1 -23.8 c -6.8 -4.8 -21.2 -17.1 -25.4 -13.3 c -2.6 2.4 -0.7 15.6 8.4 38.7 s 18.7 56.7 21.6 73.6 c 3 16.8 10.9 9.5 19 2.5 c 8.1 -7 26.4 -21.4 40 -30.7 c 13.6 -9.3 11.6 -19 10.1 -21.7 S 242.6 198.2 226.6 194.7 Z" />
<path fill="#f79820" d="M 157.9 178.9 c -4.1 -13.1 -5.2 -20.5 -9 -20.4 c -4.5 0.2 -9.1 18.7 -12.4 27.4 c -3.3 8.7 -12.7 52.3 -16.7 72.4 c -4 20 -1.8 25.8 15.2 26.7 s 36.7 4.9 42.8 -1 c 6.1 -5.9 5.3 -23.1 0 -44.5 C 172.5 217.9 161.9 192 157.9 178.9 Z" />
<path fill="#f79820" d="M 135.5 171.9 c 2.5 -9.2 3.2 -13.5 -2 -14.3 c -7.1 -1 -17.5 10.5 -25.3 22.1 S 77.5 213.4 63 228.7 c -14.5 15.3 -4 23.8 16 36.2 c 20 12.4 27.9 13.8 31.6 10.9 c 3.6 -2.9 6.6 -26.3 11.1 -43.8 C 126.1 214.4 133 181.1 135.5 171.9 Z" />
<path fill="#f79820" d="M 61.1 227.1 c 5.1 -6.8 32.2 -34.3 40 -44.8 c 7.8 -10.5 26.3 -28.2 27.9 -29.2 c 1.7 -1 -1.1 -4 -3.8 -6.8 c -2.1 -2.1 -2.8 -1.2 -11.1 0 c -8.3 1.2 -39 13.4 -53.4 17.7 c -14.4 4.2 -22.5 3.9 -31.1 7.5 c -8.6 3.6 -11.7 12.4 -1.7 26.8 c 10.1 14.4 6.3 18.9 13.6 28.9 C 48.9 237.1 56 233.9 61.1 227.1 Z" />
<path fill="#f79820" d="M 25.8 169.4 c 9.1 -1 41.5 -11.6 59.2 -18.9 c 17.7 -7.3 40.9 -11.4 40.7 -13.9 c -0.5 -5.6 -29.9 -17 -40.5 -22.6 c -10.6 -5.6 -25 -19.9 -35.4 -25.1 c -10.4 -5.3 -23.3 -4.8 -25.4 8.2 c -2.1 12.9 -8.8 27.9 -11.4 48 C 10.2 165.1 16.7 170.4 25.8 169.4 Z" />
<path fill="#f79820" d="M 54.5 88.3 c 16 5.4 37.5 19.7 43.1 24 c 5.6 4.2 31.2 20.9 35.2 17.5 c 3.4 -2.9 0.3 -21.1 -6.3 -31.8 c -6.6 -10.7 -9.1 -29.4 -14.5 -45.2 c -5.5 -15.8 -17.7 -28.4 -34 -18 s -33.4 24.8 -37.8 36 C 35.7 82 38.5 82.9 54.5 88.3 Z" />
</g>
<svg style="display: block; width: 100%;" viewBox="0 0 100 100">
<path stroke="#ffffff" stroke-opacity=".6" fill-opacity="0" style="stroke-dasharray: 157.698, 157.698; stroke-dashoffset: 55;" stroke-width="49.81" d="M 50,50 m 0,-25.095 a 25.095,25.095 0 1 1 0,50.19 a 25.095,25.095 0 1 1 0,-50.19" />
</svg>
</svg>

Categories

Resources