Задаетесь вопросом: как создать приложение на основе ИИ для генерации изображений по промптам пользователей? Вы попали по адресу!

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

Начало работы над проектом

Начнем с разработки приложения React + TypeScript с использованием Vite. Выполните в терминале следующую команду:

npm create vite@latest

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

✔ Project name: aimages
✔ Select a framework: › React
✔ Select a variant: › TypeScript

После этого необходимо установить и сконфигурировать TailwindCSS.

Выполните две команды, приведенные ниже (в указанном порядке). Первая устанавливает tailwindcss и его одноранговые зависимости. Вторая генерирует файлы tailwind.config.js и postcss.config.js.

npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

Теперь откройте файл tailwind.config.js и измените код следующим образом:

/** @type {import('tailwindcss').Config} */
export default {
content: [
"./index.html",
"./src/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}

Приведенный выше код настраивает TailwindCSS, указывая, какие файлы фреймворк должен проверять на предмет использования классов. Он настроен на проверку файла index.html и всех файлов JavaScript и TypeScript в каталоге src. Здесь же можно настроить тему, цвета, шрифты и многое другое.

Наконец, откройте файл /src/styles.css и добавьте директивы TailwindCSS в начале файла:

@tailwind base;
@tailwind components;
@tailwind utilities;

Настройка проекта завершена. Теперь загрузите проект на GitHub. Позже поймете, зачем это нужно.

Проблемы разработки пользовательских интерфейсов

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

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

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

К этому добавляется еще одна проблема  —  многократное прерывание рабочего процесса. Каждое прерывание (например, при переключении между приложениями) нарушает привычную рутину, что приводит к увеличению времени завершения задач и, возможно, к большему количеству ошибок.

Вдобавок ко всему, совместная работа над проектом становится утомительной и отнимает много времени. Обычно она включает работу над приложением, отправку изменений на GitHub и их развертывание. Только после этого другие участники процесса могут оценить вашу работу. Это приводит к существенной потере времени из-за непродуктивных действий, таких как ожидание внедрения изменений. Словом, традиционный подход может оказаться довольно громоздким и неэффективным.

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

Визуальная среда разработки React

Codux  —  это бесплатная визуальная среда разработки для приложений React + TypeScript. Codux позволяет работать над проектами в режиме реального времени с использованием визуального редактора. Все изменения, вносимые в свойства, стили и структуру компонента (JSX  —  расширение синтаксиса JavaScript), автоматически отображаются на экране.

Важное замечание: Codux не предназначен для замены IDE. Это дополнительный инструмент, который следует использовать вместе с IDE.

Используя панели и контроллеры, предоставляемые Codux, можно создавать и изменять интерфейсы. На изображении ниже показано, как устанавливать свойства и классы CSS, а также различные состояния элементов.

В нижней части находится редактор кода для внесения изменений при написании кода.

Примечание: независимо от того, вносите вы изменения с помощью визуального редактора, встроенного редактора кода или обычной IDE, они всегда будут синхронизированы.

Codux также поддерживает все популярные решения по стилизации, такие как CSS, Sass, модули CSS/Sass, Stylable и TailwindCSS. Например, приложение, которое мы создадим, будет использовать TailwindCSS.

Component Playground

Еще одна интересная функция Codux  —  Component Playground. Это экспериментальная площадка, позволяющая делиться своей работой (компонентами) с другими пользователями.

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

Посмотрим, как это происходит. В начале статьи я просил вас загрузить проект на GitHub. Причина в том, что это требование Playground.

Чтобы поделиться своей доской (или компонентом), нажмите кнопку “Share” (“Поделиться”) справа.

Предупреждение: совместно используемая доска является общедоступной. Это означает, что любой, у кого есть ссылка, может ее увидеть. Будьте осторожны.

Затем Codux попросит вас создать название ссылки для доски. Выберите название и нажмите кнопку “Create Link” (“Создать ссылку”) (при первом запуске) и “Publish” (“Опубликовать”) (после).

Примечание: при каждом внесении изменений нажимайте кнопку “Update Link” (“Обновить ссылку”), прежде чем поделиться доской. В противном случае изменения не будут учтены и видны на совместно используемой доске.

Теперь можно скопировать ссылку и поделиться ею с другими пользователями. Перейдя по этой ссылке, они увидят онлайн-версию Codux (см. изображение ниже).

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

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

Однако важно отметить, что изменения на совместно используемой доске не влияют на исходную доску и не будут на ней учтены. Хотя это была бы классная функция.

Добавление проекта в Codux

Продолжим, импортировав созданный ранее проект в Codux. Нажмите на опцию “Open Local Project” (“Открыть локальный проект”) и выберите папку проекта.

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

Когда установка будет завершена, нажмите “Scan for components” (“Проверить на наличие компонентов”), чтобы Codux импортировал все компоненты.

Сейчас все доступные компоненты можно просмотреть на боковой панели. В нашем случае здесь только один компонент  —  App (приложение), поскольку это новый проект.

Можно создавать новые компоненты, нажав кнопку “+ New Component” (“+ Новый компонент”), но об этом позже.

Как вы заметили, Codux использует понятия “компоненты” (“components”) и “доски” (“boards”). “Доска”  —  это стенд для компонентов, которые Codux автоматически отображает и позволяет пользователям визуально редактировать.

Чтобы создать “доску”, щелкните по компоненту, а затем нажмите кнопку “+ Create Board” (“+ Создать доску”). Откроется меню с предложением задать параметры: стартовую точку, название доски и путь к доске.

Можете оставить параметры по умолчанию и нажать “Create” (“Создать”).

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

Настройка Tailwind CSS

Чтобы TailwindCSS работал в Codux, необходимо выполнить определенные настройки в дополнение к уже осуществленному (и описанному в начале статьи) процессу настройки Tailwind.

Создайте codux.config.js в корневой папке проекта и добавьте следующий объект:

{
"$schema": "https://wixplosives.github.io/codux-config-schema/codux.config.schema.json",
"boardGlobalSetup": "./src/_codux/board-global-setup.ts"
}

Теперь создайте board-global-setup.ts в папке ./src/_codux и добавьте следующий импорт:

import "../index.css";

Готово! Теперь вы можете увидеть классы Tailwind CSS в среде разработки Codex.

Для получения дополнительной информации об этой настройке перейдите по ссылке.

Разработка приложения

Приступим к поэтапной разработке приложения.

Создание папки components

Начнем с создания папки component для всех компонентов. Можете сделать это либо из своей IDE, терминала, либо из Codux. Вот как выполнить это из Condux:

Нажмите на выделенную иконку, чтобы просмотреть файлы проекта. После этого создайте папку так, как сделали бы это на своем компьютере. Щелкните правой кнопкой мыши на папке src и выберите New Folder (Новая папка).

Создание компонентов из Codex

Чтобы создавать компоненты, используя интерактивный процесс в Codux, необходимо указать путь к компонентам. Можете сделать это, добавив нижеуказанный код в codux.config.json:

{
"$schema": "https://wixplosives.github.io/codux-config-schema/codux.config.schema.json",
"boardGlobalSetup": "./src/_codux/board-global-setup.ts",
"newComponent": {
"componentsPath": "src/components"
}
}

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

Создание компонента Layout

Создайте компонент Layout (компонент макета) в папке components. Макет будет использоваться на всех страницах.

Следующие шаги можете выполнять, используя обычную IDE или Codex.

Примечание: у вас будет все в порядке в любом случае, потому что код автоматически синхронизируется между ними. Используете ли вы Codux или свой редактор, оба будут содержать один и тот же код без необходимости каких-либо действий с вашей стороны.

Откройте компонент Layout и добавьте следующий код:

type LayoutProps = {
children: React.ReactNode;
};

export default function Layout({ children }: LayoutProps) {
return (
<>
<main>{children}</main>
</>
);
}

Переработка файла App.tsx

Перейдите к файлу App.tsx и замените его содержимое следующим кодом:

import Layout from "./components/Layout";
import "./App.css";
import { useState } from "react";

function App() {
const [inputValue, setInputValue] = useState("");
const [imageURL, setImageURL] = useState("");
const [loading, setLoading] = useState(false);
const [error, setError] = useState<null | string>(null);

const fetchImage = async (prompt: string) => {
const response = await fetch("http://localhost:3000/api/genimg", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ value: prompt }),
});

if (response.ok) {
const data = await response.json();

if (Array.isArray(data) && data.length > 0) {
return data[0];
}

throw new Error("Unexpected server response");
} else {
throw new Error(response.statusText);
}
};

const onInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
setInputValue(e.target.value);
};

const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
setLoading(true);
setError(null);

try {
const url = await fetchImage(inputValue);
setImageURL(url);
} catch (err) {
if (err instanceof Error) {
setError(err.message);
} else {
setError("An unexpected error occurred");
}
} finally {
setLoading(false);
}
};

return (
<>
<Layout>
<section>
<div>
<div>
<h1>PromptPix AI</h1>
<p>
Dive into the world of AI-driven creativity with PromptPix AI,
where your words become vivid visuals. Simply input your idea,
and watch as our advanced algorithms craft the image you
envisioned.
</p>
</div>
<form onSubmit={handleSubmit}>
<div>
<label htmlFor="prompt">Image prompt</label>
<textarea
id="prompt"
placeholder="Enter your prompt"
value={inputValue}
onChange={onInputChange}
/>
</div>
<button type="submit" disabled={inputValue.length === 0}>
Generate
</button>
</form>
</div>
<div>
{loading && (
<div>
<p>Your image is being generated...</p>
<div>
<div>
<div>
<svg
xmlns="http://www.w3.org/2000/svg"
width="44"
height="44"
viewBox="0 0 24 24"
strokeWidth="2"
stroke="currentColor"
fill="none"
strokeLinecap="round"
strokeLinejoin="round"
>
<path
stroke="none"
d="M0 0h24v24H0z"
fill="none"
></path>
<path d="M12 6l0 -3"></path>
<path d="M16.25 7.75l2.15 -2.15"></path>
<path d="M18 12l3 0"></path>
<path d="M16.25 16.25l2.15 2.15"></path>
<path d="M12 18l0 3"></path>
<path d="M7.75 16.25l-2.15 2.15"></path>
<path d="M6 12l-3 0"></path>
<path d="M7.75 7.75l-2.15 -2.15"></path>
</svg>
</div>
</div>
</div>
</div>
)}

{imageURL && !loading && (
<div>
<p>Find your generated image below</p>
<img
src={imageURL}
width={600}
height={600}
alt="Generated image"
/>
</div>
)}

{!imageURL && !loading && (
<div>
<p>Your image will appear below</p>
<div>
<div>
<div>
<svg
xmlns="http://www.w3.org/2000/svg"
width="44"
height="44"
viewBox="0 0 24 24"
strokeWidth="2"
stroke="currentColor"
fill="none"
strokeLinecap="round"
strokeLinejoin="round"
>
<path
stroke="none"
d="M0 0h24v24H0z"
fill="none"
></path>
<path d="M15 8h.01"></path>
<path d="M11.5 21h-5.5a3 3 0 0 1 -3 -3v-12a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v5.5"></path>
<path d="M18 18m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0"></path>
<path d="M20.2 20.2l1.8 1.8"></path>
<path d="M3 16l5 -5c.928 -.893 2.072 -.893 3 0l2 2"></path>
</svg>
</div>
</div>
</div>
</div>
)}

{error && <div>{error}</div>}
</div>
</section>
</Layout>
</>
);
}

