2013-10-13 2 views
9

У меня довольно сложное, динамически созданное изображение svg, которое было создано с помощью jQuery SVG. Я бы хотел создать область «всплывающих окон», которая отображается поверх всех элементов svg на холсте. Чтобы создать современный полупрозрачный вид iOS7, я хотел бы применить фильтр размытия ко всему под областью всплывающих окон. Я хочу иметь возможность динамически устанавливать атрибуты x, y, а также ширину и высоту этой всплывающей области.Применить фильтр размытия к определенной области изображения svg

Посмотрите this example:

<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> 

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

Я нашел this, но здесь используется статическое фоновое изображение, которое у меня нет. Есть ли какие-либо причины для достижения этого эффекта с помощью svg, css и jQuery?

ответ

11

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

http://jsfiddle.net/J3X4p/2/

<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.

+0

Эй, потрясающе! Это работает очень хорошо! Большое вам спасибо, моя команда будет очень довольна этим результатом! =) – Dafen

+0

Еще один вопрос: если элемент под фильтром отсутствует, он становится просто черным. Есть ли способ использовать фон, который находится за элементом svg?(css background-image, установленный в тег html) Если нет, я попытаюсь показать копию фонового изображения html под фильтром, но над другими элементами svg. – Dafen

+0

Только в том случае, если браузер поддерживает enable-background и BackgroundImage. Но большинство нет, как уже указывал Майкл. Если бы они это сделали, вы бы использовали его решение вместо моего. –

3

Это возможно только с встроенным SVG в одном браузере - Internet Explorer 10 - вы используете атрибут «enable-background» и используете встроенный источник «BackgroundImage». Это метод, показанный в тексте учебника, с которым вы связались.

Существует обходной путь, если ваш фон является исключительно изображениями. Вы пишете фильтр, который использует фильтр feImage, чтобы вытащить те же изображения, которые находятся в фоновом режиме, размывает их и складывает размытие под любым содержимым, которое вы хотите показать сверху. Это метод, используемый в фактическом коде учебника, с которым вы связаны.

Если ваш фон - это другой контент SVG (текст, дорожки и т. Д.), То для достижения вашего эффекта нет кросс-браузерного способа, поскольку Firefox не поддерживает объекты SVG в качестве входов в примитив фильтра feImage. Если вы не заботитесь о Firefox, вы можете использовать тот же метод обхода, что и для учебников.

Вот пример последнего - это довольно близко к тому, что вы хотите, но я проверил его только в Chrome/Windows (я знаю, что это не работает в Firefox)

<svg x="0px" y="0px" width="500px" height="500px" viewbox="0 0 500 500"> 
    <defs> 
    <filter id="blurry" x="-20%" y="-20%" height="140%" width="140%" primitiveUnits="userSpaceOnUse"> 
     <feImage x="0" y="0" width="500" height="500" xlink:href="#squares" result="mySquares"/> 
     <feGaussianBlur stdDeviation="40" in="mySquares" result="blurSquares"/> 
     <feComponentTransfer in="blurSquares" result="morealpha"> 
     <feFuncA type="linear" intercept=".8"/> 
     </feComponentTransfer> 
     <feComposite operator="in" in="morealpha" in2="SourceGraphic" result="clipBlur"/> 
     <feFlood x="10%" y="10%" width="80%" height="80%" flood-color="white" flood-opacity="0.6" result="whitesquare"/> 
     <feBlend mode="screen" in="clipBlur" in2="whitesquare"/> 
    </filter> 
    </defs> 

    <g id="squares"> 
    <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 filter="url(#blurry)" x="50" y="50" height="400" width="400" fill="rgb(255,255,255)" /> 
</svg> 

enter image description here

(Update:.. недавнего открытие - вы можете использовать JavaScript для кодирования любого контента, который вы хотите кормить feImage в SVG + XML закодированные данные URI - то, что работает кросс-браузер супер некрасиво)

+0

Спасибо за ваш ответ! Я использовал подход BigBadaboom, потому что Firefox очень важен для нас. =) – Dafen

Смежные вопросы