SVG pattern with viewBox display differently in Safari and Chrome - google-chrome

Following svg segment defines a graph with major/minor lines. It behaves as expected in Chrome. But the ending minor line mis-aligned with major line for each square. Any idea why?
<svg width="8in" height="11in" viewBox="0 0 960 1320">
<defs>
<pattern id="smallGrid" width="12" height="12" patternUnits="userSpaceOnUse">
<path d="M 12 0 L 0 0 0 12" fill="none" stroke="gray" stroke-width="0.5"></path>
</pattern>
<pattern id="grid12" width="120" height="120" patternUnits="userSpaceOnUse">
<rect width="120" height="120" fill="url(#smallGrid)"></rect>
<path d="M 120 0 L 0 0 0 120" fill="none" stroke="blue" stroke-width="1"></path>
</pattern>
</defs>
<rect fill="white" height="800" width="800" y="0"></rect>
<rect fill="url(#grid12)" height="360" width="360" y="0"></rect>
</svg>

Related

Firefox, Chrome: svg mask is missing in sprite symbol

everyone!
I have some SVG image with mask (for expamle):
<svg width="173" height="173" viewBox="0 0 173 173" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<mask id="mask0_42_56" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="61" y="65" width="50" height="43">
<rect x="61" y="65" width="50" height="43" rx="12" fill="#C4C4C4"/>
</mask>
</defs>
<rect width="173" height="173" rx="16" fill="#F2F3F7"/>
<g opacity="0.5">
<g mask="url(#mask0_42_56)">
<rect x="61" y="65" width="50" height="43" rx="0" fill="#C4C4C4"/>
<path d="M100.062 80.3574C102.651 80.3574 104.75 78.2947 104.75 75.7502C104.75 73.2058 102.651 71.1431 100.062 71.1431C97.4736 71.1431 95.3749 73.2058 95.3749 75.7502C95.3749 78.2947 97.4736 80.3574 100.062 80.3574Z"
fill="#6C6C6C"/>
<path d="M99.3574 90.5753C98.0109 89.2622 95.8359 89.2336 94.4531 90.5101L82.875 101.207V111.071H108.656C109.951 111.071 111 110.048 111 108.786V101.929L99.3574 90.5753Z"
fill="#6C6C6C"/>
<path d="M104.75 111.071L78.0929 84.4931C76.6965 83.1008 74.441 83.0706 73.0069 84.424L61 95.7654V108.648C61 109.987 62.0877 111.071 63.4306 111.071H104.75Z"
fill="#6C6C6C"/>
</g>
</g>
</svg>
I wanna bundle all of svg images on my project in one svg-sprite. I use simple gulp script for this, a lot of images displayed correctly. But images who contain mask displayed without mask. Mask id and attributes with using mask id match. The root of the incorrect display just in than symbol doesn't see mask with this id.
I have solution for Firefox. Move mask tag with chilren from symbol tag in parent svg tag.
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<mask id="ara" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="61" y="65" width="50" height="43">
<rect x="61" y="65" width="50" height="43" rx="12" fill="#C4C4C4"/>
</mask>
</defs>
<symbol fill="none" viewBox="0 0 173 173" id="empty-cover" xmlns="http://www.w3.org/2000/svg">
<rect width="173" height="173" rx="16" fill="#F2F3F7"/>
<g mask="url(#ara)" opacity="0.5">
<rect x="61" y="65" width="50" height="43" rx="0" fill="#C4C4C4"/>
<path d="M100.062 80.357c2.589 0 4.688-2.062 4.688-4.607 0-2.544-2.099-4.607-4.688-4.607-2.588 0-4.687 2.063-4.687 4.607 0 2.545 2.099 4.607 4.687 4.607zM99.357 90.575a3.582 3.582 0 00-4.904-.065l-11.578 10.697v9.864h25.781c1.295 0 2.344-1.023 2.344-2.285v-6.857L99.357 90.575z"
fill="#6C6C6C"/>
<path d="M104.75 111.071L78.093 84.493a3.656 3.656 0 00-5.086-.069L61 95.765v12.883a2.426 2.426 0 002.43 2.423h41.32z"
fill="#6C6C6C"/>
</g>
</symbol>
This solution doesn't work for Chrome.
I tried to move mask to parent tag like in Firefox solution.
And I tried put mask to both places: root svg tag and symbol.

SVG patterns for a dash and cross symbols

