Почему фильтр ломает трюк с полупикселем для четких штрихов в 1 пиксель?

Вместо этого я использую трюк «сместить все на полпикселя», описанный в второй ответ на этот вопрос, чтобы получить четкую обводку в 1 пиксель на фигуре.

(Здесь задействованы закругленные края, поэтому решение shape-rendering: crispEdges здесь нецелесообразно — из-за него изогнутые части штрихов выглядят ужасно.)

Как получается, что добавление фильтра (я использую фильтр размытия по Гауссу + фильтр смещения для реализации тени) ломает хак со смещением в полпикселя?

Вы можете поиграть с jsfiddle.

<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
  <defs>
    <filter id="f1" x="-20%" y="-20%" width="160%" height="160%">
      <feOffset result="offOut" in="SourceAlpha" dx="10" dy="10" />
      <feGaussianBlur result="blurOut" in="offOut" stdDeviation="2" />
      <feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
    </filter>
  </defs>
  <g transform="translate(5.5,5.5)">
    <!-- This one has a blurry stroke -->
    <rect width="50" height="50" rx="5" ry="5" stroke="black" stroke-width="1" fill="steelblue" filter="url(#f1)" />
    <!-- This one has a crisp stroke -->
    <rect x="150" width="50" height="50" rx="5" ry="5" stroke="black" stroke-width="1" fill="steelblue" />
  </g>
</svg>

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


person Caleb Spare    schedule 25.06.2012    source источник
comment
Я заработал (по крайней мере, в Chrome), установив filterRes достаточно высоким (2 * общая высота изображения + тень). Посмотрите эту скрипту. Хотя я не совсем понимаю, зачем это нужно.   -  person Caleb Spare    schedule 25.06.2012
comment
Вы уже поняли это, но размытие, которое вы видели, на самом деле не связано с привязкой пикселей. При применении фильтров браузеры устанавливают разумное разрешение фильтра, чтобы сохранить память и скорость, которая в вашем случае была слишком низкой. Я расширил ваш jsfiddle, чтобы проиллюстрировать эффекты filterRes jsfiddle.net/5ueck   -  person methodofaction    schedule 25.06.2012
comment
Кроме того, лучшая практика при самостоятельном выяснении вещей - опубликовать свой ответ, а затем принять его (боюсь, через два дня).   -  person methodofaction    schedule 25.06.2012
comment
filterRes теперь устарел и был удален из пограничных браузеров.   -  person Michael Mullany    schedule 27.05.2016


Ответы (1)


Если вам не нравятся размытые края, вы всегда можете поэкспериментировать с добавлением feComponentTransfer с feFuncA, чтобы вручную управлять размытием краев. Ака:

<filter id="fee" x="-20%" y="-20%" width="160%" height="160%">
    <feComponentTransfer>
          <feFuncA type="table" tableValues="0 0 1" />
    </feComponentTransfer>
</filter>
person Michael Mullany    schedule 07.05.2013