Responsive images

Atomico предоставляет удобные инструменты для создания веб-компонентов, включая работу с изображениями, которые адаптируются под различные размеры экранов и устройства. Ключевым подходом является использование реактивных свойств (props) и наблюдаемых состояний (state) для динамической подгрузки и отображения изображений.

Использование props для определения источника изображения

В компоненте можно объявить свойство src с типом String, которое будет отвечать за путь к изображению:

import { c, useProp } from "atomico";

function ResponsiveImage() {
    const src = useProp("src", { type: String });
    return <img src={src} alt="Responsive image" />;
}

ResponsiveImage.props = {
    src: String
};

export const responsiveImage = c(ResponsiveImage);

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

Адаптация изображений под экран

Для адаптивных изображений используется комбинация атрибутов HTML: srcset и sizes. Atomico позволяет динамически формировать эти значения через реактивные свойства:

function ResponsiveImage() {
    const src = useProp("src", { type: String });
    const srcSet = useProp("srcSet", { type: String });
    const sizes = useProp("sizes", { type: String });

    return <img src={src} srcSet={srcSet} sizes={sizes} alt="Responsive image" />;
}

ResponsiveImage.props = {
    src: String,
    srcSet: String,
    sizes: String
};
  • srcset — перечень вариантов изображения с разными разрешениями.
  • sizes — определяет, какой размер изображения использовать в зависимости от ширины экрана.

Динамическая подгрузка изображений с state

Atomico поддерживает хук useState, позволяющий управлять состоянием компонента. Для загрузки изображений с разными форматами и разрешениями это удобно:

import { c, useProp, useState } from "atomico";

function ResponsiveImage() {
    const src = useProp("src");
    const [currentSrc, setCurrentSrc] = useState(src);

    function handleResize() {
        if (window.innerWidth > 1200) {
            setCurrentSrc(src + "-large.jpg");
        } else if (window.innerWidth > 768) {
            setCurrentSrc(src + "-medium.jpg");
        } else {
            setCurrentSrc(src + "-small.jpg");
        }
    }

    window.addEventListener("resize", handleResize);

    return <img src={currentSrc} alt="Responsive image" />;
}

ResponsiveImage.props = { src: String };

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

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

Для экономии ресурсов и ускорения рендеринга рекомендуется использовать ленивую загрузку с атрибутом loading="lazy":

return <img src={currentSrc} alt="Responsive image" loading="lazy" />;

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

import { useRef, useEffect } from "atomico";

function LazyImage({ src }) {
    const imgRef = useRef();

    useEffect(() => {
        const observer = new IntersectionObserver(
            ([entry]) => {
                if (entry.isIntersecting) {
                    imgRef.current.src = src;
                    observer.disconnect();
                }
            },
            { threshold: 0.1 }
        );

        observer.observe(imgRef.current);
    }, [src]);

    return <img ref={imgRef} alt="Lazy loaded image" />;
}

Работа с форматом и качеством изображений

Современные веб-проекты используют форматы WebP или AVIF для сокращения объема данных без потери качества. Atomico позволяет динамически подставлять форматы через свойства:

function ResponsiveImage({ src, format }) {
    const extension = format || "jpg";
    return <img src={`${src}.${extension}`} alt="Responsive image" />;
}

Для более гибкого управления можно объединять srcset и разные форматы:

<img
    src="image.jpg"
    srcSet="image.webp 1x, image@2x.webp 2x"
    sizes="(max-width: 600px) 480px, 800px"
    alt="Responsive image"
/>

Стилизация и управление размерами через CSS

Реактивность в Atomico сочетается с CSS-переменными для адаптивного дизайна:

function ResponsiveImage({ src }) {
    return (
        <host>
            <style>
                {`
                    img {
                        width: 100%;
                        height: auto;
                        max-width: var(--max-width, 100%);
                    }
                `}
            </style>
            <img src={src} alt="Responsive image" />
        </host>
    );
}

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

Комбинация с другими компонентами

В Atomico изображения часто интегрируются с компонентами-контейнерами и сетками:

<grid-container columns="3">
    <responsive-image src="photo1" />
    <responsive-image src="photo2" />
    <responsive-image src="photo3" />
</grid-container>

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