I'm trying to achieve the following graph using SVG patterns:
The only one I could do is the first one:
.patterns { display: flex;}
<div style="position: absolute; width: 0; height: 0;">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<pattern id="pattern1" width="10" height="10" patternTransform="rotate(45 0 0)" patternUnits="userSpaceOnUse">
<line x1="0" y1="0" x2="0" y2="10" style="stroke:#04A484; stroke-width:1" />
</pattern>
<pattern id="pattern2" patternUnits="userSpaceOnUse">
</pattern>
<pattern id="pattern3" patternUnits="userSpaceOnUse">
</pattern>
</defs>
</svg>
</div>
<div class="patterns">
<svg xmlns="http://www.w3.org/2000/svg" height="100%" width="100%">
<rect width="25px" height="100px" fill="url(#pattern1)"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" height="100%" width="100%">
<rect width="25px" height="100px" fill="url(#pattern2)"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" height="100%" width="100%">
<rect width="25px" height="100px" fill="url(#pattern3)"/>
</svg>
</div>
Borders are not an issue, since I'm using a charts library that only needs the SVG pattern.
How can I achieve the other two patterns ?
Thanks in advance.
There's a slight problem with your diagonal shading. Since the line is dawn from (0,0) to (0,10), it lies on the edge of the SVG rendering area, so half of it will be hidden. That's why your lines look rather thin. You can fix that by offsetting the line slightly so that you keep everything visible.
The other patterns aren't hard to make. There's no need to apply any sort of rotation; just find a unit pattern that repeats the way you want. For the second of the three patterns, one of the horizontal lines has to travel across the edge of the pattern unit. To fix this, I broke this line into two parts; one aligned with the left edge of the pattern block, and one aligned with the right edge; i.e. M15 4 20 4M0 4 5 4 instead of M15 4 25 4, which would end up 5 pixels past the right edge of the 20×32 pattern block.
(Note: I'm using <path> elements to draw the lines, because they're a bit easier to type in. <path d="M1 2 3 4M5 6 7 8"/> is equivalent to <line x1="1" y1="2" x2="3" y2="4"/><line x1="5" y1="6" x2="7" y2="8"/>.)
.patterns { display: flex;}
<div style="position: absolute; width: 0; height: 0;">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<pattern id="pattern1" width="8" height="8" patternTransform="rotate(45)" patternUnits="userSpaceOnUse">
<path d="M3 0 3 8" style="stroke:#25a08b; stroke-width:2" />
</pattern>
<pattern id="pattern2" width="20" height="32" patternUnits="userSpaceOnUse">
<path d="M0 28 10 28M5 20 15 20M10 12 20 12M15 4 20 4M0 4 5 4" style="stroke:#b2b6c1; stroke-width:2" />
</pattern>
<pattern id="pattern3" width="20" height="32" patternUnits="userSpaceOnUse">
<path d="M1 8 9 8M5 4 5 12M11 24 19 24M15 20 15 28" style="stroke:#0c2160; stroke-width:2" />
</pattern>
</defs>
</svg>
</div>
<div class="patterns">
<svg xmlns="http://www.w3.org/2000/svg" height="100%" width="100%">
<rect x="1" y="1" width="28" height="98" fill="url(#pattern1)" stroke="#25a08b" stroke-width="2"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" height="100%" width="100%">
<rect x="1" y="1" width="28" height="98" fill="url(#pattern2)" stroke="#b2b6c1" stroke-width="2"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" height="100%" width="100%">
<rect x="1" y="1" width="28" height="98" fill="url(#pattern3)" stroke="#0c2160" stroke-width="2"/>
</svg>
</div>

Animating an SVG pattern background

I'm currently designing a new website with NextJS and Tailwind and I would like to make a background that is infinitely translating to the bottom right, just like in this example (but with my own pattern):
https://codepen.io/kootoopas/pen/reyqg
I've actually never worked with SVG patterns before. Though I've managed to display an SVG pattern as follows, I can't seem to find how to animate it.
The SVG is displayed in a flexbox div like so:
<div className="opacity-50 absolute inset-0 scale-150">
<svg width="100%" height="100%">
<defs>
<pattern id="p" width="100" height="100" patternUnits="userSpaceOnUse">
<path id="a" data-color="fill" fill="#FFF" d="M0 50v50h50C22.386 100 0 77.614 0 50zM100 50C72.386 50 50 27.614 50 0v50h50zM50 25V0C22.386 0 0 22.386 0 50h25c0-13.807 11.193-25 25-25zM100 75V50c-27.614 0-50 22.386-50 50h25c0-13.807 11.193-25 25-25zM25 50c0 13.807 11.193 25 25 25V50H25zM75 0c0 13.807 11.193 25 25 25V0H75z"></path>
</pattern>
</defs>
<rect fill="#EEB400" width="100%" height="100%"></rect>
<rect fill="url(#p)" width="100%" height="100%"></rect>
</svg>
</div>
I've tried to apply CSS classes, custom React components on it, with no avail.
Thank you very much for your time :)
<svg width="100%" height="100%">
<defs>
<pattern id="p" width="100" height="100" patternUnits="userSpaceOnUse">
<path data-color="fill" fill="#FFF" d="M0 50v50h50C22.386 100 0 77.614 0 50zM100 50C72.386 50 50 27.614 50 0v50h50zM50 25V0C22.386 0 0 22.386 0 50h25c0-13.807 11.193-25 25-25zM100 75V50c-27.614 0-50 22.386-50 50h25c0-13.807 11.193-25 25-25zM25 50c0 13.807 11.193 25 25 25V50H25zM75 0c0 13.807 11.193 25 25 25V0H75z"></path>
<animateTransform attributeName="patternTransform" type="translate" by="100 100" dur="10s" repeatCount="indefinite"></animateTransform>
</pattern>
</defs>
<rect fill="#EEB400" width="100%" height="100%"></rect>
<rect fill="url(#p)" width="100%" height="100%"></rect>
</svg>

