Ответы пользователя по тегу SVG
  • Обработка тайлов на SVG. Видны прорези между ними, что делать?

    sfi0zy
    @sfi0zy Куратор тега HTML
    Creative frontend developer
    Это похоже на известную проблему с рендерингом разных штук в браузерах. Тут два связанных момента - с одной стороны есть вопрос подгонки размеров элементов под пиксельную сетку на экране, и потенциальные ошибки с округлениями значений и "дырками" или "нахлестами" в 1px между сущностями на экране, а с другой - собственно сглаживание, когда у нас появляются промежуточные цвета, смягчающие переходы от одних к другим. Иногда, как в таких ситуациях, мы можем воспринимать их как неуместные.

    С размерами мы еще можем попытаться что-то сделать. Например распространенный костыль состоит в том, чтобы по возможности иметь размеры элементов в целом количестве пикселей. Т.е. не давать браузеру округлять на свой вкус. А вот сглаживание мы не можем выключить просто так. Вы нашли атрибут shape-rendering, но если внимательно почитать в стандарте, что он предполагает, то там будут исключительно рекомендательные высказывания:

    the user agent might turn off anti-aliasing


    или

    might adjust line positions and line widths to align edges with device pixels


    Но "might" не означает "must". На практике сглаживание или не отключается полностью, или отключается, но границы по пикселям смещаются так, что становится еще хуже, чем было, или еще какая фигня происходит. В разных браузерах все по-разному и поведение немного меняется со временем, так что старые костыли могут переставать работать. В CSS есть свойства, связанные со словом rendering, и они такие же мутные в своих формулировках.

    На практике это означает, что единственный вариант взять контроль над рендерингом в свои руки - это рисовать все на канвасе. И хотя вы говорите, что "канвас не рассматриваем", именно он и будет надежным вариантом решить такого рода проблемы раз и навсегда.
    Ответ написан
    2 комментария
  • Как распределить элементы на адаптивной, векторной кривой?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    Хорошего нативного и кроссбраузерного решения у нас пока нет. Но у path в SVG есть методы getTotalLength и getPointAtLength, а из них можно сообразить себе утилиту для расположения кружков вдоль кривой в удобных единицах измерения. Это не так здорово, как на CSS, но тем не менее:

    function putCircleOnPath(path, circle, percent) {
        const length = path.getTotalLength();
        const point = path.getPointAtLength(length * percent / 100);
    
        circle.setAttribute('cx', point.x);
        circle.setAttribute('cy', point.y);
    }


    Получится что-то такое:

    Ответ написан
    2 комментария
  • Почему свойство transform-origin не работает для rotate() внутри svg-изображения?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    В SVG условный transform-origin всегда находится в координатах (0,0) координатной плоскости. Его нельзя изменить. Если мы пытаемся задать его в CSS, то логика работы трансформаций в CSS входит в явный конфликт с логикой работы трансформаций в SVG, и там каждый браузер интерпретирует происходящее на свой вкус (тут есть старая, но все еще годная статья по теме). В последние годы, со всеми этими сменами движков у браузеров, вкусы начинают двигаться в одну сторону, но бардак все еще присутствует. Но всегда можно сделать старую добрую матрешку:

    <!-- 90 = x + width, 168 = y + height - правый нижний угол книги -->
    <g transform="translate(90, 168.5)">
        <g id="book">
            <rect class="fil0 str0" x="60" y="18.5" width="30" height="150" transform="translate(-90, -168.5)" />
        </g>
    </g>


    Убираем transform-origin из CSS, чтобы не было конфликтов, смещаем нужный центр трансформации в координаты (0, 0), применяем там трансформацию, смещаем обратно, где он должен быть.
    Ответ написан
    3 комментария
  • Как работать с gulp cheerio?

    sfi0zy
    @sfi0zy
    Creative frontend developer
    gulp cheerio как то странно работает, он портит некоторые svg иконки, их не видно, у них нет цвета и fill(заливка) на них не работает, может вообще его не использовать?

    Вы несколько раз используете метод removeAttr, чтобы удалить атрибуты fill у элементов (если у них черная заливка, заданная в формате #000 или #000000), а также все атрибуты stroke и style из кода. А теперь вы задаете вопрос, а почему у вас пропадают цвета? Очевидно они пропадают потому, что вы сами написали код, который их удаляет.
    Ответ написан
    Комментировать
  • Как сделать SVG-схему поезда кликабельной?

    sfi0zy
    @sfi0zy
    Creative frontend developer
    цифры мешают нажимать на места, а z-index изменить не получается

    У SVG-элементов есть атрибут pointer-events. Работает он по той же логике, что и в CSS. Так что можно выключить интерактивность цифр, или что там еще мешает.

    А "z-index" там работает по принципу "что раньше нарисовано - то ниже, что позже нарисовано - то выше". А отрисовывается все в том порядке, в котором оно в SVG-коде написано.
    Ответ написан
    1 комментарий
  • Почему не работает font awesome?

    sfi0zy
    @sfi0zy Куратор тега HTML
    Creative frontend developer
    В начале файла стилей видно, что вы подключаете Font Awesome Free 6.2.1. Иконка fa-forward в нее входит, а вот иконка fa-arrows-repeat-1 уже входит в Pro-версию, а не Free. Для ее использования вам нужно $99 в год.
    Ответ написан
    1 комментарий
  • Как сделать анимированную трансформацию svg при hover?

    sfi0zy
    @sfi0zy
    Creative frontend developer
    Для начала нужно определиться с двумя вещами:
    1. Safari не очень дружит с морфингом SVG из CSS. Это относится не только к clip-path, но и к любому изменению контуров в самих SVG. Поэтому вариант делать это на CSS - такой себе вариант.
    2. Для того, чтобы морфинг работал, нам нужно, чтобы контуры в SVG имели одинаковую структуру. Это первое правило морфинга. Почему это так, и в чем смысл морфинга в целом - можно почитать тут. Если вы делаете капли в blobmaker.app, то вам нужно иметь кляксы, сделанные с одним положением левого ползунка, который меняет количество точек. Правый двигать можно, рандомизировать можно, но количество точек должно быть постоянным.

    Ну а дальше весь вопрос будет в том, с помощью чего организовать конечный расчет промежуточных значений для наших кривых. Можно взять любую библиотеку для интерполяций значений, например anime.js:

    Ответ написан
    Комментировать
  • Почему текст в svg экспортируется как path?

    sfi0zy
    @sfi0zy
    Creative frontend developer
    При экспортировании там есть настройки (три точки вызывают всплывающий список параметров), и там есть пункт "Outline Text". Он как раз отвечает за то, будут ли буквы как буквы, или они будут конвертироваться в path. По умолчанию они конвертируются.
    Ответ написан
    Комментировать
  • Не отображается встроенное изображение в .svg на сайте?

    sfi0zy
    @sfi0zy
    Creative frontend developer
    На MDN говорят, что это вопрос безопасности (там только про Gecko, но можно предположить, что везде так). Если SVG используется как картинка, то в ней уже нельзя подгрузить другие внешние ресурсы. Как вариант можно использовать тег embed вместо img, и все будет работать без таких ограничений.
    Ответ написан
    Комментировать
  • Как заменить опреденный цвет на другой с помощью фильтра feColorMatrix?

    sfi0zy
    @sfi0zy
    Creative frontend developer
    Можно как-то так нашаманить:

    Идея в том, что просто фильтр с feColorMatrix будет применяться вообще ко всему, нужно сначала выбрать область с конкретным цветом, там его заменить и наложить на оригинальное изображение.

    Но важно понимать, что любые такие штуки с частичными наложениями изображения на само себя могут влететь в проблемы с размерами в нецелое количество пикселей и будут появляться артефакты в 1px по краям замененного цвета. Иногда это не важно, задачи разные бывают, но если вам нужно, чтобы было красиво и надежно, то лучше это делать на канвасе (а еще лучше - сразу в WebGL контексте) - там можно пройти по всем пикселям своими руками и заменить цвета без накладывания слоев. Это будет более замороченное решение, учитывая необходимость конвертировать SVG в изображение на канвасе, но по надежности его не превзойти.
    Ответ написан
    Комментировать
  • С чего начать изучения анимации svg?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    По сути SVG - это почти HTML (ок, нехорошо так говорить, но тем не менее). Дерево из тегов, атрибуты, все дела. Выбираем нужные элементы, меняем атрибуты - вот и вся анимация. Как и с любыми другими элементами на странице. Это не какой-то отдельный и ни на что не похожий тип анимаций.

    Есть три варианта анимирования SVG в рамках фронтенда, два идентичных обычному HTML, и один дополнительный, привнесенный извне:

    1. CSS. Картинку, вставленную в страницу, можно анимировать с помощью CSS в каких-то пределах. Не все так получится сделать, но какие-то простые движения, изменения цветов - вполне можно. Если вы знаете CSS - можно сказать, что уже знаете все, что тут можно сделать.
    2. JS. Все как всегда. Получаем элементы через querySelector, getElementBy... и.т.д., и через setAttribute задаем элементам SVG нужные атрибуты. Обычно удобно добавить какой-то инструмент для интерполяций значений во времени. Из популярного - GSAP и Anime.js. При желании можно что-то свое написать, если задачи совсем простые, в базовом варианте все подобные инструменты строятся примерно по такому принципу. Некоторые инструменты добавляют какие-то еще свои дополнительные возможности, или есть готовые прикольные примеры, сделанные с их использованием, как например у d3.js, но нужны ли они лично вам - нельзя сказать, не зная задач. А инструменты должны выбираться исходя из этих самых задач, а не из моды. Здесь важно лишь понимать, что никакие библиотеки не расширяют сам формат SVG, не привносят никаких принципиально новых возможностей в него, они все больше про организацию скриптов.
    3. Еще есть SMIL. Это древнее зло из миров, далеких фронтенду. Есть хороший туториал на CSS-tricks. Это все "модно-нативно", но иногда сложно синхронизировать с остальными событиями на странице, и сложно отлаживать, т.к. нет адекватной привязки к инструментам разработчика в браузерах.


    Полезно еще познакомиться с вот этой статьей, там отмечены некоторые косяки, связанные с кроссбраузерностью. Да, SVG - это штука, которая вроде бы была с нами всегда, но в контексте анимирования wtf-моментов там все еще достаточно.

    И есть две популярные фишки, которые часто все используют в анимациях - это маски и пунктиры. Способ анимирования не важен, но знать про них полезно.

    Ну и полезно познакомиться с каким-нибудь векторным графическим редактором, чтобы уметь структурировать SVG перед анимированием, удалять мусор, адаптировать контуры для морфинга (не всегда дизайнер будет предоставлять полный набор нужных контуров).
    Ответ написан
    1 комментарий
  • Как реализовать подобную анимацию?

    sfi0zy
    @sfi0zy Куратор тега HTML
    Creative frontend developer
    Это реализуется с помощью свойств stroke-dasharray и stroke-dashoffset в SVG. Слушаем событие скролла - меняем значения. Подробнее в статье про пунктирные вау-эффекты. Вам нужна пятая демка - там как раз вот почти то же самое рисуется при скролле. На сайте Яндекс.Практикума эту линию поделили на небольшие части для удобства/оптимизации, но принцип тот же.
    Ответ написан
    Комментировать
  • Почему SVG фильтр не работает?

    sfi0zy
    @sfi0zy
    Creative frontend developer
    Не работает из соображений безопасности. Подробности и многолетние обсуждения со спорами по теме можно загуглить по запросу "CORS SVG".

    Простых решений вашего вопроса два - или грузить картинку с того же домена, что и страница, или сконвертировать ее в base64 и вставить непосредственно в SVG:

    <svg width="0" height="0" viewBox="0 0 450 300">
      <filter id="displacement-map">
        <feImage xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQ..." x="0" y="0" width="100%" height="100%" preserveAspectRatio="none"></feImage>
        <feColorMatrix type="saturate" values="0" result="IMAGE"/>
        <feGaussianBlur stdDeviation=".5" in="IMAGE" result="MAP"></feGaussianBlur>
        <feDisplacementMap in="SourceGraphic" in2="MAP" scale="15" xChannelSelector="R" yChannelSelector="R" result="TEXTURED_TEXT"></feDisplacementMap>
      </filter>
    </svg>
    Ответ написан
    6 комментариев
  • Как анимировать появление логотипа (свг)?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    Общая концепция будет примерно такая:
    @keyframes custom-fade-in {
        0% {
            stroke-dasharray: 0 300;
            fill: transparent;
            animation-timing-function: ease-in;
        }
        50% {
            stroke-dasharray: 150 150;
            fill: transparent;
            animation-timing-function: ease-out;
        }
        100% {
            stroke-dasharray: 300 0;
            fill: #000;
        }
    }
    
    path {
        stroke: #000;
        fill: none;
        stroke-dasharray: 0 300;
        animation: custom-fade-in 2s ease-in-out infinite;
        animation-fill-mode: forwards;
    }


    Но если взять контуры как есть, то они будут заливаться не там, где нужно по дизайну. Нужно открыть эту SVG в векторном графическом редакторе и слегка порезать эти контуры. Нужно чтобы каждая буква была обрисована линией по кругу один раз, а не два, как сейчас. Тогда заливка будет по всей букве. А то сейчас заливается пространство между двумя почти продублированными контурами букв, т.к. технически именно оно является внутренной частью path. А еще будет удобно каждую букву делать отдельным контуром - проще будет подобрать значения для stroke-dasharray.
    Ответ написан
    3 комментария
  • Прорисовка SVG?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    Нужно с помощью метода getTotalLength() узнать длину path (она равна 3904) и подставить ее везде, вместо вашего магического числа 1000.
    Ответ написан
    5 комментариев
  • GreenSock или anime.js?

    sfi0zy
    @sfi0zy Куратор тега JavaScript
    Creative frontend developer
    очень сложный с анимационной части сайт

    Ну "очень сложный" - понятие растяжимое. Если нужен сложный морфинг или физика в 2d - однозначано берите GSAP, у него есть готовые плагины для этого (а значит не нужно думать об интегрировании чего-то со стороны). А так в большинстве повседневных задач вы разницы между этими инструментами не заметите, тут скорее на вкус и цвет: GSAP - это более "энтерпрайзно-замороченный" инструмент с кучей кнопок, а anime.js скорее ближе к unix-way - маленький и решающий одну задачу.
    Ответ написан
    4 комментария
  • Как правильно настроить внутреннюю тень SVG?

    sfi0zy
    @sfi0zy
    Creative frontend developer
    Тут все дело в том, что вы используете для создания тени не саму кривую штуку, а "прозрачность" вокруг нее. Это немного нелогично с точки зрения понятия "тень". То есть у вас тень отбрасывает "пустота" вокруг кривой штуки (и эта "пустота" еще и обрезается в неудачном месте). Тут нужно использовать обратный подход, когда именно кривая штука используется для создания тени. В вашем примере для этого нужно поменять tableValues в feFuncA с "1 0" на "0 1" и в первом feComposite заменить "in" на "out".

    Как альтернативный пример:


    Вобщем сделать это можно по-разному, главное в конце проверить кроссбраузерность на всякий случай.
    Ответ написан
    7 комментариев
  • Как уменьшить svg код?

    sfi0zy
    @sfi0zy
    Creative frontend developer
    Пример километрового SVG


    Это не SVG. Это обычная растровая png картинка, которую закодировали в base64 и вставили в SVG. Сжать никак не получится (ну то есть насколько вы растровую картинку сожмете?). Вам нужно эту штуку нарисовать изначально в векторе, тогда она будет маленькая и аккуратненькая.
    Ответ написан
    3 комментария
  • Почему сафари сжимает SVG?

    sfi0zy
    @sfi0zy
    Creative frontend developer
    У Safari есть проблемы с отображением SVG-картинок внутри flex-контейнеров. Стандартное решение - сделать непосредственным родительским элементам этих картинок display:block или inline-block.
    Ответ написан
    Комментировать
  • Интерактивная карта с svg и css?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    Подскажите как реализовать SVG интерактивную карту без использования обычной картинки. У многих в уроках используют картинку и поверх уже прописывают svg элементы. Я же хочу сделать полностью на svg фон и элементы к нему но вот не знаю как правильно сделать это...

    Если взять интерактивную карту, состоящую из картинки и SVG поверх нее (как в этой статье), и убрать картинку, то останется интерактивная карта, состоящая только из SVG. Это вроде как очевидно. Вы можете дорисовывать или раскрашивать элементы в SVG на свой вкус, но принцип работы интерактивной части останется тем же.
    Ответ написан
    Комментировать