Проблема с linearGradient (SVG) в IOS устройствах
Два примера простых SVG с text элементом, textPath для создания дуги, а также установленным атрибутом textLength.
В первом случае, цвет текста изменяется при помощи заданного linearGradient. Во втором случае, при помощи самого простого fill атрибута.
Проблема с отображением первого примера наблюдается на IOS устройствах (Iphone 12, Iphone XR, наверное и на других). Браузеры хром и сафари. Скриншоты прикладываю, обрезается текст в примере 1, в примере 2 все хорошо.
На десктопе в браузерах или на андроид устройствах проблема не наблюдается, попробовал порядка 5 разных устройств.
Вопрос - есть ли какое-то решение как поправить отображение цвета с градиентом на IOS устройствах? Причем как видно, в градиенте всего 1 цвет. Возможно есть какой-то css параметр или атрибут градиента, который это фиксит?
Пример 1.
<svg width="300px" height="300px" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 400 400" color="red">
<defs>
<linearGradient id="fill">
<stop stop-color="red"></stop>
</linearGradient>
</defs>
<text font-size="28" font-style="normal" font-weight="normal" fill="url(#fill)" transform="rotate(-11, 200, 200)" textLength="463.5587568803267"><defs><path id="text" d="M 200 200 m -168, 0 a 168,168 0 1,0 336,0 a 168,168 0 1,0 -336,0"></path></defs><textPath href="#text" xlink:href="#text" textLength="463.5587568803267">Пример текста по кругу</textPath></text>
</svg>
Пример 2.
<svg width="300px" height="300px" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 400 400" fill="red">
<text font-size="28" font-style="normal" font-weight="normal" transform="rotate(-11, 200, 200)" textLength="463.5587568803267"><defs><path id="text" d="M 200 200 m -168, 0 a 168,168 0 1,0 336,0 a 168,168 0 1,0 -336,0"></path></defs><textPath href="#text" xlink:href="#text" textLength="463.5587568803267">Пример текста по кругу</textPath></text>
</svg>
Скриншот отображения примера 1 на IOS
Скриншот отображения примера 2 на IOS
Скриншот примера от Alexandr_TT на IOS
Ответы (2 шт):
Причем как видно, в градиенте всего 1 цвет
Вот в этом и есть главная причина. Кроме того упущен важный параметр offset
Если необходимо, чтобы было кросс браузерное решение, нужно задавать параметры linearGradient в соответствии со спецификацией, указывая все атрибуты градиента:
<linearGradient id="fill">
<stop offset ="0" stop-color="red"></stop>
<stop offset="100%" stop-color="blue"></stop>
</linearGradient>
Ещё можно отметить, что текст на кривой нужно позиционировать не трансформацией вращения - transform="rotate(-11, 200, 200)", а с помощью - startOffset
color="red" - нужно убрать из шапки SVG. Зачем сразу красить весь блок svg в красный цвет. У вас этим, по идее должен заниматься градиент.
Иначе потом, можно долго искать причину, почему невозможно стилизовать файл из CSS/
<svg width="300px" height="300px" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 400 400" >
<defs>
<linearGradient id="fill">
<stop offset ="0" stop-color="red"></stop>
<stop offset="100%" stop-color="blue"></stop>
</linearGradient>
<path id="text" stroke="black" d="M 200 200 m -168, 0 a 168,168 0 1,
0 336,0 a 168,168 0 1,0 -336,0"/>
</defs>
<text font-size="36" font-style="normal" font-weight="normal" fill="url(#fill)" textLength="463.5587568803267">
<textPath href="#text" xlink:href="#text" textLength="463.5587568803267" startOffset="2.5%">
Пример текста по кругу
</textPath>
</text>
</svg>
Пример анимации текста
Используется изменение значений параметра startOfset
<animate id="anT" attributeName="startOffset" begin="svg1.click;anT.end+0.5s"
dur="4s" values="2.5%;100%" fill="freeze" repeatCount="1" />
Анимация начнётся после клика
<svg id="svg1" width="300px" height="300px" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 400 400" style="border:1px solid" >
<defs>
<linearGradient id="fill">
<stop offset ="0" stop-color="red"></stop>
<stop offset="100%" stop-color="blue"></stop>
</linearGradient>
<path id="text" stroke="black" d="M 200 200 m -168, 0 a 168,168 0 1,
0 336,0 a 168,168 0 1,0 -336,0"/>
</defs>
<text font-size="36" font-style="normal" font-weight="normal" fill="url(#fill)" textLength="463.5587568803267">
<textPath href="#text" xlink:href="#text" textLength="463.5587568803267" startOffset="2.5%">
Пример текста по кругу
<animate id="anT" attributeName="startOffset" begin="svg1.click;anT.end+0.5s" dur="4s" values="2.5%;100%" fill="freeze" repeatCount="1" />
</textPath>
</text>
</svg>
textLength
Теория -textLength
Атрибут textLength, доступный для элементов SVG и , позволяет указать ширину пространства, в котором будет отображаться текст. Пользовательский агент будет следить за тем, чтобы текст не простирался дальше этого расстояния, используя метод или методы, указанные атрибутом lengthAdjust. По умолчанию регулируется только интервал между символами, но размер глифа также можно настроить, если изменить lengthAdjust.
На практике в разных браузерах текст масштабируется и позиционируется немного по разному. Например FF, Chrome и Safari. Настроив положение текста в одном браузере, в другом браузере текст может быть сдвинут.
Поэтому лучше отказаться от этого атрибута и заменить его на атрибуты CSS
letter-spacing: 4px;
word-spacing: 2px;
Которые работают одинаково во всех браузерах.
Изменяя значения этих атрибутов, а также font-size, startOfset можно достичь желаемого результата.
#txt {
font-size:36px;
font-style:normal;
font-weight:normal;
fill:url(#fill);
letter-spacing: 4px;
word-spacing: 2px;
}
<svg id="svg1" width="300px" height="300px" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 400 400" >
<defs>
<linearGradient id="fill">
<stop offset ="0" stop-color="red"></stop>
<stop offset="100%" stop-color="blue"></stop>
</linearGradient>
<path id="text" stroke="black" fill="none" d="M 200 200 m -168, 0 a 168,168 0 1,
0 336,0 a 168,168 0 1,0 -336,0" />
</defs>
<text id="txt">
<textPath href="#text" xlink:href="#text" startOffset="3%">
Пример текста по кругу
</textPath>
</text>
</svg>
UPDATE
Добавил в градиент
gradientUnits="objectBoundingBox" x1="0" y1="0" x2="1" y2="0"
Изменил path для кривой, как-то он был странновато написан
d="M 200 200 m -168, 0 ?? В качестве начальной точки есть дублирующая запись
абсолютных M 200 200 и относительных координат - m -168, 0
может это причина бага Safari в IOS?
Просьба:
У кого есть айфон с Safari, Chrome проверьте пожалуйста код ниже на предмет исчезновения крайних букв.
#txt {
font-size:36px;
font-style:normal;
font-weight:normal;
fill:url(#fill);
letter-spacing: 4px;
word-spacing: 2px;
}
<svg id="svg1" width="300px" height="300px" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 400 400" style="border: 1px solid">
<defs>
<linearGradient id="fill" gradientUnits="objectBoundingBox" x1="0" y1="0" x2="1" y2="0">
<stop offset ="0%" stop-color="red"></stop>
<stop offset="100%" stop-color="blue"></stop>
</linearGradient>
<path id="text" stroke="black" fill="none" d="M20,200 A180,180 0 1 0 380,200" />
</defs> <text id="txt">
<textPath href="#text" xlink:href="#text" startOffset="10%">
Пример текста по кругу
</textPath>
</text>
</svg>