export default App;

Этот компонент содержит базовое приложение без применения какого-либо стиля.

Примечание: все, что есть в файле App, приведено в иллюстративных целях. Таким образом проще продемонстрировать инструмент. Финальный вариант приложения вы увидите на GitHub.

Оформление приложения с использованием Codux

Начнем с оформления компонента Layout. Дважды щелкните App на вкладке Elements (“Элементы”) (столбец слева).

Откроется новое дерево, в котором вы должны увидеть компонент Layout. Дважды щелкните на Layout, а затем выберите main.

На вкладке Elements отображаются все HTML-элементы из кода.

Чтобы добавить классы Tailwind в HTML-элементы, щелкните иконку “Properties” (“Свойства”) справа. Затем найдите свойство “className”.

После этого добавьте следующие классы Tailwind:

flex min-h-screen flex-col justify-center items-center

Эти классы настраивают flex-контейнер с минимальной высотой, равной высоте порта просмотра, упорядочивают его дочерние элементы в столбец и центрируют их по вертикали и горизонтали внутри контейнера.

Вы должны немедленно увидеть изменения, отраженные как визуально, так и в коде.

Теперь переключимся на IDE, чтобы увидеть, насколько легко использовать их вместе. Откройте файл index.css и добавьте этот блок:

body {
@apply bg-gray-50;
}