Image not centering in SVG arc (HTML)

The background picture is not centering behind my SVG circle arc. You can see the image:
I want something like this:
obviously without the red cut part.
My HTML is as follows:
<svg width="200" height="200">
<defs>
<pattern id="image" x="0" y="0" width="1" height="1">
<image x="0%" y="0%" width="100%" height="100%" xlink:href="Assets/Images/RoundSlider.png"></image>
</pattern>
</defs>
<g transform="translate(100,100)" stroke="black" stroke-width="2">
<path d="M 0 0 -70 70 A 99 99 0 1 0 -70 -70 Z" fill="url(#image)" />
</g>
</svg>
This happens because your path's bounding box actually starts more on the right than if it were a full circle:
const bbox = document.querySelector('path').getBBox();
const rect = document.querySelector('rect');
rect.setAttribute('x', bbox.x);
rect.setAttribute('y', bbox.y);
rect.setAttribute('width', bbox.width);
rect.setAttribute('height', bbox.height);
<h3>The red rectangle represents your <path> BBox.</h3>
<svg width="200" height="200">
<g transform="translate(100,100)" stroke="black" stroke-width="2" fill="none">
<path d="M 0 0 -70 70 A 99 99 0 1 0 -70 -70 Z"/>
<rect stroke="red"/>
<circle stroke="green" r="100" cx="0" cy="0"/>
</g>
</svg>
So you can simply adjust your image's x attribute so it takes this offset into account (assuming you got a square image):
<svg width="200" height="200">
<defs>
<pattern id="image" width="1" height="1">
<!--
#mypath.getBBox().x = -70
Add 100 from translate(100, 100)
and we got our 30 units offset
-->
<image x="-30" y="0" width="200" height="200" xlink:href="https://upload.wikimedia.org/wikipedia/commons/9/95/Clock-green.png"/>
</pattern>
</defs>
<g transform="translate(100,100)" stroke="red" stroke-width="2">
<path id="mypath" d="M 0 0 -70 70 A 99 99 0 1 0 -70 -70 Z" fill="url(#image)"/>
</g>
</svg>
Or you could also just display this <image> and clip it (might be easier with more complex pathes):
<svg width="200" height="200">
<defs>
<clipPath id="myclip">
<use xlink:href="#mypath"/>
</clipPath>
</defs>
<image x="0" y="0" width="200" height="200" xlink:href="https://upload.wikimedia.org/wikipedia/commons/9/95/Clock-green.png" clip-path="url(#myclip)"/>
<path id="mypath" d="M 0 0 -70 70 A 99 99 0 1 0 -70 -70 Z" fill="transparent" transform="translate(100,100)" stroke="red" stroke-width="2"/>
</svg>

HTML5 grid sizing

I am creating an HTML5 grid for a website. The grid looks the way I would like it to, however in each "big" square, there are 10 smaller squares. I need there to be only 5 squares in each "big" square. I am not proficient in HTML5 and am not sure how to even word the question, hopefully someone understands what I am trying to do here.
HERE is the site: http://www.webexplosive.com/sms_test/piermap.html
and HERE is my grid code:
<div style="width: 902px; height: 602px; position: absolute; left: 0px; top: 86px;">
<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="minorGrid" width="10" height="10" patternUnits="userSpaceOnUse">
<path d="M 10 0 L 0 0 0 10" fill="none" stroke="#FF4444" stroke-width="0.5"/>
</pattern>
<pattern id="grid" width="100" height="100" patternUnits="userSpaceOnUse">
<rect width="100" height="100" fill="url(#minorGrid)"/>
<path d="M 100 0 L 0 0 0 100" fill="none" stroke="red" stroke-width="4"/>
</pattern>
</defs>
<rect width="100%" height="100%" fill="url(#grid)" />
</svg>
</div>
Look at this:
http://jsfiddle.net/cBXER/
<div style="width: 902px; height: 602px; position: absolute; left: 0px; top: 86px;">
<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="minorGrid" width="20" height="20" patternUnits="userSpaceOnUse">
<path d="M 20 0 L 0 0 0 20" fill="none" stroke="#FF4444" stroke-width="0.5"/>
</pattern>
<pattern id="grid" width="100" height="100" patternUnits="userSpaceOnUse">
<rect width="100" height="100" fill="url(#minorGrid)"/>
<path d="M 100 0 L 0 0 0 100" fill="none" stroke="red" stroke-width="4"/>
</pattern>
</defs>
<rect width="100%" height="100%" fill="url(#grid)" />
</svg>
</div>
You need to change your minor grid width, height and path d values to 20 because 20 is one-fifth of 100.