SVG code efficiency - html
So, I've been asked to create a static SVG file, and have been told to use <defs> and <use> to make it more efficient.
I understand there is code repetition but I'm not sure how to go about reducing what I have and still being able to have the same output.
Here is the code:
<!DOCTYPE html>
<html>
<body>
<center>
<h1>Static SVG</h1>
<svg width="200" height="200">
<!--transforming the group of shapes so that the origin is at the center of the svg image-->
<g transform="translate(100,100)">
<!--This is effectively the background-->
<rect x="-100" y="-100" width="200" height="200" style="fill:grey" />
<!--Inner rounded rectangle-->
<rect x="-40" y="-40" rx="5" ry="5" width="80" height="80" style="fill:black" />
<!--Four inner-most short arrows-->
<polygon points="0,-60 10,-50 0,-55 -10,-50" style="fill:black;stroke:lime;stroke-width:1" />
<polygon points="60,0 50,-10 55,0 50,10" style="fill:black;stroke:lime;stroke-width:1" />
<polygon points="-60,0 -50,10 -55,0 -50,-10" style="fill:black;stroke:lime;stroke-width:1" />
<polygon points="0,60 10,50 0,55 -10,50" style="fill:black;stroke:lime;stroke-width:1" />
<!--Middle short arrows-->
<polygon points="0,-80 10,-70 0,-75 -10,-70" style="fill:red;stroke:black;stroke-width:1" />
<polygon points="80,0 70,-10 75,0 70,10" style="fill:red;stroke:black;stroke-width:1" />
<polygon points="-80,0 -70,10 -75,0 -70,-10" style="fill:red;stroke:black;stroke-width:1" />
<polygon points="0,80 10,70 0,75 -10,70" style="fill:red;stroke:black;stroke-width:1" />
<!--Outer-most short arrows-->
<polygon points="0,-100 10,-90 0,-95 -10,-90" style="fill:lime;stroke:black;stroke-width:1" />
<polygon points="100,0 90,-10 95,0 90,10" style="fill:lime;stroke:black;stroke-width:1" />
<polygon points="-100,0 -90,10 -95,0 -90,-10" style="fill:lime;stroke:black;stroke-width:1" />
<polygon points="0,100 10,90 0,95 -10,90" style="fill:lime;stroke:black;stroke-width:1" />
<!--Longer Arros positioned diagonally from origin-->
<polygon points="40,50 50,50 50,40 60,60" style="fill:yellow;stroke:black;stroke-width:1" />
<polygon points="-50,-40 -50,-50 -40,-50 -60,-60" style="fill:yellow;stroke:black;stroke-width:1" />
<polygon points="50,-40 50,-50 40,-50 60,-60" style="fill:yellow;stroke:black;stroke-width:1" />
<polygon points="-50,40 -50,50 -40,50 -60,60" style="fill:yellow;stroke:black;stroke-width:1" />
<!--The elliptical shape in the centre of the rounded Square-->
<ellipse cx="0" cy="0" rx="20" ry="40" style="fill:white" />
</g>
</svg>
</center>
</body>
</html>
You're drawing the same polygons for the most part albeit rotated and positioned differently.
Along with moving their styles into a class, you can use defs and use like this:
<defs>
<!-- Define your shape here once -->
<polygon points="0,-60 10,-50 0,-55 -10,-50"
class="inner-arrow" id="inner-arrow" />
</defs>
<!-- Reuse multiple times
with the rotation (and translation if needed) handled by transform -->
<use xlink:href="#inner-arrow" />
<use xlink:href="#inner-arrow" transform="rotate(90)" />
<use xlink:href="#inner-arrow" transform="rotate(180)" />
<use xlink:href="#inner-arrow" transform="rotate(270)" />
Here's a DEMO that has the first inner arrows' code updated.
You can use and reuse symbols, which can have individual viewBoxes and be rotated and scaled like groups. The units in the symbols are proportional to the viewBox.
Here is a JSFiddle with your arrows coded and grouped using symbols:
<svg width="200" height="200" viewBox="0 0 200 200">
<defs>
<symbol id="sm_arrow" viewBox="0 0 20 10">
<polygon points="10,0 20,10 10,5 0,10" />
</symbol>
<symbol id="lg_arrow" viewBox="0 0 200 200">
<polygon points="0,10 10,10 10,0 20,20" />
</symbol>
<symbol id="triple_arrow" viewBox="0 5 200 10">
<use xlink:href="#sm_arrow"/>
<use xlink:href="#sm_arrow" transform="translate(0,20)" />
<use xlink:href="#sm_arrow" transform="translate(0,40)" />
</symbol>
<symbol id="arrows" viewBox="0 0 200 200">
<g id="small_arrows">
<use xlink:href="#triple_arrow" transform="translate(0,-90)" />
<use xlink:href="#triple_arrow" transform="translate(290,0) rotate(90)" />
<use xlink:href="#triple_arrow" transform="translate(200,290) rotate(180)" />
<use xlink:href="#triple_arrow" transform="translate(-90,200) rotate(-90)" />
</g>
<g id="long_arrows" transform="translate(60,60)">
<use xlink:href="#lg_arrow" transform="translate(80,80)" />
<use xlink:href="#lg_arrow" transform="translate(0,80) rotate(90)" />
<use xlink:href="#lg_arrow" transform="rotate(180)" />
<use xlink:href="#lg_arrow" transform="translate(80,0) rotate(-90)" />
</g>
</symbol>
<g id="background">
<rect width="200" height="200"/>
<rect x="60" y="60" rx="5" ry="5" width="80" height="80"/>
<ellipse cx="100" cy="100" rx="20" ry="40"/>
</g>
</defs>
<use xlink:href="#background"/>
<use xlink:href="#arrows"/>
</svg>
The styles were transferred to a CSS block or file:
polygon {
stroke-width: 1;
}
#triple_arrow use:nth-child(1) {
fill:black;
stroke:lime;
}
#triple_arrow use:nth-child(2) {
fill: red;
stroke: black;
}
#triple_arrow use:nth-child(3) {
fill: lime;
stroke: black;
}
#lg_arrow {
fill:yellow;
stroke:black;
}
#background rect:nth-child(1) {
fill:grey;
}
#background rect:nth-child(2) {
fill:black;
}
#background ellipse {
fill:white;
}
Related
SVG text not horizontally center aligning
I generated a SVG using Adobe XD. They use transform for positioning things but the text in my mini computer screen is not always the same width (it is dynamically generated). I have tried anchored, anything I could find but it still didn't work. This is how it looks with the current code: Here is the code: <svg xmlns="http://www.w3.org/2000/svg" width="903.5" height="860.5" viewBox="0 0 1200 1041"> <g transform="translate(-397)"> <g transform="translate(507 975)" fill="#fff" stroke="#707070" strokeWidth="1" > <rect width="907" height="66" rx="33" stroke="none" /> <rect x="0.5" y="0.5" width="906" height="65" rx="32.5" fill="none" /> </g> <rect width="119" height="395" transform="translate(901 613)" fill="#fff" /> <g transform="translate(397)" fill="#232323" stroke="#fff" stroke-width="30" > <rect width="1127" height="627" rx="103" stroke="none" /> <rect x="15" y="15" width="1097" height="597" rx="88" fill="none" /> </g> <text fill="white" fontSize="96" fontFamily="Fredoka" > {screenText} </text> </g> </svg>
You can use transform/translate, text-anchor and dominant-baseline to place a text in the middle of something. body { background: gray; } <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 1041"> <g transform="translate(600 975)" fill="#fff" stroke="#707070" stroke-width="1"> <rect x="-453.5" width="907" height="66" rx="33" stroke="none" /> <rect x="-454" y="0.5" width="906" height="65" rx="32.5" fill="none" /> </g> <rect width="119" height="395" transform="translate(545.5 613)" fill="#fff" /> <g transform="translate(50)" fill="#232323" stroke="#fff" stroke-width="30"> <rect width="1127" height="627" rx="103" stroke="none" /> <rect x="15" y="15" width="1097" height="597" rx="88" fill="none" /> </g> <text fill="#fff" font-size="96" font-family="Fredoka" transform="translate(600 300)" text-anchor="middle" dominant-baseline="middle"> {screenText} </text> </svg>
Thanks to Buhan Yu's comment I learned that you need to specify x and y to center align it. I set x="50%" and it worked!
How to control the SVG animation which is based in CSS using JQuery?
I wanted to sync the svg animation altogether, getting stuck with initializing multiple variables, and many of the groups have both paths as well as lines, and I want to make it follow according to the order, Its just going above my ahead, I just did it for letter "W", and want to initialize O,R,L,D and all other variables altogether so it animates one after the other, or you have a better method to do the same. HTML Code <g id="W-World" stroke="#003668" stroke-width="2" fill="none"> <line x1="0.93" y1="0.482" x2="3.873" y2="7.937" clip-path="url(#clip-path-47)" /> <line x1="3.088" y1="7.937" x2="5.966" y2="0.482" clip-path="url(#clip-path-46)" /> <line x1="3.481" y1="0.482" x2="6.424" y2="7.937" clip-path="url(#clip-path-45)" /> <line x1="5.639" y1="7.937" x2="8.517" y2="0.482" clip-path="url(#clip-path-44)" /> </g> JQuery Code let W = document.querySelector("#W-World").querySelectorAll("line") W.forEach((l, i) => { l.setAttribute("style", `animation-delay:${i*1}s`) }) The main thing is like after the W loads completely, I want to initiate the animation for O then R and so on for rest of the other letters, because some groups have lines and paths both, so I am very much confused how to proceed. CodePen: https://codepen.io/ToxifiedM/pen/MWKeERr Original Question: How Can I Make SVG Text Animation Seamless And Accurate? Linked Question 1: A JQuery Function For SVG, To Execute 2nd Animation As Soon As, 1st Animation Completes? Linked Question 2: To Control The Speed Of Multiple SVG Elements Using Jquery?
I'm demonstrating it only for the world group hoping you'll be able to do it for all the letters. This is how I would do it: I'm putting all the shapes in a group and I'm selecting those paths with document.querySelector("#world").querySelectorAll("*"); where the asterix * is selecting all the elements inside the group: lines, paths... Instead of setting the stroke-dasharray and the stroke-dashoffset in css I'm seting them as presentational attributes and since I'm using javascript I'm calculating those values and setting those attributes in javascript: let totalLength = s.getTotalLength(); s.setAttribute("stroke-dasharray",totalLength); s.setAttribute("stroke-dashoffset",totalLength); Where s is the svg shape. let world = document.querySelector("#world").querySelectorAll("*"); let speed = 1;//change this to change the speed of the animation world.forEach((s,i)=>{ let totalLength = s.getTotalLength(); s.setAttribute("stroke-dasharray",totalLength); s.setAttribute("stroke-dashoffset",totalLength); s.setAttribute("style", `animation-delay:${i*speed}s`) }) svg { width: 400px; left: 50%; transform: translate(50%); } #world *{ animation: letter-animation 1s linear forwards; } #keyframes letter-animation { 100% { stroke-dashoffset: 0; } } <svg id="WOYP" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 39.219 29.466"> <defs> <clipPath id="clip-path-36"> <path id="D2" d="M44.294,14.5v.076h0V14.6h0v.018h0v.018h0v.018h0v.019a3.616,3.616,0,0,1-.231,1.064,3.245,3.245,0,0,1-.731,1.139,3.8,3.8,0,0,1-1.277.836,4.856,4.856,0,0,1-1.876.327H39.061v-.59c.184.013.385.019.6.019h.558a3.588,3.588,0,0,0,1.455-.259,2.444,2.444,0,0,0,.927-.684,2.569,2.569,0,0,0,.487-.953,4.119,4.119,0,0,0,.139-.884v-.032h0v-.016h0v-.017h0V14.6h0v-.017h0v-.138a3.254,3.254,0,0,0-.148-.874,2.553,2.553,0,0,0-.487-.891,2.627,2.627,0,0,0-.886-.669,3.089,3.089,0,0,0-1.347-.264h-.707c-.123,0-.241,0-.35,0s-.19.008-.245.015v-.581h1.308a5.084,5.084,0,0,1,1.467.187,3.963,3.963,0,0,1,1.058.478,2.776,2.776,0,0,1,.71.66,3.453,3.453,0,0,1,.424.741,3.321,3.321,0,0,1,.21.7,3.623,3.623,0,0,1,.056.514h0v.006h0v.006h0v.006h0v.006h0V14.5Z" style="fill: none;clip-rule: evenodd" /> </clipPath> <clipPath id="clip-path-37" transform="translate(-5.561 -10.291)"> <path id="D1" d="M39.157,18.037H37.938a.56.56,0,0,0,.191-.176.493.493,0,0,0,.071-.277V11.639a.464.464,0,0,0-.262-.453h1.219v6.851Z" style="fill: none;clip-rule: evenodd" /> </clipPath> <clipPath id="clip-path-38"> <path id="L2" data-name="L2" d="M35.564,18.021H32.72v-.494c.11.014.262.031.455.051a4.959,4.959,0,0,0,.651.02q.465,0,.776-.015a2.383,2.383,0,0,0,.527-.076.907.907,0,0,0,.362-.186,1.374,1.374,0,0,0,.279-.358Z" style="fill: none;clip-rule: evenodd" /> </clipPath> <clipPath id="clip-path-39" transform="translate(-5.561 -10.291)"> <path id="L1" data-name="L1" d="M32.8,17.527v.494H31.559a.6.6,0,0,0,.206-.176.463.463,0,0,0,.076-.277V11.623a.46.46,0,0,0-.282-.453H33.07a.506.506,0,0,0-.2.171.486.486,0,0,0-.076.282v5.9Z" style="fill: none;clip-rule: evenodd" /> </clipPath> <clipPath id="clip-path-40"> <path id="R3" data-name="R3" d="M25.583,14.284a12.176,12.176,0,0,1,1.264.061c.174,0,.556.37.6.434a1.35,1.35,0,0,1,.181.215c.054.08.1.148.14.2l.591,1.012q.12.21.246.412c.083.136.165.266.245.392s.158.238.231.339.138.183.192.246a1.077,1.077,0,0,0,.192.174,1.933,1.933,0,0,0,.214.131,1.976,1.976,0,0,0,.244.118l-1.046.007a.772.772,0,0,1-.51-.162,1.449,1.449,0,0,1-.322-.336c-.254-.4-.476-.757-.67-1.08s-.376-.631-.549-.923c-.067-.1-.132-.209-.2-.314a1.767,1.767,0,0,0-.2-.276.941.941,0,0,0-.259-.2.712.712,0,0,0-.34-.083l-.366,0h-.245v-.366Z" style="fill: none;clip-rule: evenodd" /> </clipPath> <clipPath id="clip-path-41"> <path id="R2" data-name="R2" d="M26.822,14.608a11.217,11.217,0,0,1-1.588.027h-.016V14.2c.067,0,.138,0,.211.009s.149.013.241.016.195.005.311.005a1.457,1.457,0,0,0,.673-.138,1.226,1.226,0,0,0,.419-.341,1.263,1.263,0,0,0,.213-.434,1.607,1.607,0,0,0,.061-.395v0a1.656,1.656,0,0,0-.061-.395,1.258,1.258,0,0,0-.213-.433,1.215,1.215,0,0,0-.419-.341,1.457,1.457,0,0,0-.673-.138c-.116,0-.22,0-.311,0s-.172.009-.241.015-.144.011-.211.011v-.46h.619c.485,0,.93.04.985.046h0a1.961,1.961,0,0,1,.457.126,1.838,1.838,0,0,1,.528.327,1.789,1.789,0,0,1,.41.525,1.487,1.487,0,0,1,.159.588v.025h0c0,.029,0,.057,0,.085v.03c0,.028,0,.056,0,.085h0v.024h0a1.487,1.487,0,0,1-.159.589,1.785,1.785,0,0,1-.41.524,1.838,1.838,0,0,1-.528.327,1.907,1.907,0,0,1-.457.125Z" style="fill: none;clip-rule: evenodd" /> </clipPath> <clipPath id="clip-path-42" transform="translate(-5.561 -10.291)"> <path id="R1" data-name="R1" d="M25.314,18.03H24.085a.746.746,0,0,0,.191-.177.441.441,0,0,0,.081-.266V11.621a.463.463,0,0,0-.081-.271.6.6,0,0,0-.191-.172h1.229v6.429a.422.422,0,0,0,.08.246.73.73,0,0,0,.191.177Z" style="fill: none;clip-rule: evenodd" /> </clipPath> <clipPath id="clip-path-43"> <path id="O1" d="M22.38,14.637v.026h0v.081l0,.023a3.231,3.231,0,0,1-.367,1.385,3.556,3.556,0,0,1-.9,1.089,3.814,3.814,0,0,1-1.2.655,3.724,3.724,0,0,1-1.289.2,3.869,3.869,0,0,1-1.4-.3,3.818,3.818,0,0,1-1.169-.756,3.474,3.474,0,0,1-.791-1.133A3.228,3.228,0,0,1,15,14.763v-.119h0v-.022h0V14.6h0v-.047h0v-.024h0V14.38a3.256,3.256,0,0,1,.273-1.138,3.554,3.554,0,0,1,.756-1.109,3.749,3.749,0,0,1,2.8-1.073,4.05,4.05,0,0,1,1.265.257A3.668,3.668,0,0,1,21.241,12a3.433,3.433,0,0,1,.836,1.113,3.107,3.107,0,0,1,.3,1.237l0,.021v.131h0v.025h0v.025h0v.052h0v.025ZM21.265,14.4a3.982,3.982,0,0,0-.18-1.025,2.913,2.913,0,0,0-.529-.99,2.287,2.287,0,0,0-.821-.628,2.492,2.492,0,0,0-1.043-.218,2.667,2.667,0,0,0-1.038.2,2.42,2.42,0,0,0-.826.569,2.593,2.593,0,0,0-.549.905,3.436,3.436,0,0,0-.2,1.085v.232h0v.024h0V14.6h0v.024h0v.023h0v.025l0,.023v.027a3.52,3.52,0,0,0,.228,1.105,2.93,2.93,0,0,0,.615.98,2.5,2.5,0,0,0,1.778.762,2.549,2.549,0,0,0,1.023-.2,2.313,2.313,0,0,0,.811-.584,2.739,2.739,0,0,0,.534-.915,3.439,3.439,0,0,0,.188-1.021v-.185h0v-.044h0V14.6h0v-.022h0v-.022h0v-.022h0v-.022h0V14.4Z" style="fill: none;clip-rule: evenodd" /> </clipPath> <clipPath id="clip-path-44" transform="translate(-5.561 -10.291)"> <path id="W4" d="M11.676,16.41l.234.578c.236-.631.477-1.261.715-1.891q.222-.6.449-1.188t.409-1.063q.181-.476.308-.8c.084-.214.136-.348.156-.4s.05-.12.066-.16a.594.594,0,0,1,.061-.111.754.754,0,0,1,.086-.1.768.768,0,0,1,.151-.11h-1.03c.121.053.192.117.212.19a.481.481,0,0,1-.04.291c0,.007-.025.079-.076.216s-.118.319-.2.546-.18.483-.287.767-.216.573-.323.867Z" style="fill: none;clip-rule: evenodd" /> </clipPath> <clipPath id="clip-path-45" transform="translate(-5.561 -10.291)"> <path id="W3" d="M11.675,16.358Zm0,0h0l.011.029h0l.232.575c-.152.4-.311.82-.474,1.252L10.176,15.07q-.242-.6-.478-1.183t-.433-1.058q-.2-.474-.333-.793c-.09-.213-.146-.343-.166-.389a1.8,1.8,0,0,0-.176-.27.774.774,0,0,0-.348-.209h1.833a.3.3,0,0,0-.221.239.9.9,0,0,0,.03.35c0,.006.027.076.08.209s.123.308.207.524.179.464.287.744.218.562.332.848Q11.179,15.089,11.675,16.358Z" style="fill: none;clip-rule: evenodd" /> </clipPath> <clipPath id="clip-path-46" transform="translate(-5.561 -10.291)"> <path id="W2" d="M9.139,16.411l.234.578c.236-.632.477-1.261.715-1.891q.222-.6.45-1.189t.408-1.062c.122-.318.224-.584.308-.8s.137-.347.157-.4l.065-.16a.556.556,0,0,1,.061-.11.7.7,0,0,1,.086-.1.8.8,0,0,1,.151-.11h-1.03c.121.054.192.117.213.191a.488.488,0,0,1-.041.29c0,.007-.025.079-.076.216s-.117.319-.2.546-.179.483-.287.768-.216.573-.323.867Z" style="fill: none;clip-rule: evenodd" /> </clipPath> <clipPath id="clip-path-47" transform="translate(-5.561 -10.291)"> <path id="W1" d="M9.138,16.358Zm0,0h0l.012.029h0l.233.575q-.229.6-.475,1.252L7.639,15.07q-.242-.6-.478-1.183t-.433-1.058q-.2-.474-.332-.793l-.166-.389a1.8,1.8,0,0,0-.177-.27.764.764,0,0,0-.347-.209H7.539a.305.305,0,0,0-.222.239.938.938,0,0,0,.03.35c0,.006.027.076.081.209s.122.308.206.524.18.464.287.744.218.562.332.848Q8.642,15.089,9.138,16.358Z" style="fill: none;clip-rule: evenodd" /> </clipPath> </defs> <g id="world" stroke="#003668" stroke-width="2" fill="none"> <!--W--> <line x1="0.93" y1="0.482" x2="3.873" y2="7.937" clip-path="url(#clip-path-47)" /> <line x1="3.088" y1="7.937" x2="5.966" y2="0.482" clip-path="url(#clip-path-46)" /> <line x1="3.481" y1="0.482" x2="6.424" y2="7.937" clip-path="url(#clip-path-45)" /> <line x1="5.639" y1="7.937" x2="8.517" y2="0.482" clip-path="url(#clip-path-44)" /> <!--O--> <path d="M18.657,11.3a3.1,3.1,0,0,0-2.289.981,3.448,3.448,0,0,0-.458,3.858,2.78,2.78,0,0,0,2.747,1.7,2.961,2.961,0,0,0,2.813-1.7,3.514,3.514,0,0,0-.458-3.858A3.055,3.055,0,0,0,18.657,11.3Z" transform="translate(-5.561 -10.291)" clip-path="url(#clip-path-43)" /> <!--R--> <line x1="19.374" y1="0.482" x2="19.374" y2="7.937" clip-path="url(#clip-path-42)" /> <path d="M25.261,11.426h1.112a1.419,1.419,0,0,1,1.57,1.5,1.466,1.466,0,0,1-1.57,1.5H25.261" transform="translate(-5.561 -10.291)" clip-path="url(#clip-path-41)" /> <path d="M25.065,14.435H26.5c.654,0,1.7,2.42,2.224,3.074l.261.261c.262.131,1.112.458,1.112.458" transform="translate(-5.561 -10.291)" clip-path="url(#clip-path-40)" /> <!--L--> <line x1="26.754" y1="0.482" x2="26.754" y2="7.937" clip-path="url(#clip-path-39)" /> <path d="M32.707,17.77h2.551a.5.5,0,0,0,.327-.13,1.886,1.886,0,0,0,.261-.72" transform="translate(-5.561 -10.291)" clip-path="url(#clip-path-38)" /> <!--D--> <line x1="33.118" y1="0.482" x2="33.118" y2="7.937" clip-path="url(#clip-path-37)" /> <path d="M38.94,11.492h1.766a3.118,3.118,0,0,1,2.224.915,3,3,0,0,1,.85,2.159,3.079,3.079,0,0,1-1.047,2.354,3.314,3.314,0,0,1-2.158.85H38.94" transform="translate(-5.561 -10.291)" clip-path="url(#clip-path-36)" /> </g> </svg> Change the speed variable in JavaScript to make it faster or slower
CSS Select #shadow-root
I'd like to use CSS to set the fill of the bottom right circle to green. The snippet below successfully colors entire shape to green, but I just want to color part of the shape (just the circle). [row="2"] [col="b"] {fill: green;} <svg> <defs> <symbol id="myShape"> <polygon points="0,0 40,0 20,20" /> <circle r="10" cx="10" cy="10" stroke="black" /> </symbol> </defs> <g row="1" translate="transform(0,0)"> <use col="a" xlink:href="#myShape" x="0" /> <use col="b" xlink:href="#myShape" x="50" /> </g> <g row="2" transform="translate(0,50)"> <use col="a" xlink:href="#myShape" x="0" /> <use col="b" xlink:href="#myShape" x="50" /> </g> </svg>
If you want something to always be a specific colour, then set it to be that colour explicitly. [row="2"] [col="b"] {fill: green;} [row="1"] [col="b"] {fill: blue;} <svg> <defs> <symbol id="myShape"> <polygon points="0,0 40,0 20,20" fill="black" /> <circle r="10" cx="10" cy="10" stroke="black" /> </symbol> </defs> <g row="1" translate="transform(0,0)"> <use col="a" xlink:href="#myShape" x="0" /> <use col="b" xlink:href="#myShape" x="50" /> </g> <g row="2" transform="translate(0,50)"> <use col="a" xlink:href="#myShape" x="0" /> <use col="b" xlink:href="#myShape" x="50" /> </g> </svg>
Why does my SVG image get cut out rather than resizing when nested inside another SVG?
I have an SVG that I want to fit in a smaller box, while preserving all ratios. I'm trying to do this by nesting the SVG inside another SVG with smaller width/height and viewbox numbers, but instead of resizing, the image is getting cut out. I've tried nesting the original SVG inside another SVG with different viewbox numbers. Original SVG <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0.0" y="0.0" width="2060.0" height="1340.0" xml:space="preserve" viewBox="0.0 0.0 2060.0 1340.0"> <!-- The artwork image. --> <image dragTarget="true" scaleTarget="true" dragConstraint="canvas-front-rect" scaleConstraint="canvas-front-rect" id="artwork-image" x="5" y="-100.0" width="2400" height="1500" preserveAspectRatio="xMidYMid slice" xlink:href="https://www.printbit.com/wp-content/uploads/2017/06/happy-people.jpg" /> <!-- The "sides" --> <g transform="scale(1, -1) translate(0, -140)" > <use clip-path="url(#clip-path-top)" xlink:href="#artwork-image" /> </g> <g transform="scale(1, -1) translate(0, -2540)" > <use clip-path="url(#clip-path-bottom)" xlink:href="#artwork-image" /> </g> <g transform="scale(-1, 1) translate(-140, 0)" > <use clip-path="url(#clip-path-left)" xlink:href="#artwork-image" /> </g> <g transform="scale(-1, 1) translate(-3980, 0)" > <use clip-path="url(#clip-path-right)" xlink:href="#artwork-image" /> </g> <!-- Constraint information --> <rect id="canvas-front-rect" constraint="gte" x="70.0" y="70.0" width="1920.0" height="1200.0" stroke-width="1" stroke="#0000FF" fill="none" visibility="visible" /> <!-- Clip path definitions for the mirroring --> <defs> <clipPath id="clip-path-top"> <rect x="70.0" y="70.0" width="1920.0" height="70.0" stroke="#00FF00" fill="none"/> </clipPath> <clipPath id="clip-path-bottom"> <rect x="70.0" y="1200.0" width="1920.0" height="70.0" stroke="#00FF00" fill="none"/> </clipPath> <clipPath id="clip-path-left"> <rect x="70.0" y="70.0" width="70.0" height="1200.0" stroke="#00FF00" fill="none"/> </clipPath> <clipPath id="clip-path-right"> <rect x="1920.0" y="70.0" width="70.0" height="1200.0" stroke="#00FF00" fill="none"/></clipPath> </defs> </svg> and I'm trying to nest this inside of <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0.0" y="0.0" width="492.16" height="406.83" xml:space="preserve" viewBox="0.0 0.0 492.16 406.83" ></svg> Expected Result: I want the original SVG to show up as a smaller version of itself, with all ratios preserved. Actual: However, instead of just resizing, the image gets cut out.
Take the width and height off the nested <svg/> element. Then it will adapt to the size of the parent. <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0.0" y="0.0" width="492.16" height="406.83" xml:space="preserve" viewBox="0.0 0.0 492.16 406.83" > <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0.0" y="0.0" xml:space="preserve" viewBox="0.0 0.0 2060.0 1340.0"> <!-- The artwork image. --> <image dragTarget="true" scaleTarget="true" dragConstraint="canvas-front-rect" scaleConstraint="canvas-front-rect" id="artwork-image" x="5" y="-100.0" width="2400" height="1500" preserveAspectRatio="xMidYMid slice" xlink:href="https://www.printbit.com/wp-content/uploads/2017/06/happy-people.jpg" /> <!-- The "sides" --> <g transform="scale(1, -1) translate(0, -140)" > <use clip-path="url(#clip-path-top)" xlink:href="#artwork-image" /> </g> <g transform="scale(1, -1) translate(0, -2540)" > <use clip-path="url(#clip-path-bottom)" xlink:href="#artwork-image" /> </g> <g transform="scale(-1, 1) translate(-140, 0)" > <use clip-path="url(#clip-path-left)" xlink:href="#artwork-image" /> </g> <g transform="scale(-1, 1) translate(-3980, 0)" > <use clip-path="url(#clip-path-right)" xlink:href="#artwork-image" /> </g> <!-- Constraint information --> <rect id="canvas-front-rect" constraint="gte" x="70.0" y="70.0" width="1920.0" height="1200.0" stroke-width="1" stroke="#0000FF" fill="none" visibility="visible" /> <!-- Clip path definitions for the mirroring --> <defs> <clipPath id="clip-path-top"> <rect x="70.0" y="70.0" width="1920.0" height="70.0" stroke="#00FF00" fill="none"/> </clipPath> <clipPath id="clip-path-bottom"> <rect x="70.0" y="1200.0" width="1920.0" height="70.0" stroke="#00FF00" fill="none"/> </clipPath> <clipPath id="clip-path-left"> <rect x="70.0" y="70.0" width="70.0" height="1200.0" stroke="#00FF00" fill="none"/> </clipPath> <clipPath id="clip-path-right"> <rect x="1920.0" y="70.0" width="70.0" height="1200.0" stroke="#00FF00" fill="none"/></clipPath> </defs> </svg> </svg>
Prevent arrow heads from being cropped
I'm trying to compose an arrow in SVG: svg line { stroke-width: 10px; stroke: black; } svg polyline { stroke: orange; } <figure> <svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg" width="40" height="300"> <defs> <marker id="start" markerWidth="3" markerHeight="3" refX="0" refY="1.5" orient="auto" > <polyline points="1.5,0 0,1.5 1.5,3" fill="none" /> </marker> <marker id="end" markerWidth="3" markerHeight="3" refX="1.5" refY="1.5" orient="auto" > <polyline points="0,0 1.5,1.5 0,3" fill="none" /> </marker> </defs> <line x1="20" y1="50" x2="20" y2="250" marker-start="url(#start)" marker-end="url(#end)" /> </svg> </figure> As you can see in this scaled-up screen-shot, it kind of works: Yet the looks differ a lot from my expectations: Is it possible to see the complete arrow head and also get square corners?
From Details on how markers are rendered: overflow="visible" svg line { stroke-width: 10px; stroke: black; } svg polyline { stroke: orange; } <figure> <svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg" width="40" height="300"> <defs> <marker id="start" markerWidth="3" markerHeight="3" refX="0" refY="1.5" orient="auto" overflow="visible" > <polyline points="1.5,0 0,1.5 1.5,3" fill="none" /> </marker> <marker id="end" markerWidth="3" markerHeight="3" refX="1.5" refY="1.5" orient="auto" overflow="visible" > <polyline points="0,0 1.5,1.5 0,3" fill="none" /> </marker> </defs> <line x1="20" y1="50" x2="20" y2="250" marker-start="url(#start)" marker-end="url(#end)" /> </svg> </figure>