Сохранение html страницы с svg (с использованием mask) как pdf и проблемы при открытии в редакторах векторной графики
Есть страница с svg элементом.
<!doctype html>
<html lang="ru" dir="ltr">
<head>
<meta charset="utf-8">
</head>
<body>
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="10 10 380 380" color="#1f26b4" version="1.1"><metadata><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:title/></cc:Work></rdf:RDF></metadata><g><g data-type="round"><defs><mask id="round-mask_25KtbDrFpl"><circle fill="white" r="190" cx="200" cy="200"/></mask></defs><circle mask="url(#round-mask_25KtbDrFpl)" stroke-linejoin="round" r="190" cx="200" cy="200" fill="none" stroke-width="362" stroke="#1f26b4" stroke-dasharray="0"/></g><g data-type="round"><defs><mask id="round-mask_aRXKnJsro9"><circle fill="white" r="186" cx="200" cy="200"/></mask></defs><circle mask="url(#round-mask_aRXKnJsro9)" stroke-linejoin="round" r="186" cx="200" cy="200" fill="none" stroke-width="8" stroke="#ffffff" stroke-dasharray="0"/></g></g></svg>
</body>
</html>
https://jsfiddle.net/4o2ebxdu/1/
Круги сделаны через маски. Этот подход отлично работает в браузерах и программах для просмотра svg. Всё отображается корректно.
Если взять данную html страницу и открыть в chrome/chromium`e, сохранить как PDF, то получится вот такой PDF, который также корректно отображается в браузере или программах для просмотра PDF. https://dropmefiles.com/4EpAb
Однако, если открыть этот PDF через Adobe Illustrator, Corel Draw или другие программы для работы с графикой, то начинаются проблемы. Выглядит вот так:
Возможно, это проблема иллюстратора, корела или хрома/хромиума. Однако, если маски не использовать, то подобных проблем естественно не наблюдается. Но подход с масками очень удобный.
Вопрос: нет ли каких-то хитростей чтобы избежать этого эффекта? Я пытался добавлять для mask overflow:hidden, пытался делать mask блочным элементом, это не помогает.
Пытался использовать use внутри маски, как было сказано в этом подобном вопросе https://stackoverflow.com/questions/63467045/incorrect-svg-mask-position-on-load-when-using-relative-positions-chrome
Тоже нет эффекта. PDF визуально правильный, но использовать его невозможно, ведь любые программы для работы с графикой отображают pdf неверно.
Причём, если открыть сам SVG в редакторе, то отображается корректно. Делаю вывод, что это баг хромиума/хрома. Но может есть какой-то хак-решение. Вот открытый .svg в иллюстраторе:
UPD.
Скрин из иллюстратора примеров с картинками.
Ответы (1 шт):
Вот так выглядит ваш файл svg
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="10 10 380 380" color="#1f26b4" version="1.1"><metadata><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:title/></cc:Work></rdf:RDF></metadata><g><g data-type="round"><defs><mask id="round-mask_25KtbDrFpl"><circle fill="white" r="190" cx="200" cy="200"/></mask></defs><circle mask="url(#round-mask_25KtbDrFpl)" stroke-linejoin="round" r="190" cx="200" cy="200" fill="none" stroke-width="362" stroke="#1f26b4" stroke-dasharray="0"/></g><g data-type="round"><defs><mask id="round-mask_aRXKnJsro9"><circle fill="white" r="186" cx="200" cy="200"/></mask></defs><circle mask="url(#round-mask_aRXKnJsro9)" stroke-linejoin="round" r="186" cx="200" cy="200" fill="none" stroke-width="8" stroke="#ffffff" stroke-dasharray="0"/></g></g></svg>
Мешает служебная информация, которую оставил векторный редактор и возможно была выбрана опция Remove whitespace
Чтобы, как-то разобраться в коде оптимизировал ваш файл с помощью SVG-EDITOR
Вот что получилось:
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" width="380" height="380" viewBox="10 10 380 380" color="#1f26b4" style="border:1px solid">
<g data-type="round">
<defs>
<mask id="round-mask_25KtbDrFpl">
<circle fill="white" r="190" cx="200" cy="200"/>
</mask>
</defs>
<circle mask="url(#round-mask_25KtbDrFpl)" stroke-linejoin="round" r="190" cx="200" cy="200" fill="none" stroke-width="362" stroke="#1f26b4" stroke-dasharray="0"/>
</g>
<g data-type="round">
<defs>
<mask id="round-mask_aRXKnJsro9">
<circle fill="white" r="186" cx="200" cy="200"/>
</mask>
</defs>
<circle mask="url(#round-mask_aRXKnJsro9)" stroke-linejoin="round" r="186" cx="200" cy="200" fill="none" stroke-width="8" stroke="#ffffff" stroke-dasharray="0"/>
</g>
</svg>
Рамка это граница холста SVG, который имеет физические размеры 380х380 при
<mask id="round-mask_25KtbDrFpl">
<circle fill="white" r="190" cx="200" cy="200"/>
</mask>
Края окружности находится вплотную 190 * 2 = 380 к границам холста.
Хоть вы и не указали здесь stroke по умолчанию она равна 1px.
Внешняя половина этой строки находится вне холста SVG и поэтому подрезается.
Мы с вами не знаем, как происходит конвертация в pdf. Может при конвертации, эта распространенная ошибка как-то учитывается, поэтому файл PDF выглядит нормально. Но при обратной конвертации в векторный редактор эта ошибка вылазит наружу.
Тем более вы заполняете фигуру широкой строкой 362px, половина её тоже выходит наружу, потом вы режете её другой маской, короче процесс очень запутанный. Поэтому возможны любые сюрпризы, тем более браузеры не всегда одинаково отрабатывают эти процессы.
Вывод один, старайтесь подбирать размеры SVG холста таким образом, чтобы был гарантированный зазор между краем холста и внешней части SVG элемента.
И вообще, это плохая практика, заполнять фигуру очень широкой строкой, так как её вторая половина выходит наружу и с ней надо что-то делать.
Есть же команда fill="#1f26b4" и не надо никаких масок. Они нужны для более продвинутых вещей.
Вот пример, пробуйте проделать с ним те же конвертации в pdf и обратно
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" width="380" height="380" viewBox="0 0 380 380" style="border:1px solid">
<circle fill="#1f26b4" r="180" cx="190" cy="190"/>
<circle fill="none" stroke="white" stroke-width="4" r="170" cx="190" cy="190"/>
<circle fill="white" r="12" cx="190" cy="190"/>
</svg>
Пример для проверки, мешает ли маска
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" width="380" height="380" viewBox="0 0 380 380" style="border:1px solid">
<defs>
<mask id="msk">
<rect width="100%" height="100%" fill="black" />
<circle fill="white" r="160" cx="190" cy="190"/>
</mask>
</defs>
<circle fill="#1f26b4" r="180" cx="190" cy="190"/>
<circle fill="none" stroke="white" stroke-width="4" r="170" cx="190" cy="190"/>
<image mask="url(#msk)" y="30" href="https://i.stack.imgur.com/Vccyb.jpg" width="100%"
<height="100%" />
</svg>




