Retina и высокая плотность пикселей

Высокая плотность пикселей на современных дисплеях, таких как Retina и 4K-экраны, требует особого подхода при работе с графикой. SVG.js предоставляет гибкие инструменты для масштабирования векторной графики и обеспечения её четкости на любых экранах. Основная идея заключается в том, чтобы не использовать фиксированные пиксельные размеры, а опираться на относительные единицы и масштабирование векторного контента.


Настройка размера холста для Retina

При создании холста через SVG().addTo(selector).size(width, height) необходимо учитывать фактическое разрешение экрана. На устройствах с высокой плотностью пикселей один CSS-пиксель отображается как несколько физических пикселей. Чтобы изображение выглядело чётким:

const ratio = window.devicePixelRatio || 1;
const draw = SVG().addTo('#canvas')
                  .size(400 * ratio, 300 * ratio)
                  .viewbox(0, 0, 400, 300);
draw.node.style.width = '400px';
draw.node.style.height = '300px';

Пояснение:

  • window.devicePixelRatio возвращает отношение физических пикселей к CSS-пикселям.
  • Настройка viewbox позволяет использовать исходные координаты и сохраняет масштабируемость.
  • Стиль width и height возвращает отображение к CSS-размерам, а фактический холст будет иметь повышенное разрешение.

Масштабирование элементов SVG

SVG.js позволяет применять масштабирование ко всем объектам через метод scale() или используя координаты при создании элементов.

const rect = draw.rect(100, 50).fill('#3498db');
rect.scale(ratio, ratio);

Важные моменты:

  • Масштабирование через scale увеличивает размеры элементов пропорционально фактическому разрешению экрана.
  • Можно использовать относительные единицы (%, em) при работе с координатами для более гибкого контроля.

Использование viewBox и preserveAspectRatio

Для корректного отображения на экранах с разной плотностью пикселей важно грамотно задавать viewBox и атрибут preserveAspectRatio:

draw.viewbox(0, 0, 400, 300)
    .attr({ preserveAspectRatio: 'xMidYMid meet' });

Ключевые моменты:

  • viewBox определяет систему координат внутреннего SVG.
  • preserveAspectRatio контролирует выравнивание и масштабирование внутри контейнера.
  • При изменении размеров контейнера графика остаётся чёткой благодаря векторной природе.

Работа с шрифтами и текстом

Текстовые элементы на Retina-дисплеях часто теряют чёткость, если использовать фиксированные пиксели. SVG.js поддерживает относительные единицы для текста:

draw.text('Пример текста')
    .font({ size: 2 + 'em', family: 'Arial' });

Особенности:

  • Единицы em и rem масштабируются вместе с размером контейнера.
  • Для точной подстройки под плотность пикселей можно использовать умножение на devicePixelRatio.

Оптимизация производительности

Высокая плотность пикселей увеличивает нагрузку на рендеринг. Для оптимизации SVG.js предлагает следующие приёмы:

  1. Группировка элементов через group():

    const group = draw.group();
    group.add(draw.circle(50).fill('#e74c3c'));
    group.add(draw.rect(100, 50).fill('#2ecc71'));
    group.scale(ratio);

    Масштабирование применяется ко всей группе, уменьшая количество операций.

  2. Использование defs и use для повторяющихся объектов:

    const star = draw.symbol().polygon('10,0 12,7 20,7 14,11 16,18 10,14 4,18 6,11 0,7 8,7');
    draw.use(star).move(50, 50).scale(ratio);
    draw.use(star).move(150, 100).scale(ratio);

    Повторное использование уменьшает нагрузку на DOM.

  3. Минимизация сложных фильтров и градиентов, которые требуют больших вычислений на высоких разрешениях.


Автоматическая адаптация под devicePixelRatio

SVG.js можно интегрировать с динамическим изменением плотности пикселей при ресайзе окна:

function resizeCanvas() {
    const ratio = window.devicePixelRatio || 1;
    draw.size(400 * ratio, 300 * ratio)
        .viewbox(0, 0, 400, 300);
    draw.node.style.width = '400px';
    draw.node.style.height = '300px';
}

window.addEventListener('resize', resizeCanvas);
resizeCanvas();

Такой подход позволяет поддерживать четкость графики при изменении масштаба и на разных устройствах, что критично для интерактивных приложений и визуализаций.


Итоговые рекомендации по Retina

  • Всегда использовать viewBox для масштабируемой системы координат.
  • Применять devicePixelRatio для создания холста с повышенным разрешением.
  • Масштабировать элементы и группы, а текст — через относительные единицы.
  • Минимизировать сложные эффекты и фильтры, которые сильно нагружают GPU на высоких разрешениях.
  • Использовать defs и use для повторяющихся объектов.

Эти подходы обеспечивают четкость, масштабируемость и оптимальную производительность при работе с SVG.js на дисплеях высокой плотности пикселей.