Композит из двух отфильтрованных файлов SVG - PullRequest
1 голос
/ 07 марта 2019

Я пытаюсь реализовать визуальную стратегию 'diff' для печатных плат.Намерение состоит в том, чтобы выделить «новые» дополнения синим цветом, а старые части дизайна (удалены) красным.У меня есть два черно-белых файла SVG, каждый из которых представляет собой конкретную версию одного слоя платы.Они генерируются программно.Они выглядят примерно так: png изображение примера svg - я не могу напрямую загрузить .svg, но здесь есть пара примеров:

3c9fec_F_Cu.svg

75d8f4_F_Cu.svg

Я применил два отдельных фильтра feColorMatrix, один фильтр к версии 1 и другой версии 2, а затем разместил оба отфильтрованных изображения, расположив их абсолютно так, чтобы они перекрывали друг друга.друг с другом, в пределах одного <div>.

. Это работает в Chrome, но не работает в других браузерах (пробовал Safari и Firefox).

Результат в Chrome (желательно):

Я попытался применить фильтр feColorMatrix напрямую и объединить файлы результатов, но это не работает вообще ни в одном браузере.

Мой текущий успешный код (для Chrome):

.gallery {
  border: 1px solid #ccc;
}

.gallery:hover {
  border: 1px solid #777;
}

.gallery img {
  width: 100%;
  height: auto;
}
<div class="gallery">
<svg width="1123px" height="794px" viewBox="50 0 600 400" xmlns="http://www.w3.org/2000/svg" version="1.1">
                <defs>
                    <filter id="f1" x="0%" y="0%" width="100%" height="100%">
                        <feColorMatrix result="original" id="c1" type="matrix" values="1   0   0   0   0
                                                    0   1   0   1   0
                                                    0   0   1   1   0
                                                    0   0   0   1  0 " />
                    </filter>
                    <filter id="f2" x="0%" y="0%" width="100%" height="100%">
                        <feColorMatrix result="original" id="c2" type="matrix" values="1   0   0   1   0
                                            0   1   0   0   0
                                            0   0   1   0   0
                                            0   0   0   .5   0" />
                    </filter>

                </defs>
            <image x="0" y="0" width="100%" filter="url(#f1)" xlink:href="../../75d8f4/ThermocoupleLogger-F_Cu.svg" style="position:absolute;" />    
            <image x="0" y="0" width="100%" filter="url(#f2)" xlink:href="../../3c9fec/ThermocoupleLogger-F_Cu.svg" style="position:absolute;" />
            </svg>
    </div>

Моя альтернативная попытка с feMerge:

<div class="gallery">
<svg width="1123px" height="794px" viewBox="50 0 600 400" xmlns="http://www.w3.org/2000/svg" version="1.1">
                <defs>
                    <filter id="f1" x="0%" y="0%" width="100%" height="100%">
                    <feColorMatrix xlink:href="../../75d8f4/ThermocoupleLogger-F_Cu.svg" result="one" type="matrix" 
                                    values="1   0   0   0   0
                                            0   1   0   1   0
                                            0   0   1   1   0
                                            0   0   0   1  0 " />
                    </filter>

                    <filter id="f2" x="0%" y="0%" width="100%" height="100%">
                    <feColorMatrix xlink:href="../../3c9fec/ThermocoupleLogger-F_Cu.svg" result="two" type="matrix"
                                    values="1   0   0   1   0
                                            0   1   0   0   0
                                            0   0   1   0   0
                                            0   0   0   .5   0" />
                    </filter>

                    <filter id="composite">
                        <feMerge>
                        <feMergeNode in="one"/>
                        <feMergeNode in="two"/>
                        </feMerge>
                    </filter>

                </defs>

<g filter="url(#composite)"></g>

</svg>
</div>

Я был бы признателен за любой совет, который позволил бы мне достичь этого с некоторой степенью кросс-браузерной совместимости.

1 Ответ

1 голос
/ 07 марта 2019

Ваша первая версия в основном верна - но добавьте атрибут высоты непосредственно к вашему тегу изображения - SVG суетливо относится к размерам, а Chrome часто принимает то, чего не следует.Теги img и image являются разными элементами, поэтому height: auto не применяется к тегам изображений.Кроме того, существует ограниченное количество стилей CSS, которые применяются к подэлементам SVG, если есть сомнения, придерживаться атрибутов SVG.И удалить position: absolute - позиционирование в SVG является абсолютным по умолчанию.

Вторая версия не будет работать по многим причинам.feColorMatrix не принимает xlink: href в качестве входных данных - вы должны сначала импортировать внешний файл в фильтр, используя feImage, и добавить к нему атрибут result.Затем вы можете ссылаться на результат в атрибуте in вашего feColorMatrix.Фильтры могут ссылаться только на result внутри одного и того же фильтра, поэтому ссылки на one и two из фильтра id=composite не будут работать.Наконец, фильтрация пустого тега g не будет работать - он не имеет никаких измерений, поэтому область фильтра равна нулю.Так что ... используйте эту модифицированную версию своей первой попытки.

.gallery {
  border: 1px solid #ccc;
}

.gallery:hover {
  border: 1px solid #777;
}

.gallery img {
  width: 100%;
  height: auto;
}
<div class="gallery">
<svg width="1123px" height="794px" viewBox="50 0 600 400" xmlns="http://www.w3.org/2000/svg" version="1.1">
                <defs>
                    <filter id="f1" x="0%" y="0%" width="100%" height="100%">
                        <feColorMatrix result="original" id="c1" type="matrix" values="1   0   0   0   0
                                                    0   1   0   1   0
                                                    0   0   1   1   0
                                                    0   0   0   1  0 " />
                    </filter>
                    <filter id="f2" x="0%" y="0%" width="100%" height="100%">
                        <feColorMatrix result="original" id="c2" type="matrix" values="1   0   0   1   0
                                            0   1   0   0   0
                                            0   0   1   0   0
                                            0   0   0   .5   0" />
                    </filter>

                </defs>
            <image x="0" y="0" height="100%" width="100%" filter="url(#f1)" xlink:href="https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/beacon.svg"  />    
            <image x="0" y="0" height="100%" width="100%" filter="url(#f2)" xlink:href="https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/adobe.svg"  />
            </svg>
    </div>

Вы также можете сделать более элегантную версию, используя оператор xor feComposite.Наведите курсор мыши, чтобы увидеть эффект.

svg :hover {
  filter: url(#diff);
}
<svg width="1600px" height="800px" viewBox="0 0 1600 800">
<defs>
  <filter id="diff" x="20%" y="0%" width="80%" height="100%" >
    <feColorMatrix type="matrix" values="0 0 0 0 0  0 0 0 0 0   0 0 0 0 1   0 0 0 1 0" result="blue-original"/>
    <feImage x="-100" y="0" width="800" height="600" xlink:href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/32648/SVG-Test%201.svg">
    </feImage>
       <feColorMatrix type="matrix" values="0 0 0 0 1  0 0 0 0 0   0 0 0 0 0   0 0 0 1 0"/> 
    <feComposite operator="xor" in="blue-original"/>
  </filter>
  </defs>



<image  xlink:href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/32648/SVG-test2.svg" x="-100" y="0" width="800" height="600" preserveAspectRatio="xMinYMin slice"/>
  
  <image  xlink:href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/32648/SVG-Test%201.svg" x="500" y="0" width="800" height="600" preserveAspectRatio="xMinYMin slice"/>
  
</svg>
...