How to force an image displayed with SVG element to cover the entire width and height

前端 未结 2 2087
忘了有多久
忘了有多久 2021-01-23 01:36

I have generated a blurred image using svg element. I want it to cover the entire width and height of the screen.

Now to better understand I am providing tw

相关标签:
2条回答
  • 2021-01-23 01:58

    If you know the dimensions of the image ahead of time, you can use the viewBox and preserveAspectRatio SVG attributes and skip the JavaScript altogether. In my fiddle it appears that you have to specify the image's width and height explicitly as well for this to work.

    <svg class="blur" viewBox="0 0 4288 2848" preserveAspectRatio="xMidYMid slice">
      <filter id="filter">
        <feGaussianBlur stdDeviation="5"/>
      </filter>
      <image xlink:href="https://saudiwoman.files.wordpress.com/2010/02/crowded-restaurant.jpg" filter="url(#filter)"
        width="4288" height="2848"></image>
    </svg>
    

    Another option is to specify the image as the SVG element's background in CSS, blurring with the filter property.

    0 讨论(0)
  • 2021-01-23 02:08

    I happened to have made something similar with jQuery a while back - a blurred svg with an <image> inside it that has the same behaviour as if it were given a center top / cover background. It uses the aspect ratio of the container (with overflow: hidden) and compares it to the ratio of the image to make it adapt to either full height or width of the wrapper element. When the parent is relatively narrower than the image itself, a transform is used to center the image horizontally :

    Fiddle

    <div id="wrap">
      <svg id="blur">
        <filter id="filter">
          <feGaussianBlur stdDeviation="5" />
        </filter>
        <image xlink:href="//saudiwoman.files.wordpress.com/2010/02/crowded-restaurant.jpg" width="100%" height="100%" filter="url(#filter)"></image>
      </svg>
    </div>
    

    body {
      margin: 0;
      padding: 0;
    }
    
    #wrap {
      height: 100vh;
      overflow: hidden;
    }
    
    .tall {
      position: relative;
      left: 50%;
      -webkit-transform: translateX(-50%);
      transform: translateX(-50%);
    }
    

    $(function() {
    
    var parent = $('#wrap'),
    scene = $('#blur'),
    ratio = 4288/2848; // aspect ratio of the image
    
    $(window).on('load resize', coverSpace);
    
    function coverSpace() {
    
        var range = parent.width(),
        term = parent.height(),
        proportion = range/term;
    
        if (proportion >= ratio) scene.css({width: '100%', height: range/ratio}).removeAttr('class');
        else scene.css({width: term*ratio, height: term}).attr('class', 'tall');
    }
    });
    

    I've reduced this from the original demo which uses a small plugin that has creates animated blur. In this form it wouldn't be a big step to make it vanilla JS altogether, jQuery isn't that great at accessing svg anyway. But if it's on a site that's linked to the library already, it should work fine as is in any case.

    Here's also a reduced case that will imitate center center / cover (with switching transforms) :

    http://codepen.io/Shikkediel/pen/MaGbbp


    Edit - and here's one for the purists :

    document.addEventListener('DOMContentLoaded', function() {
    
    var parent = document.getElementById('wrap'),
    scene = document.getElementById('blur'),
    ratio = 4288/2848;
    
    window.addEventListener('load', coverSpace);
    
    window.addEventListener('resize', coverSpace);
    
    function coverSpace() {
    
        var range = parent.clientWidth,
        term = parent.clientHeight,
        proportion = range/term;
    
        if (proportion >= ratio) {
        scene.style.width = '100%';
        scene.style.height = range/ratio + 'px';
        scene.removeAttribute('class');
        }
        else {
        scene.style.width = term*ratio + 'px';
        scene.style.height = term + 'px';
        scene.setAttribute('class', 'tall');
        }
    }
    });
    
    0 讨论(0)
提交回复
热议问题