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.
Related
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!
I'm a beginner in animation. I am trying to learn svg animation from the following piece of code.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" viewbox="50 70 200 200">
<path stroke="black" fill="none" d="M70,85H125V140H70V85Z" ></path>
<path d="M0,0 L-2.69,-4.95L0,-2.2L2.69,-4.95L0,0z" transform="rotate(-90)" style="fill: #ff0000;">
<animateMotion path="M70,85H125V140H70V85Z" dur="10s" rotate="auto" repeatCount="indefinite"></animateMotion>
</path>
<g>
<desc>white mask</desc>
<rect x="90" y="80" width="15" height="65" fill="white" />
<rect x="65" y="105" width="65" height="15" fill="white" />
</g>
</svg>
I'm tring to move the arrow to rotate in opposite direction (i.e anticlockwise) but unable to achieve that. I have tried to change the path but I'm stuck at this point.
Any help will be appreciated.
We can use keyTimes and keyPoints to run the animation backwards and alter the transform to rotate the arrow. See how the keyPoints go from 1 to 0.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" viewbox="50 70 200 200">
<path stroke="black" fill="none" d="M70,85H125V140H70V85Z" ></path>
<path d="M0,0 L-2.69,-4.95L0,-2.2L2.69,-4.95L0,0z" transform="rotate(90)" style="fill: #ff0000;">
<animateMotion keyPoints="1;0" keyTimes="0;1" path="M70,85H125V140H70V85Z" dur="10s" rotate="auto" repeatCount="indefinite"></animateMotion>
</path>
<g>
<desc>white mask</desc>
<rect x="90" y="80" width="15" height="65" fill="white" />
<rect x="65" y="105" width="65" height="15" fill="white" />
</g>
</svg>
My svg is displayed correct in IE, Edge and Chrome. Firefox doesn't work. The problem is, that the text doesn't appear correct.
Chrome
chrome
FF
Firefox Version
Here the code of my svg. I really don't know what the problem is.
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="780px" height="540px" viewBox="0 0 780 540" enable-background="new 0 0 780 540" xml:space="preserve">
<a href="https://www.google.ch" target="_blank">
<g>
<image
overflow="visible"
opacity="0.35"
width="56"
height="52"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADkAAAA1CAYAAAD72kP+AAAACXBIWXMAAAsSAAALEgHS3X78AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAu9JREFUeNrsmmtv0zAUhp1LU5goDDGuAgk+8oH//0s2beIqBmUbW9e10DVN13AOeU0PrtMLrUuqOtKreU2jniev7ZP4OFRbcMQzzgcbxJIvAhkY2iRIqVJIhorweYx2uAGwI2goNLJBasA66Q6pQdoh1SrsqnbshpSSfpA6pGtSpkFNyBiAT0nPSXsAjSvu4oB0RTohHZPOAf6769ogGwB8Q3pF2hVuVtFJhuyRTkmHpD4c7QP0j0OBgGTnHpJekl6jnVR4XPL4+0m6S+qSPiNePZfkZjcM4dpt0n0APsI4rTJkF+41EGsk4y1LITFgE1xUxw2oYneNMCZriHsiG8RTHgBkrqxqGpGxhWVZIFRbcHhID+khPaSH9JAe0kN6SA/pIT2kh/SQHtJDbiFkbvzdlKM07jInR0J5hYF1bGa8UyH5C7y0zsWSFMrUuK5QNUBdyRqIeIcmbGzcEV0d4hXpFulCFQUgvhm31HhlOqgIIMNxieASsbZVURfJZA+MxIV6gbYGoET9vSodWtwP/hMcQ3BBh8t0Z6RPpCPSW1XUQlowa2RCyqB1l81s9lsAgzV2TV2HZOe+kt6R9kkHaJ/g/NDmpDkm+7C+h3a/ZHy6hLXBsUvfSB/h3j7EgE24m0pjopLZaij6u67edtC+XgNsGVzTAneEz84wl6RmbNEcs1YPF7ehK/zvAnYeuAPAccH1A861xIQzMbSiGT8ou6521AXsonDvMR7P8d1UjMGJVBfN+eM3cHXVsMvAdRFP2cQ4N+QqYU1I53DLTBA6n0bIpVx653r9A9ITVWyqeAE9U0VJfhcPFQmuy41cd4Gpn0GOoSYmk7boktm/PGouMwsuCruH84ka79i4dAm3yrw2L6wG3UFXlvtuvriAc5G8p8E+VsUGKA05BOQpEvt3F3AuH8dssLz15B6g63CyB9COK7h1PHNK2BrgzIlnADmBW+dbRCDeYkJLWnL+Yr7OVyW5Pyi3LFv4w6/WzTh+CTAA7UuPJ4vLMvAAAAAASUVORK5CYII="
transform="matrix(1 0 0 1 490.2483 147.248)"
></image>
<g>
<g>
<polygon
fill="red"
points="540.724,151.425 540.724,180.043 518.262,191.72 495.801,180.043 495.801,151.425"
/>
<polygon
fill="none"
stroke="#D9D9D9"
stroke-width="0.75"
stroke-linejoin="round"
stroke-miterlimit="10"
points="540.724,151.425 540.724,180.043 518.262,191.72 495.801,180.043 495.801,151.425"
/>
</g>
</g>
</g>
</a>
<text transform="matrix(1 0 0 1 509.5081 163.1104)">
<tspan x="0" y="0" fill="#949495" font-family="'Calibri'" font-size="11">
KVP
</tspan>
<tspan
x="-0.516"
y="12"
fill="#949495"
font-family="'Calibri'"
font-size="11"
>
[VP]
</tspan>
</text>
<path
fill="none"
stroke="#A3D2C4"
stroke-width="0.75"
stroke-linejoin="round"
stroke-miterlimit="10"
d="M664.349,162.086"
/>
</svg>
This is not an answer, it's just a comment: As you can see the next example works the same way in Chrome and FF. There must be something else in your code that is causing the problem.
svg{border:1px solid;}
<svg viewBox="240 120 90 50">
<rect x="260" y="135" width="50" height="20" fill="none" stroke="black" />
<text id="txt"
transform="matrix(1 0 0 1 262.6731 147.9746)"
fill="#1D1D1B"
font-family='Calibri'
font-size="11"
>
Betrieb
</text>
</svg>
UPDATE
The OP added more code.
I've replaced the <tspan> with <text> elements. Instead of having the <a> inside the text, now the <a> is wrapping the text.
Also I've replaced your image with a shadow generated with an svg filter.
svg{border:1px solid}
text{fill:#949495;font-family:Calibri;font-size:11;text-anchor:middle}
<svg viewBox="480 140 78 60">
<defs>
<filter id="f">
<feGaussianBlur in="SourceAlpha" stdDeviation="1.3" result="desenfoque"></feGaussianBlur>
<feOffset in="desenfoque" dx="0" dy="0" result="sombra"></feOffset>
<feMerge>
<feMergeNode in="sombra"></feMergeNode>
<feMergeNode in="SourceGraphic"></feMergeNode>
</feMerge>
</filter>
</defs>
<a href="https://www.google.ch" target="_blank">
<g>
<g>
<g filter="url(#f)">
<polygon
fill="red"
points="540.724,151.425 540.724,180.043 518.262,191.72 495.801,180.043 495.801,151.425"
/>
<polygon
fill="none"
stroke="#D9D9D9"
stroke-width="0.75"
stroke-linejoin="round"
stroke-miterlimit="10"
points="540.724,151.425 540.724,180.043 518.262,191.72 495.801,180.043 495.801,151.425"
/>
</g>
</g>
</g>
</a>
<a href="https://google.ch">
<text x="518.5" y="167" >KVP</text>
</a>
<a href="https://google.ch">
<text x="518.5" y="180" >[VP]</text>
</a>
<!--This path has a width and a height == 0
you can delete it -->
<path
fill="none"
stroke="#A3D2C4"
stroke-width="0.75"
stroke-linejoin="round"
stroke-miterlimit="10"
d="M664.349,162.086"
/>
</svg>
I am having a hard time applying a filter to an inline SVG symbol. I can make it work fine in a normal external SVG file but as soon as I make it inline with an HTML document, the filtered objects disappear. Is there anything I'm missing with the filter attribute? This fails for me in an up to date Chrome 57.
<html>
<body>
<svg style="display:none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<filter id="blur_inline">
<feGaussianBlur in="SourceGraphic" stdDeviation="3"/>
</filter>
<symbol id="filtered" width="80mm" height="50mm" viewBox="0 0 80 50" preserveAspectRatio="xMinYMin meet">
<rect id="a" x="0" y="10" width="30" height="20" fill="green"/>
<rect id="e" x="40" y="10" width="30" height="20" fill="blue" filter="url(#blur_inline)"/>
</symbol>
<symbol id="no_filter" width="80mm" height="50mm" viewBox="0 0 80 50" preserveAspectRatio="xMinYMin meet">
<rect id="a" x="0" y="10" width="30" height="20" fill="green"/>
<rect id="e" x="40" y="10" width="30" height="20" fill="blue"/>
</symbol>
</defs>
</svg>
<p>Symbol with a green and blurred blue box:</p>
<svg width="100mm" height="50mm">
<use xlink:href="#filtered" x="10" y="35" ></use>
</svg>
<p>Second symbol with no filter applied:</p>
<svg width="100mm" height="50mm">
<use xlink:href="#no_filter" x="10" y="35" ></use>
</svg>
</body>
</html>
Setting your SVG to display:none will make it non-functional because it disables all CSS.
<html>
<body>
<svg width="0" height="0">
<defs>
<filter id="blur_inline">
<feGaussianBlur in="SourceGraphic" stdDeviation="3"/>
</filter>
<symbol id="filtered" width="80mm" height="50mm" viewBox="0 0 80 50" preserveAspectRatio="xMinYMin meet">
<rect id="a" x="0" y="10" width="30" height="20" fill="green"/>
<rect id="e" x="40" y="10" width="30" height="20" fill="blue" filter="url(#blur_inline)"/>
</symbol>
<symbol id="no_filter" width="80mm" height="50mm" viewBox="0 0 80 50" preserveAspectRatio="xMinYMin meet">
<rect id="a" x="0" y="10" width="30" height="20" fill="green"/>
<rect id="e" x="40" y="10" width="30" height="20" fill="blue"/>
</symbol>
</defs>
</svg>
<p>Symbol with a green and blurred blue box:</p>
<svg width="100mm" height="50mm">
<use xlink:href="#filtered" x="10" y="35" ></use>
</svg>
<p>Second symbol with no filter applied:</p>
<svg width="100mm" height="50mm">
<use xlink:href="#no_filter" x="10" y="35" ></use>
</svg>
</body>
</html>
Is it possible to have a multiple different views into single SVG, or even just simulate that sort of effect with some clever use of groups? I wish to show different parts of a potentially very large SVG, but I'd rather avoid rendering it multiple times. Is there some sort of simple way of doing this?
for standalone SVGs there is the <view/> element which you can use to show only portions of your graphics. try this in a standalone file.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100" width="100" height="100">
<view id="circleView" viewBox="0 0 100 100"/>
<view id="rectView" viewBox="100 0 100 100"/>
<a xlink:href="#rectView">
<circle cx="50" cy="50" r="45" fill="blue"/>
</a>
<a xlink:href="#rectView">
<rect x="105" y="5" width="90" height="90" fill="royalblue" stroke="#53c"></rect>
</a>
</svg>
just click on the cirlce to see the rect and on the rect to see the circle.
this also works if you reference your svg via <img>
<img src="your.svg#circleView"/>
<img src="your.svg#rectView"/>
i found this to be not working for inlined SVG. Here you can use a similar aproach. You can just change the viewBox of your SVG. In contrast to the above, viewBoxes can even be animated!
<svg viewBox="0 0 460 360" width="200" height="200">
<polygon id="triangle" points="100,10,450,350,10,350" fill="#52c" />
<circle id="circle" cx="50" cy="50" r="45" fill="#c52" />
<rect id="rect" x="255" y="155" width="200" height="200" fill="#5c2" />
<animate attributeName="viewBox" to="250 150 210 210" dur="0.5s" begin="circle.click" fill="freeze" />
<animate attributeName="viewBox" to="0 0 100 100" dur="0.5s" begin="triangle.click" fill="freeze" />
<animate attributeName="viewBox" to="0 0 460 360" dur="0.5s" begin="rect.click" fill="freeze" />
</svg>
<br/>click on any of he shapes!
of course you can also just set the viewBox by script...
if you want to reference different parts of your SVG, you might use the <use> - Element as suggested in the other answers.
It's pretty simple to do. You just use the <use> element as Robert suggests. Here is a working example.
svg {
border: solid 1px black;
}
svg#original {
width: 450px;
}
<svg viewBox="0 0 450 300" id="original">
<circle cx="225" cy="150" r="150" fill="orange"/>
<circle cx="175" cy="110" r="25" fill="black"/>
<circle cx="275" cy="110" r="25" fill="black"/>
<circle cx="225" cy="70" r="150" fill="none" stroke="black" stroke-width="20" stroke-dasharray="0 145 180 1000"/>
</svg>
<br/>
<!-- part of the original at the same scale -->
<svg width="150" height="150">
<use xlink:href="#original" x="-50" y="0" width="450" height="300"/>
</svg>
<!-- part of the original at 0.5x scale -->
<svg width="150" height="150">
<use xlink:href="#original" x="0" y="0" width="450" height="300" transform="scale(0.5)"/>
</svg>
<!-- part of the original at 3x scale (and using a different method to achieve the scaling) -->
<svg width="150" height="150">
<use xlink:href="#original" x="-450" y="-255" width="1350" height="900"/>
</svg>