Bearcam Companion: Amplify и React

В своей последней заметке я настроил бэкенд для приложения Bearcam Companion с помощью AWS Amplify Studio. В этот раз я напишу о коде фронтенда и подключении его к бэкенду с помощью Amplify CLI.

Существует множество фреймворков для фронтенда, из которых можно выбирать. Поскольку я создаю веб-приложение с помощью AWS Amplify и хорошо знаком с JavaScript, я смог значительно сузить круг выбора. В конце концов, я остановился на React (в основном потому, что большинство примеров AWS Amplify используют React).

Ознакомьтесь с Amplify Getting Started для React, чтобы узнать основы.

Настройка

Я начал с пустого приложения React (вы можете изменить название с myapp на любое другое, которое вы хотите назвать своим приложением):

npx create-react-app@latest myapp
cd myapp
Войти в полноэкранный режим Выход из полноэкранного режима

У меня уже был установлен Amplify CLI из предыдущего руководства, поэтому мне просто нужно вытащить мой проект. Я получил соответствующую команду из Amplify Studio, нажав на ссылку Local setup instruction в правом верхнем углу страницы Studio. Команда будет выглядеть примерно так:

amplify pull --appId <app-ID> --envName <environment>
Войти в полноэкранный режим Выйти из полноэкранного режима

Для вас будет заполнен <app-ID>, и вы сможете выбрать одно из ваших <окружений> (у меня пока только staging окружение).

Приложение

Я следовал различным руководствам, чтобы соединить мой React frontend с Amplify backend. Как только я получил базовую настройку, я отредактировал App.js (в src/App.js), чтобы добавить FrameView. Это будет основной вид для приложения Bearcam Companion. Мне нужно импортировать его в App.js и добавить JSX в функцию return():

import FrameView from './FrameView';

function App() {
  return (
    <div className="App">
      <h2>Bearcam Companion</h2>
      <FrameView/>
    </div>
  );
}

export default App;
Вход в полноэкранный режим Выход из полноэкранного режима

Frame View

В FrameView я хочу использовать FrameCollection, которую я создал в Amplify Studio, чтобы показать последние кадры видео в моей таблице Images. Я уже подключил компонент FrameCollection к модели данных с помощью Amplify Studio. Код был снесен, когда я выполнил команду amplify pull. На самом деле, все компоненты из оригинальных примеров Figma плюс те, которые я создал, появляются в src/ui-components. Вот мой первоначальный код FrameView, включая компонент FrameCollection:

import { FrameCollection } from './ui-components'

export default function FrameView () {

    return(
      <div>
        <FrameCollection width={"100vw"} itemsPerPage={4} />
      </div>
    )
}
Вход в полноэкранный режим Выход из полноэкранного режима

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

Просмотр в браузере

На этом этапе я могу запустить npm:

npm start
Войти в полноэкранный режим Выйти из полноэкранного режима

Теперь я могу просмотреть свое приложение в браузере (я использую Chrome) по адресу http://localhost:3000/. Пока что это выглядит следующим образом:

Основной смысл FrameView заключается в отображении фрейма (FrameCollection будет использоваться для выбора фрейма). Я также хочу иметь возможность рисовать на фрейме ограничивающие рамки из модели данных Objects. Сначала я поработаю над отображением и выбором фрейма.

Добавление изображения рамки

Я добавил <img> в FrameView, изначально жестко закодировав источник изображения на одно из изображений из моего набора Amplify Content. Теперь приложение начинает обретать форму:

Выбор кадра из коллекции кадров

Я добавил событие onClick к FrameCollection, используя следующий код в FrameView.js (см. эту страницу для получения дополнительной информации):

  <FrameCollection width={"100vw"} itemsPerPage={4}
   overrideItems={({ item, index }) => 
                  ({onClick: () => {updateFrame(item)}
  })} />
Вход в полноэкранный режим Выйти из полноэкранного режима

Затем я создал updateFrame, который обновляет источник изображения:

  function updateFrame(item) {
    document.getElementById("refImage").src = item.url
  }
Вход в полноэкранный режим Выход из полноэкранного режима

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

Нарисуйте ограничивающие рамки

Мне все еще нужно добавить ограничивающие рамки на изображение. Первой моей мыслью было использовать элемент HTML Canvas. Я добавил <canvas> туда, где у меня был элемент <img>, и спрятал <img>. Поскольку браузер уже позаботился о загрузке <img>, мне не нужно было беспокоиться о логике загрузки. Я мог сослаться на него с помощью document.getElementById и нарисовать его на холсте. Я использовал image.id, чтобы найти все ограничивающие рамки для этого изображения в Objects с помощью такой строки:

const boxes = await DataStore.query(Objects, c => c.imagesID("eq", imageID));
Войти в полноэкранный режим Выйти из полноэкранного режима

Теперь я итерировал boxes и нарисовал каждую на <canvas>. В итоге у меня получилось что-то вроде этого:

Я не был доволен этим решением по двум основным причинам:

  1. Пришлось постараться, чтобы все выглядело хорошо.
  2. Я не могу легко обрабатывать действия hover или click для полей, что будет важно, когда я захочу получить дополнительную информацию или нажать для редактирования.

Должен быть лучший способ

Для вдохновения я обратился к демонстрации Amazon Rekognition (которую я использовал для получения ограничивающих рамок для моего тестового контента). В демонстрации Rekognition используется относительно позиционированный <div> со стилизованными бордерами для каждого бокса. Это выглядит намного лучше (и может быть изменено с помощью CSS) и должно облегчить обработку действий пользователя.

Я займусь этим в следующий раз…

Оцените статью
Procodings.ru
Добавить комментарий