I currently have a working example, but I'm wondering if there's someone out there with more knowledge on SVGs than myself who can compress the code and make it more elegant.
What I'm trying to do:
Show image inside the custom defined path (shape) once page is loaded ("lazy load")
Until page load (on slower devices most importantly) show a fill as background.
See the fiddle and code here:
https://jsfiddle.net/k2o9L6dg/
Replicate the issue
All is working fine as you can see, but I would like to remove the <g> tag. If I remove this tag, the shape is transparent/white until the image loads. You can throttle under the "Network" tab to see this user experience. I would like to use a grey fill until image loads, so text can be displayed within the shape.
I feel like it should be possible to make this work, without having to define the "path" two times. Whenever I change the fill on the mask path to other than white, nothing appears at all (no idea why this happens).
I would like to be able to compress the code to just this:
<div class="vector">
<svg xmlns="http://www.w3.org/2000/svg" image-rendering="optimizeQuality" viewBox="0 0 510 360" shape-rendering="geometricPrecision" fill-rule="evenodd">
<defs>
<mask id="bg-c" maskContentUnits="objectBoundingBox">
<path fill="white" transform="scale(0.001965, 0.002800)" d="M148.500 3.099 C 113.488 6.747,84.700 13.892,62.351 24.482 C 43.108 33.600,33.681 41.189,22.444 56.609 C 7.759 76.760,4.338 86.781,5.282 106.890 C 5.880 119.655,7.968 128.762,13.637 143.340 C 23.834 169.561,23.443 167.883,23.464 185.500 C 23.479 197.898,23.041 203.414,21.520 210.000 C 18.603 222.635,18.745 240.097,21.847 249.975 C 30.657 278.033,52.991 299.700,93.500 319.490 C 109.905 327.505,121.171 331.756,142.440 337.958 C 190.118 351.861,258.762 358.886,289.318 352.989 C 307.253 349.528,331.710 340.925,364.262 326.626 C 392.030 314.428,408.965 308.298,425.480 304.468 C 451.051 298.538,471.322 283.403,481.509 262.633 C 487.363 250.696,489.054 243.962,489.701 230.000 C 490.547 211.754,486.958 197.061,477.358 179.483 C 469.662 165.389,471.689 154.395,491.588 102.309 C 506.590 63.041,509.743 48.582,505.331 39.285 C 501.149 30.471,482.609 22.301,459.167 18.940 C 445.334 16.957,405.463 18.286,371.500 21.862 C 319.125 27.376,299.077 27.919,277.500 24.407 C 270.080 23.199,265.779 21.647,253.000 15.566 C 234.292 6.663,230.109 5.365,214.006 3.470 C 200.434 1.873,162.341 1.658,148.500 3.099">
</path>
</mask>
</defs>
<image loading="lazy" data-href="https://images.pexels.com/photos/910411/pexels-photo-910411.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1" alt="" width="100%" height="100%" mask="url(#bg-c)" preserveAspectRatio="xMidYMid slice">
</image>
</svg>
</div>
You can avoid duplicate <path> elements by creating a reusable definition in <defs>.
<defs>
<path id="maskPath" d="..." />
</defs>
Note: your reusable path definition must not contain any fill property if you need to change it's fill for different instances (like mask and background shape)
Your mask would look something like this:
<mask id="bg-c" >
<use href="#maskPath" fill="white" />
</mask>
Example
//emulate loading by setTimeout delay
emulateLazyLoad();
function emulateLazyLoad() {
let lazyImages = document.querySelectorAll('[loading="lazy"]');
lazyImages.forEach(function(lazy) {
let imgHref = lazy.dataset.href;
setTimeout(function() {
if (lazy.nodeName.toLowerCase() == "image") {
lazy.setAttribute("href", imgHref);
} else {
lazy.src = imgHref;
}
lazy.classList.replace("loading", "loaded");
}, 1000);
});
}
svg {
width: 50%;
display: inline-block;
}
.image {
transition: 0.3s opacity;
}
.loading {
opacity: 0;
}
.loaded {
opacity: 1;
}
<div class="vector">
<svg xmlns="http://www.w3.org/2000/svg" image-rendering="optimizeQuality" viewBox="0 0 510 360" shape-rendering="geometricPrecision" fill-rule="evenodd">
<defs>
<path id="maskPath" d="M148.500 3.099 C113.488 6.747,84.700 13.892,62.351 24.482 C 43.108 33.600,33.681 41.189,22.444 56.609 C 7.759 76.760,4.338 86.781,5.282 106.890 C 5.880 119.655,7.968 128.762,13.637 143.340 C 23.834 169.561,23.443 167.883,23.464 185.500 C23.479 197.898,23.041 203.414,21.520 210.000 C 18.603 222.635,18.745 240.097,21.847 249.975 C 30.657 278.033,52.991 299.700,93.500 319.490 C109.905 327.505,121.171 331.756,142.440 337.958 C 190.118 351.861,258.762 358.886,289.318 352.989 C 307.253 349.528,331.710 340.925,364.262 326.626 C392.030 314.428,408.965 308.298,425.480 304.468 C 451.051 298.538,471.322 283.403,481.509 262.633 C 487.363 250.696,489.054 243.962,489.701 230.000 C490.547 211.754,486.958 197.061,477.358 179.483 C 469.662 165.389,471.689 154.395,491.588 102.309 C 506.590 63.041,509.743 48.582,505.331 39.285 C501.149 30.471,482.609 22.301,459.167 18.940 C 445.334 16.957,405.463 18.286,371.500 21.862 C 319.125 27.376,299.077 27.919,277.500 24.407 C 270.080 23.199,265.779 21.647,253.000 15.566 C 234.292 6.663,230.109 5.365,214.006 3.470 C 200.434 1.873,162.341 1.658,148.500 3.099" />
<mask id="bg-c">
<use href="#maskPath" fill="white" />
</mask>
</defs>
<use id="bgShape" href="#maskPath" fill="gray" />
<text x="50%" y="50%" text-anchor="middle" dominant-baseline="middle">Loading ...</text>
<image class="image loading" loading="lazy" data-href="https://images.pexels.com/photos/910411/pexels-photo-910411.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1" alt="" width="100%" height="100%" mask="url(#bg-c)" preserveAspectRatio="xMidYMid slice" />
</svg>
</div>
Place another <use>instance of your blob shape to create a background element like so:
<use id="bgShape" href="#maskPath" fill="gray" />
<text x="50%" y="50%" text-anchor="middle" dominant-baseline="middle">Loading ...</text>
<image class="image loading" loading="lazy" data-href="https://images.pexels.com/photos/910411/pexels-photo-910411.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1" alt="" width="100%" height="100%" mask="url(#bg-c)" preserveAspectRatio="xMidYMid slice" />
<svg xmlns="http:/www.w3.org/2000/svg" version="1.1" viewBox="0 0 462.22 473.42">
<g
transform="translate(-140.31946,-267.08233)">
<clipPath
id="img">
<path
style="fill:#cccccc;fill-opacity:1;stroke:#ffffff;stroke-width:0.5;stroke-opacity:1"
inkscape:connector-curvature="0"
d="m 164.84,522.87 0.11,0.44 1.2,1.23 1.14,0.03 2.18,0.85 1.25,-0.2 1.87,-1.43 0.73,-0.13 1.15,0.06 0.44,0.49 1.07,0.01 0.72,-0.56 1.34,0.46 1.3,1.66 0.43,3.08 1.11,0.53 -0.73,2 0.31,0.44 0.75,-0.43 2.12,0.49 0.38,-0.41 0.08,-1.14 0.5,-0.65 1.15,0.02 0.95,-0.98 1.4,-0.6 0.35,0.14 1.03,-0.31 0.34,1.32 3.17,0.61 0.54,-0.61 1.37,-0.08 0.37,-0.9 1.36,-0.97 0.96,-0.04 1.82,-0.88 1.32,-1.82 1.02,-0.33 0.78,0.08 0.9,0.77 1.68,0.43 1.53,1.59 0.56,0.03 0.44,1.16 0.64,0.05 0.76,1.3 1.11,-0.38 1.98,1.3 1.06,-0.19 1.55,-1.16 1.19,0.19 1.42,1.41 0.07,0.65 -0.46,1.06 -0.88,0.44 -0.59,0.89 0.04,1.45 -0.39,1.05 0.55,0.92 1.27,-0.23 1.82,1.1 0.57,-0.14 0.86,0.29 1.19,-0.73 -0.03,-0.84 -0.59,0.44 -0.61,-0.27 -0.39,-1.27 1.54,0.16 -0.51,-1.37 0.76,-0.87 1.17,-0.57 1.82,0.38 1.75,-0.45 0.85,-0.57 1.24,0.37 1.64,-0.73 1.19,0.33 0.45,1.49 1.63,0.27 1.39,-0.51 1.06,0.18 1.41,-0.41 1.73,-0.02 1.05,-0.56 0,0 0.73,2.16 1.58,0.07 0.44,-0.1 1.09,-1.33 -0.15,-0.73 0.49,-0.29 0.74,0.15 -0.19,2.49 -0.71,0.41 -0.18,0.46 0.06,1.8 -1.56,1.65 0.06,0.37 0.66,0.5 -0.07,0.59 0.49,0.3 0.25,0.62 1.89,1.42 2.04,1.03 1.18,-0.31 0.43,0.37 1.39,-0.26 0.4,0.22 0.91,1.85 -0.28,1.03 0.23,0.58 1.65,1.36 1.06,0.05 0.7,0.38 0.2,0.61 -0.2,0.86 1.4,-0.2 1.31,1.42 0.63,0.13 0.23,0.32 0,0 -0.47,0.57 -3.32,1.69 0.56,0.84 -0.7,0.86 -0.38,1.77 0.31,0.39 0.92,0.27 0.53,0.76 -0.22,0.87 -1.27,0.38 -2.71,1.63 -1.54,-0.19 -0.74,0.36 -1.49,1.87 -0.19,1.09 -0.86,0.24 -1.16,1.08 0.38,0.88 -0.99,0.92 -0.77,1.43 0.42,0.85 -0.5,0.52 0.53,0.53 -2.59,1.57 0.2,0.81 -0.26,0.64 -0.78,-1.33 0.03,-0.43 -0.94,-1.14 -0.87,-0.41 0.04,-0.73 -1.18,0.25 -1.93,-0.31 -0.5,0.45 -1.03,-0.4 -0.58,0.8 -0.57,0.01 -1.58,2.17 0.61,0.66 0.7,0.2 -0.52,0.44 0.46,0.77 -0.67,0.72 0.49,1.81 -1.88,1.12 -1.39,2.33 -0.63,-0.35 -0.48,0.21 -0.6,-0.17 -1.12,0.77 -2.53,0.25 0.61,0.55 -0.73,1.44 1.02,0.58 0.17,0.39 -0.66,1.1 0.09,0.83 -0.46,1.72 0.28,0.89 -0.59,1.39 -1.88,-0.39 -1.41,0.55 -0.53,0.69 -0.9,0.02 -0.85,0.82 -0.78,1.72 0.7,0.56 0.75,0.14 0.32,0.69 0.66,0.1 0.03,0.62 0.37,0.22 -1.37,0.43 -0.94,1.87 -0.57,0.31 -0.76,-0.05 -1.26,0.77 0.05,0.83 -0.74,1.28 0.17,2.6 2.44,1.43 1.28,1.87 -0.14,1 -0.52,0.29 -0.05,0.93 0.73,0.39 0.15,0.8 -0.59,0.83 -1.21,0.43 -0.34,1.75 -0.34,0.37 1.65,1.48 0.96,2.58 -0.13,1.8 0.53,2.61 -0.44,0.39 -1.34,0.15 0,0 -1.29,-0.28 -0.52,0.23 -0.52,-0.34 0,0 -0.08,-1.97 -1.13,-1.56 -0.32,-1.52 -1.12,-0.56 -1.37,-1.84 -1.42,0.11 0.02,-0.67 -0.43,-0.55 0.01,-0.92 -0.32,-0.42 -1.16,0.17 -0.75,-0.56 -1.03,0.27 -0.45,-0.57 -1.5,-0.3 -0.42,-1.05 0.42,-0.86 -0.25,-0.53 0.34,-1.02 -1.99,-0.45 -0.67,-0.93 2.15,-3.09 -0.84,-1.21 -2.35,-1.52 -0.47,-0.75 0.53,-2.37 0.78,-1.57 -0.54,-1.26 -1.5,-0.86 -0.3,-0.95 0.13,-0.89 -0.72,-2.3 -0.47,-0.49 -0.41,-2.54 0.55,-1.53 0.04,-1.33 -1.68,-2.95 -0.75,-0.46 -0.34,0.14 -1.57,-1.25 -1.1,-3.81 -0.64,-0.95 -0.39,-1.37 -1.25,-1.38 0.17,-1.45 0.33,-0.38 -1.25,-0.25 -0.96,0.88 -0.79,0.04 -0.19,-0.13 0.15,-0.48 -0.9,-0.05 -0.17,-0.61 -0.72,-0.13 -0.24,-0.41 -1.57,0.3 -0.76,-0.46 -0.44,0.14 -0.05,-0.8 -0.75,-0.02 -0.07,-2.24 -0.61,-0.42 0.35,-0.18 0.42,-1.17 -1.05,-1.57 0.02,-1.71 -0.98,-0.79 1.02,-0.29 0.27,-0.39 1.05,0.79 0.31,-0.17 -0.51,-2.42 0.17,-1.41 -1.09,-0.68 -0.31,0.19 0.12,-0.61 -0.37,-0.1 -1.05,-1.29 -0.33,-0.01 -0.89,0.77 -0.32,-0.2 -0.12,-0.68 -1.05,-0.23 -0.71,0.22 -1.07,-0.99 -1.05,-1.97 -0.82,-0.77 -0.06,-0.75 -0.4,-0.51 0.95,-1.39 -0.04,-0.41 -1.32,-1.54 -0.48,-1.11 -0.07,-1.3 -1.17,-0.38 -2.3,0.23 -0.78,0.52 -0.99,-0.5 -2.61,0.38 -0.81,-1.16 -1.1,-0.45 -0.17,-0.69 -1.63,-0.17 0,0 -0.43,0 -1.11,-0.91 -1.84,-0.11 -0.21,-1.41 -0.86,-0.58 0,0 -0.48,-1.34 -0.42,-2.96 1.07,-1.26 0.33,-0.8 -1.27,-2.99 0.05,-0.64 0.37,-0.32 -0.27,-0.9 0.07,-1.68 2.07,-1.9 0.35,-0.14 0.42,0.48 0.2,-0.62 -0.5,-0.67 -0.68,0.06 -0.66,-0.53 0.04,-1.21 1.22,-0.95 0.6,-0.85 1.28,-0.45 0.44,0.86 0.87,0.61 2.25,0.71 z"
class="land"
title="Alba"
id="RO-AB" />
<image xlink:href="ana.jpg" clip-path="url(#img)" x="0" y="0" height="50px" width="50px"/>
</clipPath>
</g>
</svg>
Why is this code now working if i save it like a html document? Please help me . I am very new in svg so do not be rude with me :)
I'm including svg:s in my markup using xlink:href:
<svg class="questionTitleIcon">
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#icon-questionmark"></use>
</svg>
#icon-questionmark is defined
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="icon-questionmark" viewBox="0 0 60 61" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns"><!-- Generator: Sketch 3.4.1 (15681) - http://www.bohemiancoding.com/sketch --><title>Slice 1</title><desc>Created with Sketch.</desc><defs></defs><g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage"><g id="icon-invoicing-1" sketch:type="MSLayerGroup"><path d="M59.9827338,30.6427143 C59.9827338,14.2078571 46.5638849,0.884857143 30.0107914,0.884857143 C13.4581295,0.884857143 0.0392805755,14.2078571 0.0392805755,30.6427143 C0.0392805755,47.0775714 13.4581295,60.4005714 30.0107914,60.4005714 C46.5638849,60.4005714 59.9827338,47.0775714 59.9827338,30.6427143" id="Fill-1" fill="#FFBB2F" sketch:type="MSShapeGroup"></path><path d="M32.7333898,38.383 C33.4633898,39.1 33.8283898,40.003 33.8283898,41.091 C33.8283898,42.18 33.4633898,43.082 32.7333898,43.799 C32.0023898,44.516 31.0933898,44.874 30.0053898,44.874 C28.9163898,44.874 28.0203898,44.516 27.3173898,43.799 C26.6143898,43.082 26.2623898,42.18 26.2623898,41.091 C26.2623898,40.003 26.6143898,39.1 27.3173898,38.383 C28.0203898,37.667 28.9163898,37.308 30.0053898,37.308 C31.0933898,37.308 32.0023898,37.667 32.7333898,38.383 Z" id="Path" stroke="#6C4B00" stroke-width="2" sketch:type="MSShapeGroup"></path><path d="M22.0223898,23.022 C22.0223898,23.022 22.4993898,19.883 24.0523898,18.329 C25.6053898,16.777 27.7353898,16 30.4433898,16 C31.7433898,16 32.9053898,16.193 33.9273898,16.577 C34.9493898,16.963 35.8193898,17.507 36.5353898,18.21 C37.2523898,18.914 37.7963898,19.743 38.1683898,20.699 C38.5393898,21.654 38.7253898,22.69 38.7253898,23.805 C38.7253898,24.601 38.6393898,25.298 38.4663898,25.895 C38.2943898,26.492 38.0623898,27.037 37.7703898,27.528 C37.4773898,28.019 37.1463898,28.464 36.7743898,28.862 L36.4023898,29.26 C35.9503898,29.676 35.2333898,30.297 34.8093898,30.641 C34.8093898,30.641 34.8093898,30.641 34.4653898,30.932 C34.1193898,31.225 33.8083898,31.53 33.5293898,31.848 C33.2503898,32.167 33.1113901,32.3135647 32.8723898,32.884 C32.6333895,33.4544353 32.6333898,34.305 32.6333898,34.437 C32.6333898,34.568 31.7333898,34.675 30.6333898,34.675 L29.0583898,34.675 C27.9583898,34.675 27.0583898,34.326 27.0583898,33.899 C27.0583898,33.472 27.1773898,31.749 27.4173898,31.151 C27.6563898,30.554 27.9603898,30.017 28.3323898,29.539 C28.7043898,29.061 29.1153898,28.623 29.5673898,28.225 L30.0183898,27.826 C30.5143898,27.432 31.4163898,26.701 32.0223898,26.201 C32.0223898,26.201 32.0223898,26.201 32.4743898,25.736 C32.9253898,25.272 33.1513898,24.734 33.1513898,24.123 C33.1513898,23.433 32.9323898,22.836 32.4943898,22.331 C32.0553898,21.827 31.3323898,21.575 30.3233898,21.575 C29.3143898,21.575 28.5323898,21.867 27.9743898,22.451 C27.7887231,22.6456667 27.9743896,22.4510002 27.4173899,23.2842646 C26.8603902,24.1175289 26.2383898,24.999 25.1383898,24.999 L23.7223898,24.999 C22.6223898,24.999 21.8573898,24.109 22.0223898,23.022 Z" id="Path" stroke="#6C4B00" stroke-width="2" sketch:type="MSShapeGroup"></path></g></g></symbol>
</svg>
This works fine in Chrome.
In firefox, on any other url than "/", if I have a base-tag in my header, the items are not found, here is an example of the base-tag
Why is this and what can be done about it?
As Kaiido said, if you have to use a <base> element, then you will need to change all your xlink:href and url(#foo) references to absolute URLs. For example:
xlink:href="/path/to/my.svg#icon-questionmark"