Применение фильтра blur к определенной области изображения SVG

178
14 марта 2017, 12:45

У меня есть довольно сложное, динамически созданное svg изображение, которое было реализовано с помощью плагина - jQuery SVG.
Я хотел бы создать область popup, которая будет отображаться поверх всех элементов svg на холсте.
Для реализации современного полупрозрачного эффекта похожего на look в iOS7, я бы хотел применить фильтр размытия (blur) ко всем изображениям под всплывающей областью.
Я хочу иметь возможность динамически устанавливать атрибуты x, y, а также изменять ширину и высоту этой всплывающей области.
Взгляните на этот пример: jsfiddle

<svg width="500" height="500">
<rect x="10" y="10" height="235" width="235" fill="red" />
<rect x="255" y="10" height="235" width="235" fill="green" />
<rect x="10" y="255" height="235" width="235" fill="blue" />
<rect x="255" y="255" height="235" width="235" fill="yellow" />
<rect x="50" y="50" height="400" width="400" fill="rgba(255,255,255,0.8)" />

В этом случае всё, что покрыто белой областью, должно быть размытым. Это выглядит следующим образом:

Я нашел пример, но там используется статическое фоновое изображение, которого у меня нет. Есть ли какие-либо способы для достижения этого эффекта с помощью svg, css и jQuery?
Перевод вопроса: Apply blur filter to certain area of svg image

Answer 1

так кошернее

<svg width="500" height="500"> 
    <rect x="10" y="10" height="235" width="235" fill="red" /> 
    <rect x="255" y="10" height="235" width="235" fill="green" /> 
    <rect x="10" y="255" height="235" width="235" fill="blue" /> 
    <rect x="255" y="255" height="235" width="235" fill="yellow" /> 
   
  <defs> 
    <filter id="f1" x="0" y="0"> 
      <feGaussianBlur in="SourceGraphic" stdDeviation="20" /> 
    </filter> 
  </defs> 
    <rect id="blur" x="50" y="50" height="400" width="400" fill="rgba(255,255,255,0.8)" filter="url(#f1)" /> 
</svg>

Answer 2

Как насчет такого подхода? Это немного сложнее в использовании, но, похоже, это работает во всех браузерах.
jsfiddle

<svg x="0px" y="0px" width="500px" height="500px" viewbox="0 0 500 500"> 
  <defs> 
    <filter id="blurry" x="0%" y="0%" height="100%" width="100%" primitiveUnits="userSpaceOnUse"> 
      <feGaussianBlur x="50" y="50" width="400" height="400" stdDeviation="40" in="SourceGraphic" result="blurSquares"/> 
      <feComponentTransfer in="blurSquares" result="opaqueBlur"> 
        <feFuncA type="linear" intercept="1"/> 
      </feComponentTransfer> 
      <feBlend mode="normal" in="opaqueBlur" in2="SourceGraphic"/> 
    </filter> 
  </defs> 
 
  <g id="squares" filter="url(#blurry)"> 
    <rect x="10" y="10" height="235" width="235" fill="red" /> 
    <rect x="255" y="10" height="235" width="235" fill="green" /> 
    <rect x="10" y="255" height="235" width="235" fill="blue" /> 
    <rect x="255" y="255" height="235" width="235" fill="yellow" /> 
  </g> 
 
    <rect x="50" y="50" height="400" width="400" fill="rgb(255,255,255)" fill-opacity="0.8" /> 
</svg> 

Это сложнее, потому что фильтр применяется к фону, а не к <rect>. Чтобы он работал, вам нужно скопировать x, y, width и height из <rect> в примитив feGaussianBlur.

Перевод ответа: @Paul LeBeau

READ ALSO
CSS z-index не работает при двух блоках absolute

CSS z-index не работает при двух блоках absolute

Добрый день, у меня есть слайдер

178
HTML элемент есть, но не видим [требует правки]

HTML элемент есть, но не видим [требует правки]

Как видно, элемент есть и подсвечен в консоли разработчикаНо [на странице][1] его не видно

186
Позиционирование двух блоков и текста

Позиционирование двух блоков и текста

Добрый день, столкнулся с ситуацией где нужно сделать так что бы два блока были с background и наезжали друг на друга но что бы текст был выше них,...

163