Добавление классов из компонента App

Добавьте следующие классы к элементу section из компонента App:

container flex flex-col gap-6 py-8 md:max-w-[64rem] md:py-12 lg:py-24

Эти классы изменяют section: во flex-контейнере элементы располагаются в столбец сверху вниз, вертикальный зазор между дочерними элементами составляет 6 единиц, вертикальный паддинг  —  8 единиц (12 единиц на средних экранах и 24 единицы на больших), максимальная ширина  —  64 rem на средних и больших экранах.

Аналогично примените следующие классы к первому элементу div:

bg-white shadow-md rounded border border-slate-200 p-14 text-center

Эти вспомогательные классы TailwindCSS определяют белый фон, среднюю затененность, закругленные углы, рамку грифельного цвета, паддинг со всех сторон по 14 единиц и текст, выровненный по центру.

Вот как выглядит приложение на данный момент.

Следующие шаги:

  • стилизация заголовка и описания;
  • стилизация формы;
  • стилизация той части, где появится изображение;
  • создание API.

Оформите заголовок и описание с использованием IDE (в моем случае VS Code), чтобы увидеть автосинхронизацию в действии.

Замените 2-й элемент div следующим кодом:

<div className="mx-auto flex w-full flex-col md:max-w-[58rem]">
<h1 className="font-heading text-2xl mb-4 sm:text-4xl text-center">
PromptPix AI
</h1>
<p className="text-sm sm:text-base text-center mb-4">
Dive into the world of AI-driven creativity with PromptPix AI,
where your words become vivid visuals. Simply input your idea,
and watch as our advanced algorithms craft the image you
envisioned.
</p>
</div>

На скриншоте ниже показано, как должен выглядеть код.

Если вы вернетесь к Codux, то увидите внесенные изменения в визуальной области и редакторе кода внизу страницы.

Аналогично все изменения, внесенные в Codux, будут доступны в IDE.

В качестве упражнения добавьте к этим элементам следующие классы:

  • к элементу form  —  space-y-6;
  • к элементу div внутри формы  —  flex flex-col items-center gap-4;
  • к элементу label  —  text-sm sm:text-base;
  • к элементу textarea  —  border border-slate-200 rounded p-2 w-3/4 h-32 resize-none;
  • к элементу button:
`${
inputValue.length === 0
? "bg-white text-gray-800 font-semibold py-2 px-4 border border-slate-400 rounded shadow opacity-50 hover:opacity-50 cursor-not-allowed"
: "bg-white hover:bg-slate-100 text-gray-800 font-semibold py-2 px-4 border border-slate-400 rounded shadow"
}`

Вот как выглядит приложение с применением всех вышеперечисленных классов:

Последний шаг включает стилизацию той части, где появится сгенерированное изображение. Создадим начальный элемент div (который отображается перед вводом запроса) в виде flex-контейнера с дочерними элементами, расположенными в столбце с центровкой по горизонтали, с промежутком в 24 пикселя между каждым дочерним элементом и верхним отступом в 48 пикселей  —  flex flex-col items-center gap-6 mt-12.

Добавьте их как обычно, используя поле “className” из Codux.

Примените те же классы Tailwind к другим двум элементам div, которые отображают состояние загрузки и сгенерированное изображение.

Наконец, стилизуйте error:

{error && (
<div className="text-center w-1/2 mx-auto bg-red-500 mt-2 rounded border border-red-800">
{error}
</div>
)}

Пользовательский интерфейс готов!

Condux предлагает гораздо больше

При создании этого приложения вы в основном применяли классы и визуализировали результаты в режиме реального времени. Однако Condux предлагает гораздо больше.

С помощью Codex вы можете протестировать приложение на нескольких портах просмотра и вносить изменения в режиме реального времени для каждого порта.

