-
-
Notifications
You must be signed in to change notification settings - Fork 260
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use a circular clipPath to mask flags #11
Comments
Love it! By the way (and please don't let this side-note derail the focus of this issue! 😄), it should be possible to avoid some repetition in the human-readable form by using <rect y="0" x="0" height="512" width="512" fill="#eeeeee"/> <!-- White background -->
<g fill="#d80027"> <!-- Red stripes -->
<rect y="64" x="0" height="64" width="512"/>
<rect y="192" x="0" height="64" width="512"/>
<rect y="320" x="0" height="64" width="512"/>
<rect y="448" x="0" height="64" width="512"/>
</g> with a repeating pattern in the <pattern id="stripes" width="512" height="128" patternUnits="userSpaceOnUse">
<rect x="0" y="0" width="512" height="64" fill="#eeeeee"/> <!-- White stripe -->
<rect x="0" y="64" width="512" height="64" fill="#d80027"/> <!-- Red stripe -->
</pattern> and then filling the entire rectangle with it: <rect y="0" x="0" height="512" width="512" fill="url(#stripes)"/> <!-- Stripes --> Something similar could be done for the stars, avoiding the multiple clones + translations. But again, these are just possible optimizations we could consider in the future :) for now, using the circle mask is already a nice improvement! |
Another possible improvement for the future is to make sure the geometry of the flags works without the circular mask, i.e. with the flags as actual square icons. Of course, this should not sacrifice the aesthetics of the circular form, which should remain the primary representation. |
To be honest, I had a vague recollection of that functionality existing, but had never used it until the experiments that led to my comment above. I'm still learning about the syntax — MDN's reference and tutorial docs have been useful so far for that.
Apologies, that was indeed why I made that comment. In usual "obvious once you figured it out" fashion, it didn't occur to me that the rationale wouldn't be clear without context. It's exactly as you put it :) |
As a follow-up to this, and for clarification, do you think flags that don't require a mask should be given one? To choose one of the simplest examples, Japan's flag requires just two circle elements and is 165 bytes minified: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<circle cx="256" cy="256" r="256" fill="#eee"/>
<circle cx="256" cy="256" r="112" fill="#d80027"/>
</svg> But with the clipPath it's <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<defs>
<clipPath id="circle-mask">
<circle r="256" cy="256" cx="256"/>
</clipPath>
</defs>
<g clip-path="url(#circle-mask)">
<!--
EDIT: Forgot to use a rect instead of a circle. This reduces the minified size to 196 bytes.
<circle cx="256" cy="256" r="256" fill="#eee"/>
-->
<rect x="0" y="0" width="512" height="512" fill="#eee"/>
<circle cx="256" cy="256" r="112" fill="#d80027"/>
</g>
</svg> In a perfect world, SVGO would surely compress either of these SVG files down to the same 165 bytes. But I guess it just doesn't support removing redundant clipPaths. Maybe I should look into writing a plugin for SVGO. |
Hmm, that's a good point. I suppose we might have to decide whether we want to prioritize consistency and semantic clarity of the design definitions — as well as the extensibility to square/squircle icons (the latter being a common trend in icons lately), as opposed to maximum compactness of the resulting images. Perhaps unsurprisingly, I'm tempted to side with the former over the latter, especially since a total of bites in the order of hundreds is still a pretty small payload, and even orders of magnitude more compact than the equivalent PNG even in small resolutions (I tested saving a 32x32 PNG of the Japanese flag image, and even after compressing it with That said, if we do want to keep the maximum compression possible, maybe we could add some custom logic to the optimization process — for example, storing both a canonical source A plugin for SVGO sounds pretty dope, actually! It would be a nice solution, but I must point out that it would only work if we hardcode circles for the background shape, which would prevent other icon shapes. (Not saying it's a deal-breaker, but I do find the possibility quite interesting.) |
Btw, I haven't tested this, but perhaps we could reuse the mask code from a single file, so that we don't have to repeat the same code in all files? That would also help with the compactness angle. I found an article saying that something like this is possible for |
What about if we didn't use Square iconsA border radius of <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="border-radius: 0%">
<rect x="0" y="0" width="512" height="512" fill="#eee"/>
<circle cx="256" cy="256" r="112" fill="#d80027"/>
</svg> Rounded square iconsA border radius of <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="border-radius: 25%">
<rect x="0" y="0" width="512" height="512" fill="#eee"/>
<circle cx="256" cy="256" r="112" fill="#d80027"/>
</svg> Circle iconsA border radius of <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="border-radius: 50%">
<rect x="0" y="0" width="512" height="512" fill="#eee"/>
<circle cx="256" cy="256" r="112" fill="#d80027"/>
</svg> One drawback to this approach is of course that applying custom masks (such as a squircle) is no longer possible. A squircle can (hypothetically) be made with pure CSS, but it's far more verbose than just using a |
In my recent experiments with
|
The One caveat of using I tried adding a |
Oh damn, nice catch! I thought the
Thanks for going to such lengths looking for a solution. You are right that this seems to be a browser bug. Strange that it renders incorrectly in both Chrome and Firefox. I get the same results on my end. |
No problem :) I'll respond there.
Yeah, it's possible that it's been reported; otherwise, we should probably do so to make sure it's addressed eventually. It's not the first edge case I've found while trying to do smarter stuff with SVGs (some of the experiments I did with , as mentioned above did produce inconsistent and IMO erroneous results, too). I just haven't found the energy to prepare a proper report. In the meantime, we should be fine working with |
Hey @waldyrious, sorry it's taken me so long to get back to you. Just to keep you in the loop, @climech's PR #18 (also related: #19) has effectively resolved this issue, i.e., applying a circular mask to all flags. So it's probably safe to close this issue now. @climech opted for using |
@HatScripts, thanks! The new flags show up correctly in GitHub: I have also tried embedding them in my application and they look square too (native app). |
Hello, @Shatur95! Some more details would be appreciated. What system was this observed on, and what kind of rendering library was used to display the images in your application? The files validate against the W3 (SVG 1.1) spec, but I suppose it's up to the libraries to adhere to it 😞 Also, can you save the following 3 snippets as separate files and test if anything changes? 1.svg: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<defs>
<mask id="a">
<circle cx="256" cy="256" r="256" fill="#fff"/>
</mask>
</defs>
<g mask="url(#a)">
<path fill="#0052b4" d="M0 0h144.7l36 254.6-36 257.4H0z"/>
<path fill="#d80027" d="M367.3 0H512v512H367.3l-29.7-257.3z"/>
<path fill="#ffda44" d="M144.7 0h222.6v512H144.7z"/>
<path fill="#d80027" d="M256 354.5V256h66.8v47.3zm-66.8-165.3H256V256h-66.8z"/>
<path fill="#ff9811" d="M289.4 167a22.3 22.3 0 0 0-33.4-19.3 22.1 22.1 0 0 0-11.1-3c-12.3 0-22.3 10-22.3 22.3H167v111.3c0 41.4 32.9 65.4 58.7 77.8a22.1 22.1 0 0 0-3 11.2 22.3 22.3 0 0 0 33.3 19.3 22.1 22.1 0 0 0 11.1 3 22.3 22.3 0 0 0 19.2-33.5c25.8-12.4 58.7-36.4 58.7-77.8V167zm22.3 111.3c0 5.8 0 23.4-27.5 40.9a136.5 136.5 0 0 1-28.2 13.3c-7-2.4-17.8-6.7-28.2-13.3-27.5-17.5-27.5-35.1-27.5-41v-77.9h111.4z"/>
</g>
</svg> 2.svg: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<clipPath id="a">
<circle cx="256" cy="256" r="256"/>
</clipPath>
<g clip-path="url(#a)">
<path fill="#0052b4" d="M0 0h144.7l36 254.6-36 257.4H0z"/>
<path fill="#d80027" d="M367.3 0H512v512H367.3l-29.7-257.3z"/>
<path fill="#ffda44" d="M144.7 0h222.6v512H144.7z"/>
<path fill="#d80027" d="M256 354.5V256h66.8v47.3zm-66.8-165.3H256V256h-66.8z"/>
<path fill="#ff9811" d="M289.4 167a22.3 22.3 0 0 0-33.4-19.3 22.1 22.1 0 0 0-11.1-3c-12.3 0-22.3 10-22.3 22.3H167v111.3c0 41.4 32.9 65.4 58.7 77.8a22.1 22.1 0 0 0-3 11.2 22.3 22.3 0 0 0 33.3 19.3 22.1 22.1 0 0 0 11.1 3 22.3 22.3 0 0 0 19.2-33.5c25.8-12.4 58.7-36.4 58.7-77.8V167zm22.3 111.3c0 5.8 0 23.4-27.5 40.9a136.5 136.5 0 0 1-28.2 13.3c-7-2.4-17.8-6.7-28.2-13.3-27.5-17.5-27.5-35.1-27.5-41v-77.9h111.4z"/>
</g>
</svg> 3.svg: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<defs>
<clipPath id="a">
<circle cx="256" cy="256" r="256"/>
</clipPath>
</defs>
<g clip-path="url(#a)">
<path fill="#0052b4" d="M0 0h144.7l36 254.6-36 257.4H0z"/>
<path fill="#d80027" d="M367.3 0H512v512H367.3l-29.7-257.3z"/>
<path fill="#ffda44" d="M144.7 0h222.6v512H144.7z"/>
<path fill="#d80027" d="M256 354.5V256h66.8v47.3zm-66.8-165.3H256V256h-66.8z"/>
<path fill="#ff9811" d="M289.4 167a22.3 22.3 0 0 0-33.4-19.3 22.1 22.1 0 0 0-11.1-3c-12.3 0-22.3 10-22.3 22.3H167v111.3c0 41.4 32.9 65.4 58.7 77.8a22.1 22.1 0 0 0-3 11.2 22.3 22.3 0 0 0 33.3 19.3 22.1 22.1 0 0 0 11.1 3 22.3 22.3 0 0 0 19.2-33.5c25.8-12.4 58.7-36.4 58.7-77.8V167zm22.3 111.3c0 5.8 0 23.4-27.5 40.9a136.5 136.5 0 0 1-28.2 13.3c-7-2.4-17.8-6.7-28.2-13.3-27.5-17.5-27.5-35.1-27.5-41v-77.9h111.4z"/>
</g>
</svg> |
I use KDE Plasma. My application written in Qt framework that should support SVG 1.1.
Tested, looks same: |
Oh, it looks like Qt just not support |
@Shatur95 Could you please test the following? <svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" style="border-radius: 50%">
<path fill="#0052b4" d="M0 0h144.7l36 254.6-36 257.4H0z"/>
<path fill="#d80027" d="M367.3 0H512v512H367.3l-29.7-257.3z"/>
<path fill="#ffda44" d="M144.7 0h222.6v512H144.7z"/>
<path fill="#d80027" d="M256 354.5V256h66.8v47.3zm-66.8-165.3H256V256h-66.8z"/>
<path fill="#ff9811" d="M289.4 167a22.3 22.3 0 0 0-33.4-19.3 22.1 22.1 0 0 0-11.1-3c-12.3 0-22.3 10-22.3 22.3H167v111.3c0 41.4 32.9 65.4 58.7 77.8a22.1 22.1 0 0 0-3 11.2 22.3 22.3 0 0 0 33.3 19.3 22.1 22.1 0 0 0 11.1 3 22.3 22.3 0 0 0 19.2-33.5c25.8-12.4 58.7-36.4 58.7-77.8V167zm22.3 111.3c0 5.8 0 23.4-27.5 40.9a136.5 136.5 0 0 1-28.2 13.3c-7-2.4-17.8-6.7-28.2-13.3-27.5-17.5-27.5-35.1-27.5-41v-77.9h111.4z"/>
</svg> In the meantime I'll draft a new release v2.0.0 so that you can revert back to v1.0.0 if you like. |
Same here. But not problem, there is no issue here. The icons conform to SVG 1.1 and Qt implementation conform to Tiny 1.2, so rounding just not supported by Qt.
Yes, it would be nice if you draft a new release. |
Hmm, that is very strange. So even the
Done :) |
Yes, I double checked it. It looks square both in the system and in the Qt application.
Thanks! |
Per waldyrious's suggestion on #8, here are some experiments with converting flags to use a circular
<clipPath>
. This helps to avoid having longer than necessary<path d="...">
s, and generally makes the code more human readable. It also seems to result in smaller files when minified with svgo (For these examples I'm using svgo 1.3.2; the latest release at the time of writing).We also trying to avoid the anti-aliasing/color-bleeding issues described here and on the graphic design SE.
Russia
Original (302 bytes minified):
New (298 bytes minified):
United States
Original (836 bytes minified):
16px, 24px, 32px, 48px (zoomed to 400%)
New (784 bytes minified):
16px, 24px, 32px, 48px (zoomed to 400%)
The text was updated successfully, but these errors were encountered: