Подготовка изображений для получения эффекта предварительного размытия с помощью Gatsby

Gatsby отлично справляется с обработкой изображений и помогает с их оптимизацией. И даже может произвести предварительную загрузку изображений и размытие.

Но использование gatsby-source-filesystem, GraphQL, плагинов Sharp и gatsby-image довольно затруднительно.

Содержание

Medium использует технику предварительного размытия для изображений

gatsby-image – это компонент React, который Gatsby использует для обработки и размещения отложено загружаемых изображений. Он также задает положение изображений и позволяет создавать предварительное размытие каждого конкретного изображения.

Для реализации адаптивности используется тег <img> с набором изображений соответствующего размера в атрибуте srcset вместе с атрибутом sizes.

<img srcset="img-320w.jpg 320w,
              img-480w.jpg 480w,
              img-800w.jpg 800w"
      sizes="(max-width: 320px) 280px,
            (max-width: 480px) 440px,
            800px"
      src="img-800w.jpg">

Но gatsby-image выполняет все необходимые изменения размера и сжатие автоматически, обрабатывая настройки атрибутов srcset в теге <img />.

Структура каталогов для изображений

Кроме этого Gatsby помогает структурировать изображения, а не собирать их в одном каталоге на сервере. Генератор статистических сайтов (SSG) Gatsby использует настраиваемую конфигурацию webpack для обработки, минимизации и экспорта всех файлов в проекте. Сгенерированный вывод помещается в папку /public. Общая структура gatsby-starter-default, выглядит следующим образом:

/
|-- /.cache
|-- /plugins
|-- /public
|-- /src
    |-- /pages
    |-- /components
    |-- /images
    |-- html.js
|-- /static (not present by default)
|-- gatsby-config.js
|-- gatsby-node.js
|-- gatsby-ssr.js
|-- gatsby-browser.js

Более подробно о структуре проекта Gatsby можно прочитать здесь.

Начнем с организации структуры следующих типов ресурсов:

  • Иконок.
  • Логотипов.
  • Фавикон.
  • Галерея изображений.

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

Статическая группа

Добавьте все файлы в папку static, расположенную в корне проекта. Упаковщик автоматически копирует ее содержимое в папку public, откуда финальная сборка может напрямую обращаться к файлам.

Допустим, что у вас есть файл logo.svg, который не требует обработки. Поместите его в папку static и используйте в файле компонента следующим образом:

import React from "react"

// Указываем webpack, что файл JavaScript нуждается в этом изображении
import logo from "../../static/logo.svg" 

function Header() {
  // Оно может напрямую использоваться, как src изображения
  return <img src={logo} alt="Logo" />
}

export default Header

У Gatsby есть документация по импорту ресурсов непосредственно в файлы, к которым вы можете обратиться.

Особый случай: favicon

Плагин gatsby-plugin-manifest не только добавляет в проект файл manifest.json, но и генерирует фавикон необходимых размеров и связывает их на сайте. Поместите файл favicon.svg в папку static и настройте файл gatsby-config.js с установками для gatsby-plugin-manifest.

{
  resolve: `gatsby-plugin-manifest`,
  options: {
    name: `Absurd`,
    icon: `static/favicon.svg`,
  },
},

Группа «для обработки»

gatsby-image не работает как тег img, в котором мы указываем атрибут src, и он выполняет всю обработку «под капотом». В Gatsby для этого нужно настроить gatsby-source-filesystem для файлов. Затем использовать GraphQL для их запроса и обработки с помощью плагинов Gatsby Sharp с gatsby-image. В результате этого создается адаптивное изображение с отложенной загрузкой.

Вариант использования: галерея изображений

В качестве примера рассмотрим обработку изображений на странице «О нас». Она представляет собой массив данных с заголовком, описанием и изображением.

Массив данных будет иметь следующую структуру:

const TEAM = [
  {
    name: 'Josh Peck',
    image: 'josh.jpg',
    role: 'Founder',
  },
  {
    name: 'Lisa Haydon',
    image: 'lisa.jpg',
    role: 'Art Director',
  },
  {
    name: 'Ashlyn Harris',
    image: 'ashlyn.jpg',
    role: 'Frontend Engineer',
  }
];

Теперь поместим все изображения (josh.jpg, lisa.jpg и так далее) в src/images/team. Следующий шаг — запросить изображения и связать их с данными.

Чтобы эти файлы стали доступными для обработки в Gatsby, используем gatsby-source-filesystem. Конфигурация gatsby-config.js для этой конкретной папки будет выглядеть следующим образом:

{
  resolve: `gatsby-source-filesystem`,
  options: {
    name: `team`,
    path: `${__dirname}/src/images/team`,
  },
  `gatsby-transformer-sharp`,
  `gatsby-plugin-sharp`,
},

Чтобы запросить массив файлов из этой папки, можно использовать sourceInstanceName. Он принимает значение имени, указанного в gatsby-config.js:

{
  allFile(filter: { sourceInstanceName: { eq: "team" } }) {
    edges {
      node {
        relativePath
        childImageSharp {
          fluid(maxWidth: 300, maxHeight: 400) {
            ...GatsbyImageSharpFluid
          }
        }
      }
    }
  }
}

Это возвращает массив:

// Данные четкого изображения удалены для лучшей читаемости
{
  "data": {
    "allFile": {
      "edges": [
        {
          "node": {
            "relativePath": "josh.jpg"
          }
        },
        {
          "node": {
            "relativePath": "ashlyn.jpg"
          }
        },
        {
          "node": {
            "relativePath": "lisa.jpg"
          }
        }
      ]
    }
  }

relativePath используется, чтобы связать нужные нам изображения с элементом в массиве данных. JavaScript может помочь с этим:

// Img - это gatsby-image
// TEAM - это массив данных

TEAM.map(({ name, image, role }) => {
  // Находим связанное изображение в массиве изображений
  const img = data.allFile.edges.find(
    ({ node }) => node.relativePath === image
  ).node;

  return (
    <div>
      <Img fluid={img.childImageSharp.fluid} alt={name} />
      <Title>{name}</Title>
      <Subtitle>{role}</Subtitle>
    </div>
  );
})

Пример использования: иллюстрации

В этом случаем мы можем разместить все изображения в одной папке. А также использовать sourceInstanceName для указания того, из какой папки мы запрашиваем изображение.

Создадим папку с именем src/images/art и настроим gatsby-source-filesystem. В данном случае мы будем запрашивать конкретное изображение, которое нам необходимо:

art_team: file(
    sourceInstanceName: { eq: "art" }
    name: { eq: "team_work" }
  ) {
    childImageSharp {
    fluid(maxWidth: 1600) {
      ...GatsbyImageSharpFluid
    }
  }
}

Это может быть использовано непосредственно в компоненте:

<Img fluid={data.art_team.childImageSharp.fluid} />

А также для каждого компонента или раздела, которому требуется изображение из этой группы.

Особый случай: встраивание SVG

Gatsby автоматически перегоняет изображения меньшего размера в формат base64 и помещает данные в строку. Что уменьшает количество запросов и увеличивает производительность. Но это решение не подходит для файлов в формате SVG.

Плагин gatsby-plugin-svgr — это наиболее удобное решение. Он позволяет импортировать все файлы SVG как компоненты React:

import { ReactComponent as GithubIcon } from './github.svg';

Для этого нужно переместить SVG-файл из папки static и поместить его в папку компонента, который его использует.

Заключение

Все используемые в этой статье соглашения взяты из начального проекта gatsby-absurd, который я создал на GitHub. Вот результат:

Посмотреть результат

Взгляните на Team.js, чтобы увидеть, как сразу несколько изображений запрашиваются из одной группы. Другие разделы, такие как About.js и Header.js, иллюстрируют то, как запрашиваются иллюстрации (группа изображений, совместно используемых в различных разделах). В Footer.js и Navbar.js представлены примеры обработки иконок.

Данная публикация представляет собой перевод статьи «Ways to Organize and Prepare Images for a Blur-Up Effect Using Gatsby» , подготовленной дружной командой проекта Интернет-технологии.ру

Меню