<div id="app"></div>
body {
font-family: Trebuchet MS, sans-serif;
}
.download-link {
color: black;
text-decoration: none;
background: white;
padding: 1rem;
border-radius: 5px;
margin: 1rem;
font-size: 2rem;
box-shadow: 0 6px 6px rgba(0,0,0,.4)
}
.download {
display: flex;
flex-wrap: wrap;
position: absolute;
bottom: 2rem;
left: 2rem;
}
const tartan = [
{ fill: "#FF8A00", size: 40 },
{ fill: "#E52E71", size: 10 },
{ fill: "#FFFFFF", size: 10 },
{ fill: "#E52E71", size: 70 },
{ fill: "#100e17", size: 20 },
{ fill: "#E52E71", size: 70 },
{ fill: "#FFFFFF", size: 10 },
{ fill: "#E52E71", size: 10 },
{ fill: "#FF8A00", size: 40 },
]
const SvgDefs = () => {
return (
<defs>
<pattern
id="diagonalStripes"
x="0"
y="0"
width="8"
height="8"
patternUnits="userSpaceOnUse"
>
<polygon points="0,4 0,8 8,0 4,0" fill="#ffffff" />
<polygon points="4,8 8,8 8,4" fill="#ffffff" />
</pattern>
<mask id="grating" x="0" y="0" width="1" height="1">
<rect
x="0"
y="0"
width="100%"
height="100%"
fill="url(#diagonalStripes)"
/>
</mask>
</defs>
)
}
const SvgTile = ({ tartan }) => {
const cumulativeSizes = tartan
.map(el => el.size)
.reduce(function(r, a) {
if (r.length > 0) a += r[r.length - 1]
r.push(a)
return r
}, [])
const size = cumulativeSizes[cumulativeSizes.length - 1]
return (
<svg
viewBox={`0 0 ${size} ${size}`}
width={size}
height={size}
x="0"
y="0"
xmlns="http://www.w3.org/2000/svg"
>
<SvgDefs />
<g id="horizStripes">
{tartan.map((el, index) => {
return (
<rect
fill={el.fill}
height={el.size}
width="100%"
x="0"
y={cumulativeSizes[index - 1] || 0}
/>
)
})}
</g>
<g id="vertStripes" mask="url(#grating)">
{tartan.map((el, index) => {
return (
<rect
fill={el.fill}
height="100%"
width={el.size}
x={cumulativeSizes[index - 1] || 0}
y="0"
/>
)
})}
</g>
</svg>
)
}
const SvgBg = ({ svgData }) => {
return (
<div
style={{
width: "100%",
height: "100vh",
backgroundImage: `url("data:image/svg+xml;utf8,${svgData}")`,
}}
/>
)
}
const SvgDownloadLink = ({ svgData, fileName }) => {
return (
<a
className="download-link"
download={`${fileName}.svg`}
href={`data:image/svg+xml;utf8,${svgData}`}
>
Download as SVG
</a>
)
}
const App = () => {
const tartanStr = ReactDOMServer.renderToStaticMarkup(<SvgTile tartan={tartan} />)
const tartanData = encodeURIComponent(tartanStr)
return (
<div className="App">
<SvgBg svgData={tartanData} />
<div className="download">
<SvgDownloadLink svgData={tartanData} fileName="CSSTricks"/>
</div>
</div>
)
}
const rootElement = document.getElementById("app")
ReactDOM.render(<App />, rootElement)
View Compiled
This Pen doesn't use any external CSS resources.