Кроме того, вместо добавления классов для каждого элемента вручную, можно использовать вкладку “Computed Styles” (“Вычисляемые стили”) для стилизации элементов. Вместо написания кода вручную, можно стилизовать элементы в интерактивном режиме.

Моей любимой функцией является возможность открывать код для определенного элемента. Вы можете выбрать конкретный элемент, щелкнуть по нему правой кнопкой мыши и открыть его в редакторе кода/IDE.

Изображение ниже иллюстрирует, как Codux выделяет соответствующий код для выбранного элемента.

Как видите, в Codux много интересных функций. Рекомендую вам скачать его и изучить. Это бесплатно!

Бэкенд-код для генерации изображения

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

import express, { Request, Response } from "express";
import Replicate from "replicate";
import cors from "cors";

const app = express();
const port = 3030;

app.use(express.json());
app.use(cors());

app.options("/api/genimg", (req: Request, res: Response) => {
// Предварительный запрос. Успешный ответ:
res.status(200).end();
});

app.post("/api/genimg", async (req: Request, res: Response) => {
const { value } = req.body;

try {
const replicate = new Replicate({
auth: process.env.REPLICATE_API_TOKEN || "",
});

const result = await replicate.run(
"stability-ai/stable-diffusion:a00d0b7dcbb9c3fbb34ba87d2d5b46c56969c84a628bf778a7fdaec30b1b99c5",
{
input: {
prompt: value,
image_dimensions: "1024x1024",
num_inference_steps: 50,
num_outputs: 1,
guideance_scale: 7.5,
prompt_strength: 0.8,
scheduler: "KarrasDPM",
},
}
);

res.status(200).json(result);
} catch (error) {
console.error("Failed to generate image. Error:", error);
res.status(500).json({ message: "Failed to generate image" });
}
});

app.all("/api/genimg", (req: Request, res: Response) => {
res.status(405).json({ message: "Method Not Allowed" });
});

app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});

Этот TypeScript-код настраивает Express-сервер, который прослушивает порт 3030 и у которого включен CORS. Он определяет три маршрута, все для пути “/api/genimg”. Маршрут OPTIONS предназначен для обработки предварительных запросов CORS. Маршрут POST принимает тело JSON со свойством “value”, использует его в качестве запроса для генерации изображения с использованием Replicate API и возвращает результат. Если во время этого процесса возникает ошибка, он регистрирует ее и возвращает идентификатор состояния 500 с сообщением о сбое. Маршрут ALL имеет функцию catch-all; он возвращает индикатор состояния 405, указывающий на то, что используемый метод не разрешен. Сервер прослушивает указанный порт и при запуске отправляет сообщение на консоль.

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

Примечание: чтобы посмотреть весь код приложения (как на стороне сервера, так и на стороне клиента), перейдите по этой ссылке на GitHub.

Заключение

Создание приложений сопряжено с проблемами, способными замедлить процесс разработки и затруднить совместную работу. Одной из основных проблем является необходимость постоянно переключаться между различными инструментами. Это отнимает много времени, мешает сосредоточиться и нарушает рабочий ритм. Более того, совместная работа над проектом сопряжена с большими трудностями: часто требуется несколько шагов, прежде чем сотрудники смогут протестировать вашу работу.

Именно здесь приходит на помощь Codux, делая весь процесс более плавным и эффективным. Этот инструмент визуализирует изменения по мере их внесения без постоянного переключения между несколькими инструментами. Более того, он предлагает визуальный пользовательский интерфейс, который упрощает разработку приложений, позволяя создавать все необходимое несколькими щелчками мыши. Но, пожалуй, главное достоинство Codux заключается в том, что он обеспечивает совместную работу в режиме реального времени, предоставляя всем участникам возможность беспрепятственно работать вместе.

В завершение хочу еще раз напомнить, что Codux предназначен не для того, чтобы заменить IDE и другие инструменты. Codux  —  это еще один инструмент в арсенале разработчика.

Читайте также:

Читайте нас в Telegram, VK и Дзен


Перевод статьи Catalin’s Tech: Build A Stunning Generative AI App with a React IDE

Предыдущая статьяТренды в сфере графического дизайна в 2024 году
Следующая статьяКарьерные пути в Java: от младшего разработчика до эксперта