如何在图像加载前显示 SVG 填充?
How can I display an SVG fill before image loads?
我目前有一个工作示例,但我想知道是否有比我更了解 SVG 的人可以压缩代码并使其更优雅。
我想做什么:
- 页面加载后在自定义路径(形状)内显示图像(“延迟加载”)
- 直到页面加载(最重要的是在较慢的设备上)显示填充作为背景。
在此处查看 fiddle 和代码:
https://jsfiddle.net/k2o9L6dg/
复制问题
如您所见,一切正常,但我想删除 <g>
标签。 如果删除此标签,形状为 transparent/white 直到图像加载。您可以在“网络”选项卡下节流以查看此用户体验。我想在图像加载之前使用灰色填充,以便文本可以显示在形状内。
我觉得应该可以完成这项工作,而不必两次定义“路径”。每当我将蒙版路径上的填充更改为白色以外的其他内容时,什么也没有出现(不知道为什么会这样)。
我希望能够将代码压缩成这样:
<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>
您可以通过在 <defs>
中创建可重复使用的定义来避免重复的 <path>
元素。
<defs>
<path id="maskPath" d="..." />
</defs>
注意:您的可重用路径定义不得包含任何填充 属性 如果您需要为不同的实例更改它的填充(例如蒙版和背景形状)
你的面具看起来像这样:
<mask id="bg-c" >
<use href="#maskPath" fill="white" />
</mask>
例子
//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>
放置另一个 <use>
blob 形状的实例来创建背景元素,如下所示:
<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 的人可以压缩代码并使其更优雅。
我想做什么:
- 页面加载后在自定义路径(形状)内显示图像(“延迟加载”)
- 直到页面加载(最重要的是在较慢的设备上)显示填充作为背景。
在此处查看 fiddle 和代码:
https://jsfiddle.net/k2o9L6dg/
复制问题
如您所见,一切正常,但我想删除 <g>
标签。 如果删除此标签,形状为 transparent/white 直到图像加载。您可以在“网络”选项卡下节流以查看此用户体验。我想在图像加载之前使用灰色填充,以便文本可以显示在形状内。
我觉得应该可以完成这项工作,而不必两次定义“路径”。每当我将蒙版路径上的填充更改为白色以外的其他内容时,什么也没有出现(不知道为什么会这样)。
我希望能够将代码压缩成这样:
<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>
您可以通过在 <defs>
中创建可重复使用的定义来避免重复的 <path>
元素。
<defs>
<path id="maskPath" d="..." />
</defs>
注意:您的可重用路径定义不得包含任何填充 属性 如果您需要为不同的实例更改它的填充(例如蒙版和背景形状)
你的面具看起来像这样:
<mask id="bg-c" >
<use href="#maskPath" fill="white" />
</mask>
例子
//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>
放置另一个 <use>
blob 形状的实例来创建背景元素,如下所示:
<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" />