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>
Related
This question already has answers here:
How to resize a svg
(2 answers)
Closed 17 hours ago.
I have the below SVG which I am using as a mask to overlay on an image, I am trying to make the circle responsive, so it shrinks on mobile devices but haven't had any luck using view box etc as it removes the mask, I am also trying to position the shadow to the bottom right of the circle, but again I am having trouble making it responsive.
Any help would be greatly appreciated.
svg {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
}
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 2000 1000" preserveAspectRatio="xMidYMin slice">
<defs>
<mask id="mask" x="0" y="0">
<rect x="0" y="0" height="100%" width="100%" fill="#fff"/>
<circle cx="50%" cy="50%" r="250" />
</mask>
<pattern id="img" patternUnits="objectBoundingBox" x="0" y="0" width="100%" height="100%">
<image xlink:href="https://images.unsplash.com/photo-1507181179506-598491b53db4?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=299b6fae13eb39086f5bb28029c61760&auto=format&fit=crop&w=1778&q=80" width="100%" height="100%" preserveAspectRatio="xMidYMid slice" />
</pattern>
</defs>
<path id="Shadow" d="M462.231,0c19.593,38.355,29.045,88.448,36.926,138.3,9.125,75.59-104.323,237.333-194.755,250.24C246.323,389.921,51.569,371.964,0,313.148c46.559,91.147,141.283,153.59,250.655,153.59,155.395,0,281.365-125.97,281.365-281.365A280.22,280.22,0,0,0,462.231,0" opacity="0.2" />
<rect width="100%" height="100%" mask="url(#mask)" fill-opacity="1" fill="url(#img)" />
</svg>
Putting the path inside a g container allowed me to scale the shadow relative to the mask, hope this helps someone in the future.
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 500 500" preserveAspectRatio="xMidYMid slice">
<defs>
<mask id="mask" x="0" y="0">
<rect x="0" y="0" height="100%" width="100%" fill="#fff"/>
<circle cx="50%" cy="50%" r="16.5%" />
</mask>
<pattern id="img" patternUnits="objectBoundingBox" x="0" y="0" width="100%" height="100%">
<image xlink:href="https://images.unsplash.com/photo-1507181179506-598491b53db4?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=299b6fae13eb39086f5bb28029c61760&auto=format&fit=crop&w=1778&q=80" width="100%" height="100%" preserveAspectRatio="xMidYMid slice" />
</pattern>
</defs>
<g>
<path id="Shadow" d="m 462.231 0 c 19.593 38.355 29.045 88.448 36.926 138.3 c 9.125 75.59 -104.323 237.333 -194.755 250.24 c -58.079 1.381 -252.833 -16.576 -304.402 -75.392 c 46.559 91.147 141.283 153.59 250.655 153.59 c 155.395 0 281.365 -125.97 281.365 -281.365 a 280.22 280.22 0 0 0 -69.789 -185.373" opacity="0.2" style="transform: scale(0.3) translate(579px, 650px);" />
<rect width="100%" height="100%" mask="url(#mask)" fill-opacity="1" fill="url(#img)" />
</g>
</svg>
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>
I have three SVGs nested inside another SVG. The first one is supposed to be fluid and stretched out so preserveAspectRatio is none. The other two are set to 10% and 90% for the x value. But if you resize the page you'll see they have different distance from the left and right side. Why?
I'm expecting to see the left one having the same distance from left as the right one having the distance from right.
.box {
width: 60vw;
border: 1px dashed lightgray;
}
svg {
overflow: visible;
}
<div class="box">
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="50">
<svg viewBox="0 0 2 2" preserveAspectRatio="none">
<rect x="0" width="2" height="1" fill="#DDDDDD" />
</svg>
<svg x="10%" viewBox="0 0 20 20" preserveAspectRatio="xMinYMid">
<rect x="0" y="0" width="10" height="10" fill="#7FDBFF" />
</svg>
<svg x="90%" viewBox="0 0 20 20" preserveAspectRatio="xMinYMid">
<rect x="0" y="0" width="10" height="10" fill="#7FDBFF" />
</svg>
</svg>
</div>
Because you're starting to draw the second blue box at 90%, when you really want to end the draw at 90%. Fix this by setting the viewBox of the second blue box to:
viewBox="20 0 20 20"
Here's another solution.
The two blue SVGs are identical apart from their preserveAspectRatio attributes.
.box {
width: 60vw;
border: 1px dashed lightgray;
}
svg {
overflow: visible;
}
<div class="box">
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="50">
<svg viewBox="0 0 2 2" preserveAspectRatio="none">
<rect x="0" width="2" height="1" fill="#DDDDDD" />
</svg>
<svg x="10%" width="80%" height="100%" viewBox="0 0 10 20" preserveAspectRatio="xMinYMid">
<rect x="0" y="0" width="10" height="10" fill="#7FDBFF" />
</svg>
<svg x="10%" width="80%" height="100%" viewBox="0 0 10 20" preserveAspectRatio="xMaxYMid">
<rect x="0" y="0" width="10" height="10" fill="#7FDBFF" />
</svg>
</svg>
</div>
For anyone as confused as me, here is the problem:
If I set the viewBox x value to half of the width 10 / 2 = 5, then I technically panned the origin to the width's center.
.box {
width: 60vw;
border: 1px dashed lightgray;
}
svg {
overflow: visible;
}
<div class="box">
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="50">
<svg viewBox="0 0 2 2" preserveAspectRatio="none">
<rect x="0" width="2" height="1" fill="#DDDDDD" />
</svg>
<svg x="10%" viewBox="5 0 20 20" preserveAspectRatio="xMinYMid">
<rect x="0" y="0" width="10" height="10" fill="#7FDBFF" />
</svg>
<svg x="90%" viewBox="5 0 20 20" preserveAspectRatio="xMinYMid">
<rect x="0" y="0" width="10" height="10" fill="#7FDBFF" />
</svg>
</svg>
</div>
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>
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.