SVG resizing in IE9 - css

I've got an inline SVG element inside a div, which scales to fit the browser window. When the browser is resized, the SVG image resizes with it, so that all the image is visible, and it keeps the same proportions.
However, in IE9, the image is much smaller, and doesn't resize. Taking off the viewBox scales the image to the full size, which is too big, and it still doesn't resize.
I've found that by setting the width and height of the containing div will make the image larger, but only with fixed pixels, rather than 100%, which is what I need.
This jsfiddle shows the problem in action (i.e. it's fine in Chrome, and not fine in IE9). Resizing the frame borders should make the image resize.
<div id="outer">
<svg viewBox="0 0 700 1000" xmlns=http://www.w3.org/2000/svg>
<g transform="rotate(90, 350, 350)" id="pitch-rotated">
<title>Pitch</title>
<path d="m0,0l1000,0l0,700l-1000,0l0,-700z" stroke-width="5" stroke="#fff" fill="#008800" id="perimiter"/>
<line id="centre-line" y2="700" x2="500" y1="0" x1="500" stroke-width="5" stroke="#ffffff" fill="none"/>
<path id="penalty-box-home" fill="none" stroke="#fff" stroke-width="5" d="m0,148.5l165,0l0,403l-165,0l0,-403z"/>
<path id="six-yard-box-home" fill="none" stroke="#fff" stroke-width="5" d="m0,258.5l55,0l0,183l-55,0l0,-183z"/>
<path d="m1000,148.5l-165,0l0,403l165,0l0,-403z" stroke-width="5" stroke="#fff" fill="none" id="penalty-box-away"/>
<path d="m1000,258.5l-55,0l0,183l55,0l0,-183z" stroke-width="5" stroke="#fff" fill="none" id="six-yard-box-away"/>
<circle fill="none" stroke="#ffffff" stroke-width="5" cx="500" cy="350" r="95" id="centre-circle"/>
<circle fill="none" stroke="#ffffff" stroke-width="10" cx="500" cy="350" r="1" id="centre-spot"/>
<circle fill="none" stroke="#ffffff" stroke-width="7" cx="110" cy="350" r="1" id="penalty-spot-home"/>
<circle fill="none" stroke="#ffffff" stroke-width="7" cx="890" cy="350" r="1" id="penalty-spot-away"/>
<path d="m165,277.5a91,91 1 0 10,145" stroke="#ffffff" stroke-width="5" fill="none" id="penalty-curve-home"/>
<path d="m835,277.5a91,91 0 0 00,145" stroke="#ffffff" stroke-width="5" fill="none" id="penalty-curve-away"/>
<path d="m0,10a7.5,7.5 0 0 010,-10" stroke="#ffffff" stroke-width="5" fill="none" id="corner-home-left"/>
<path d="m0,690a7.5,7.5 0 0 110,10" stroke="#ffffff" stroke-width="5" fill="none" id="corner-home-right"/>
<path d="m1000,10a7.5,7.5 0 0 1-10,-10" stroke="#ffffff" stroke-width="5" fill="none" id="corner-away-left"/>
<path d="m1000,690a7.5,7.5 0 0 0-10,10" stroke="#ffffff" stroke-width="5" fill="none" id="corner-away-right"/>
</g>
</svg>
</div>

I haven't tested this in IE yet but if you're looking to use 100% width and height the I assume you either want it to be 'fullscreen' or to fit within a container. Since you also mentioned that it scales correctly when...
setting the width and height of the containing div will make the image larger, but only with fixed pixels
...then you can use JS for this. With jQuery, for example, you can do the following:
$(window).resize(function()
{
$('#outer').css({
width: $(window).width() + 'px',
height: $(window).height() + 'px'
})
});
This is assuming that you want your #outer container to be the width and height of the window when the window is resized.

I know you've said you'd like to avoid setting the width and height, but that's the only way I've managed to get it to work, personally.
Though I did figure out that you only need to set the height, you can leave the width at 100%, so:
var container = this.$('.container'),
width = container.width(),
scale = svg.width / width;
container.height(parseInt(svg.height / scale, 10));
Where svg.width and svg.height are the values I know to be the original width and height of the SVG..

Related

Get left and top of a text element inside an SVG?

I want to get the (top, left) coordinate of the text element relative to the svg element, expressed in the same unit/greatness as the y and x attributes of the text element.
I think that the example below is close, but there is a problem. getBoundingClientRect returns different values for top, left as the view port size changes, while of course the y, x attribute values of the text element are always the same. Thus the unit/greatness of top, left and y, x does not match.
I tried setting display: flex on the body to force the svg to not scale, but then it got the size 0 x 0.
const svgRect = document.querySelector("svg").getBoundingClientRect()
const textRect = document.querySelector("text").getBoundingClientRect()
const textBoxPosRelativeToSvgExpressedInSvgCoordinates = {top: textRect.y - svgRect.y, left: textRect.x - svgRect.x}
console.log(textBoxPosRelativeToSvgExpressedInSvgCoordinates)
<body>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 400">
<g id="main">
<line x1="10" y1="10" x2="100" y2="200" stroke="#00c" stroke-width="5" stroke-linecap="round"/>
<polyline points="580,10 560,390 540,200 520,390 400,390" stroke="#c00" stroke-width="5" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
<polygon points="350,75 379,161 469,161 397,215 423,301 350,250 277,301 303,215 231,161 321,161" stroke="#ff0" stroke-width="10" fill="#ffc"/>
<rect x="100" y="10" width="150" height="100" rx="10" ry="20" stroke="#060" stroke-width="8" fill="#0f0"/>
<circle cx="100" cy="300" r="80" stroke="#909" stroke-width="10" fill="#f6f"/>
<ellipse cx="450" cy="50" rx="80" ry="30" stroke="#0cc" stroke-width="10" fill="#0ff"/>
<text x="240" y="390" font-family="sans-serif" font-size="50" fill="#00f">SVG</text>
</g>
</svg>
</body>

clip-path url fails to find id

I have an SVG that I am trying to use to clip a div, but the id I give to the <clipPath> tag does not work.
I have tried changing the ID, and have made sure that the SVG does indeed exist in the same file, and the ID is visible.
The svg is like so:
<svg id="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 149.559">
<defs>
<clipPath id="clipper">
<g id="svgg" stroke="none" fill-rule="evenodd">
<path id="path0" d= .../>
<path id="path1" d= .../>
<path id="path2" d= .../>
<path id="path3" d= .../>
<path id="path4" d= .../>
</g>
</clipPath>
</defs>
</svg>
I added the <defs> and <clipPath> tag so I could use the svg I had as a clipping mask.
The html element being used is:
<div class="logo-bg" style="clipPath: url(#clipper)"></div>
the div does have a width and height.
Within developer tools, the css property of the div I am trying to clip with clip-path: url(#clip-id) shows "could not load the image". Ideally I would be able to clip the div with the SVG.
here's the code I am working with: https://jsfiddle.net/mzLtsqva/6/
I am new to working with SVGs and so would appreciate any help to solve this issue.
Inside the <clipPath> don't wrap the paths in a group element.
In the next example I'm using a clipping path that is not working: #no and one that is working: #yes. In the one that is not working I'm wrapping the elements inside in a <g> element.
svg{border:1px solid;}
<svg width="250" height="250" viewBox="0 0 250 250" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<rect id="rect" x ="0" y ="0" height ="150" width ="70" style ="stroke:#000;" transform="translate(90, 50)"/>
<clipPath id="no">
<g>
<use xlink:href="#rect" fill="none"></use>
<use xlink:href="#rect" fill="none" transform="rotate(60 125 125)"></use>
<use xlink:href="#rect" fill="none" transform="rotate(-60 125 125)"></use>
</g>
</clipPath>
</defs>
<image xlink:href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/beagle400.jpg" height="250" width="250" x="-15" y ="50" clip-path="url(#no)"></image>
</svg>
<svg width="250" height="250" viewBox="0 0 250 250" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<clipPath id="yes">
<use xlink:href="#rect" fill="none"></use>
<use xlink:href="#rect" fill="none" transform="rotate(60 125 125)"></use>
<use xlink:href="#rect" fill="none" transform="rotate(-60 125 125)"></use>
</clipPath>
</defs>
<image xlink:href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/beagle400.jpg" height="250" width="250" x="-15" y ="50" clip-path="url(#yes)"></image>
</svg>

How to hide overflow when sliding an element of an SVG in using keyframe animation?

I need to slide up the entire hand and phone element (hand_phone class) onto it's current position on the red background. The trouble I have is only showing the hand when it's on the red background, not sliding it up on the blue or white. As if the hand and phone is behind everything else and the red box is a window. I've tried clipPath, hidden: overflow, but not having any luck.
https://jsfiddle.net/8moofbef/3/
.hand_phone {
animation: slide 1s;
}
#keyframes slide {
from {transform: translateY(400px)}
to {transform: translateY(0px)}
}
Define the <clipPath> that you want the hand to appear inside of. In this case it's just a <rect> the same size as the red one.
<defs>
<clipPath id="red-rect-clip">
<rect x="167.5" y="981.4" class="st2" width="391.7" height="451"/>
</clipPath>
</defs>
Secondly, you need apply the clip path to the correct elements. It can't be <g class="hand_phone"> because that is being animated with a transform. And any transform you apply to that will also move the clip path that is attached to it.
So what you need to do is surround the "hand_phone" elements with a parent group. Then apply the clip path to that. That way the clip doesn't move, and you get the effect you want.
<g clip-path="url(#red-rect-clip)">
<g class="hand_phone">
<...>
</g>
</g>
.hand_phone {
animation: slide 1s;
}
#keyframes slide {
from {transform: translateY(400px)}
to {transform: translateY(0px)}
}
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1920 1920" style="enable-background:new 0 0 1920 1920;" xml:space="preserve">
<defs>
<clipPath id="red-rect-clip">
<rect x="167.5" y="981.4" class="st2" width="391.7" height="451"/>
</clipPath>
</defs>
<style type="text/css">
.st0{fill:#057BDB;}
.st1{fill:#FFFFFF;}
.st2{fill:#FF0049;}
.st3{clip-path:url(#SVGID_2_);}
.st4{fill:#01434C;}
.st5{fill:#03828E;}
.st6{fill:#085E67;}
.st7{fill:#6CB5AE;}
.st8{fill:#25A599;}
.st9{fill:#B5B5B5;}
.st10{fill:#DDDDDD;}
.st11{fill:#F27040;}
.st12{fill:#F48359;}
.st13{fill:#F05A2B;}
.st14{fill:#253D46;}
.st15{fill:#969BA4;}
.st16{fill:#465B66;}
.st17{fill:#AFBDC5;}
.st18{fill:#FF8B00;}
.st19{fill:#566D78;}
.st20{fill:#5D6972;}
.st21{fill:#78909B;}
.st22{fill:#F8A773;}
.st23{fill:#FAB685;}
.st24{fill:#F79B6A;}
.st25{fill:#140F2C;}
.st26{fill:#E5E5E5;}
.st27{fill:#F4F4F4;}
.st28{fill:#150E39;}
.st29{fill:#1C1749;}
.st30{fill:#171043;}
.st31{fill:#5E6A7E;}
.st32{fill:#0A038E;}
.st33{fill:#30120B;}
.st34{fill:#CBE6F3;}
.st35{fill:#838E93;}
.st36{fill:#BCB1D7;}
.st37{fill:#9F98C6;}
.st38{fill:#D8CEE6;}
.st39{fill:#FF88A7;}
.st40{fill:#EAEBF0;}
.st41{fill:#F0F1F8;}
.st42{fill:#D5DAEE;}
.st43{fill:#378E43;}
.st44{fill:#BD3A27;}
.st45{fill:#795549;}
.st46{fill:#F69D5E;}
.st47{fill:#221F1F;}
.st48{fill:#403F41;}
.st49{fill:#E6E6E7;}
.st50{fill-rule:evenodd;clip-rule:evenodd;fill:#D0A785;}
.st51{fill-rule:evenodd;clip-rule:evenodd;fill:#FFD6B6;}
.st52{fill-rule:evenodd;clip-rule:evenodd;fill:#AAAAAA;}
.st53{fill-rule:evenodd;clip-rule:evenodd;fill:#CCE9F9;}
.st54{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
.st55{fill-rule:evenodd;clip-rule:evenodd;fill:#CBCBCB;}
.st56{fill-rule:evenodd;clip-rule:evenodd;fill:#989898;}
.st57{fill-rule:evenodd;clip-rule:evenodd;fill:#93C6E2;}
.st58{fill:#CBCBCB;}
.st59{fill:#E6E6E6;}
.st60{fill:#96BEE5;}
.st61{opacity:0.5;fill:#F2F2F2;}
.st62{fill:#F2F2F2;}
.st63{fill:#CBCDCE;}
.st64{fill:#0D3EB7;}
.st65{fill:#4D4D4D;}
.st66{opacity:0.1;}
.st67{fill:#808080;}
.st68{fill:#D7D8D9;}
.st69{fill:#F1F2F2;}
.st70{fill:#FFFEF7;}
.st71{fill:#BDCAE8;}
.st72{opacity:0.5;fill:#FFFFFF;}
.st73{fill:#D7D7D7;}
.st74{fill:#D7869D;}
.st75{opacity:0.2;fill-rule:evenodd;clip-rule:evenodd;fill:#1A1A1A;}
.st76{opacity:0.65;}
.st77{fill:none;stroke:#ED1C24;stroke-width:2;stroke-miterlimit:10;}
.st78{fill:none;stroke:#ED1C24;stroke-width:2;stroke-miterlimit:10;stroke-dasharray:1.9968,1.9968;}
.st79{opacity:0.95;fill:none;stroke:#ED1C24;stroke-width:2;stroke-miterlimit:10;stroke-dasharray:2;}
.st80{fill:#567396;}
.st81{fill:#FFFFFF;stroke:#057BDB;stroke-width:0.75;stroke-miterlimit:10;}
</style>
<g>
<rect y="-1" class="st0" width="1920" height="1920"/>
<g class="white_rectangle">
<rect x="140.6" y="666.1" class="st1" width="849.2" height="793.9"/>
</g>
<g class="red_rectangle">
<rect x="167.5" y="981.4" class="st2" width="391.7" height="451"/>
</g>
<g clip-path="url(#red-rect-clip)">
<g class="hand_phone">
<path class="st46" d="M435.6,1066.8l-16,21c-4.1,5.3-23.5,14.4- 15.2,22.4c10.1,9.7,22.5,10.1,26.5,5.8l28-31
c4.2-5.1,10.1-14.8,1.3-23.2C450.1,1052,439.5,1062.5,435.6,1066.8z"/>
<path class="st46" d="M280.3,1138.7c-0.6,33.7-3.4,107.9-3.4,107.9s-1.2,15.3,4.8,22.2c6.1,6.9,15.1,9.9,15.1,9.9l-15.1,31.5
l80.3,42.6l56.4-87.9l-118.3-110.6C300.2,1154.2,303.5,1137,280.3,1138.7z"/>
<path class="st47" d="M418.3,1044.1H312.8c-7.1,0-12.9,5.8-12.9,12.9v201.7c0,7.2,5.8,12.9,12.9,12.9h105.5
c7.2,0,12.9-5.8,12.9-12.9v-201.7C431.3,1049.9,425.5,1044.1,418.3,1044.1z"/>
<rect x="308" y="1072.8" class="st1" width="115.2" height="167.1"/>
<circle class="st48" cx="365.6" cy="1060" r="4.8"/>
<path class="st48" d="M374,1250.7h-16.8c-2.9,0-5.3,2.4-5.3,5.3c0,2.9,2.4,5.3,5.3,5.3H374c2.9,0,5.3-2.4,5.3-5.3
C379.3,1253,376.9,1250.7,374,1250.7z"/>
<path class="st46" d="M424.7,1208l-5.1,6.5c-4.1,5.3-9,14.4-0.7,22.4c10.1,9.7,20.7-0.8,24.6-5.1l4.4-5.6
c4.2-5.1,10.1-14.8,1.3-23.2C439.2,1193.3,428.6,1203.8,424.7,1208z"/>
<path class="st46" d="M424.7,1166.5l-5.1,6.5c-4.1,5.3-9,14.4-0.7,22.4c10.1,9.7,20.7-0.8,24.6-5.1l4.4-5.6
c4.2-5.1,10.1-14.8,1.3-23.2C439.2,1151.8,428.6,1162.2,424.7,1166.5z"/>
<path class="st46" d="M424.7,1124.6l-5.1,6.4c-4.1,5.3-9,14.4-0.7,22.4c10.1,9.7,20.7-0.8,24.6-5l4.4-5.6
c4.2-5.1,10.1-14.8,1.3-23.2C439.2,1109.9,428.6,1120.4,424.7,1124.6z"/>
<polygon class="st49" points="270.7,1297.2 200,1433.1 335.4,1433.1 376.7,1353.7 "/>
<polygon class="st1" points="270.7,1297.2 200,1433.1 267.7,1433.1 323.7,1325.5 "/>
</g>
</g>
</g>
</svg>
https://jsfiddle.net/8moofbef/4/

How can I scale the unkown content of a svg to 100%?

I have a few svg-paths like this:
<svg>
<path d="M5,1L5,2" stroke="black" stroke-width="1" fill="none"></path>
<path d="M5,1L5,2L5,3L5,4L5,5L5,6" stroke="black" stroke-width="1" fill="none"></path>
<path d="M5,1L5,2L5,3" stroke="black" stroke-width="1" fill="none"></path>
</svg>
I don't know their width or height or coordinates or how many there are, I would like to scale them so that they together fill the entire parent container. One solution would be to somehow make the svg-canvas shrink to their size and then scale it all with css. I'm new to svg so I'm not sure what's the best approach.

SVG resizing in IE11

I was researching a strange behaviour in IE11 and came across this thread with the exact problem, but for IE9:
SVG resizing in IE9
I've got an inline SVG element inside a div, which scales to fit the browser window. When the browser is resized, the SVG image resizes with it, so that all the image is visible, and it keeps the same proportions.*
However, in IE9, the image is much smaller, and doesn't resize. Taking off the viewBox scales the image to the full size, which is too big, and it still doesn't resize.
The problem can be seen in this jsfiddle where the resizing does not work as expected in IE9 nor IE11.
<div id="outer">
<svg viewBox="0 0 700 1000" xmlns=http://www.w3.org/2000/svg>
<g transform="rotate(90, 350, 350)" id="pitch-rotated">
<title>Pitch</title>
<path d="m0,0l1000,0l0,700l-1000,0l0,-700z" stroke-width="5" stroke="#fff" fill="#008800" id="perimiter"/>
<line id="centre-line" y2="700" x2="500" y1="0" x1="500" stroke-width="5" stroke="#ffffff" fill="none"/>
<path id="penalty-box-home" fill="none" stroke="#fff" stroke-width="5" d="m0,148.5l165,0l0,403l-165,0l0,-403z"/>
<path id="six-yard-box-home" fill="none" stroke="#fff" stroke-width="5" d="m0,258.5l55,0l0,183l-55,0l0,-183z"/>
<path d="m1000,148.5l-165,0l0,403l165,0l0,-403z" stroke-width="5" stroke="#fff" fill="none" id="penalty-box-away"/>
<path d="m1000,258.5l-55,0l0,183l55,0l0,-183z" stroke-width="5" stroke="#fff" fill="none" id="six-yard-box-away"/>
<circle fill="none" stroke="#ffffff" stroke-width="5" cx="500" cy="350" r="95" id="centre-circle"/>
<circle fill="none" stroke="#ffffff" stroke-width="10" cx="500" cy="350" r="1" id="centre-spot"/>
<circle fill="none" stroke="#ffffff" stroke-width="7" cx="110" cy="350" r="1" id="penalty-spot-home"/>
<circle fill="none" stroke="#ffffff" stroke-width="7" cx="890" cy="350" r="1" id="penalty-spot-away"/>
<path d="m165,277.5a91,91 1 0 10,145" stroke="#ffffff" stroke-width="5" fill="none" id="penalty-curve-home"/>
<path d="m835,277.5a91,91 0 0 00,145" stroke="#ffffff" stroke-width="5" fill="none" id="penalty-curve-away"/>
<path d="m0,10a7.5,7.5 0 0 010,-10" stroke="#ffffff" stroke-width="5" fill="none" id="corner-home-left"/>
<path d="m0,690a7.5,7.5 0 0 110,10" stroke="#ffffff" stroke-width="5" fill="none" id="corner-home-right"/>
<path d="m1000,10a7.5,7.5 0 0 1-10,-10" stroke="#ffffff" stroke-width="5" fill="none" id="corner-away-left"/>
<path d="m1000,690a7.5,7.5 0 0 0-10,10" stroke="#ffffff" stroke-width="5" fill="none" id="corner-away-right"/>
</g>
</svg>
So my question is, is there still no non-JS way of solving this, even in IE11?
Encountered similar problems with one of my clients. So, the checklist:-
Is the window.onresize triggering?
Are you able to read the new window.innerHeight and window.innerWidth?
What I did was write a zoom slider for SVG. With window.addEventListener("resize", .....) code (thank you SO), read the new height and width values, calculate the correct Zoom. If .onresize doesn't trigger (happen occassionally on every browsers, out of our control), they can use the slider to fix it.
Sideline: Out of curiosity, this looks like a soccer game simulation?

Resources