Нежелательное поведение альфа-маски SVG в Safari - PullRequest
1 голос
/ 08 мая 2019

Я пытаюсь применить одну маску к двум перекрывающимся <rect> элементам SVG. Я создал упрощенный живой пример со следующим кодом:

<svg viewBox="0 0 100 100" style="background: #000">
	<defs>
		<!-- 	Define radial gradient	 -->
		<radialGradient id="radialFill">
			<stop stop-color="white" offset="0.8"/>
			<stop stop-color="black" offset="1"/>
		</radialGradient>
		
		<!-- 	Define mask with gradient	 -->
		<mask id="SVGMask" mask-type="luminance">
			<circle fill="url(#radialFill)" cx="50" cy="50" r="50"/>
		</mask>
	</defs>
	
	<!-- 	Use mask on group	 -->
	<g id="combined" style="mask: url(#SVGMask);">
		<rect id="rect" width="100" height="100" fill="#f90"/>
		<rect id="rect" width="50" height="100" fill="#fff"/>
	</g>
</svg>
<figcaption>Mask 2+ elements Safari bug</figcaption>

В приведенном выше коде у меня есть оранжевый <rect> для цвета фона, белый <rect>, занимающий половину viewBox, затем я оборачиваю их в <g> и примените маску ко всей группе.

Эта настройка прекрасно работает как в Firefox, так и в Chrome, но не работает в Safari.Как вы можете видеть, оранжевый фон показывает сквозь белый, а затем исчезает.Похоже, что маска применяется отдельно к передним и задним каналам, а не один раз для всей группы.

enter image description here

Есть ли у кого-нибудь решение илиобойти эту ошибку?Это происходит как в OSX Safari, так и в iOS Safari.(Мой вариант использования более сложный, чем этот, но я создал этот упрощенный пример, чтобы продемонстрировать ошибку).

1 Ответ

1 голос
/ 09 мая 2019

Для этого есть (хакерский) обходной путь - но он работает. Задача состоит в том, чтобы заставить маску обрабатывать свой ввод как растровое изображение, а не как наложенные фигуры. Вы можете запустить Safari, вставив фиктивный фильтр в группу между группой фигур и маской. Сделайте следующие изменения:

Добавьте это в свои SVG-определения:

<filter id="dummy-filter>
   <feColorMatrix type="saturate" values="1"/>
</filter>

и измените вашу разметку на это:

<g id="combined" ... etc.
 <g filter="url(#dummy-filter)">
   <rect ... etc.
   <rect ... etc.
 </g>
</g>
...