В своем последнем посте я настроил бэкэнд для приложения Bearcam Companion с помощью AWS Amplify Studio. В этот раз я напишу о коде фронтенда и его подключении к бэкенду с помощью Amplify CLI.
Существует множество интерфейсных фреймворков на выбор. Поскольку я создаю веб-приложение с помощью AWS Amplify и знаком с JavaScript, мне удалось значительно сузить круг вопросов. В конце концов я выбрал React (главным образом потому, что я обнаружил, что в большинстве примеров AWS Amplify используется React).
Ознакомьтесь с разделом Начало работы с React в Amplify, чтобы узнать об основах.
Настраивать
Я начал с пустого приложения React (вы можете изменить имя с myapp
на то, что вы хотите назвать своим приложением):
npx create-react-app@latest myapp cd myapp
У меня уже был установлен Amplify CLI из предыдущего учебника, поэтому мне просто нужно вытащить свой проект. Я получил соответствующую команду от Amplify Studio, щелкнув ссылку Инструкция по локальной настройке в правом верхнем углу страницы Studio. Команда будет выглядеть примерно так:
amplify pull --appId <app-ID> --envName <environment>
<app-ID>
будет заполнено для вас, и вы сможете выбирать между своими <environments>
(у меня пока только среда staging
).
Приложение
Я следовал различным руководствам, чтобы соединить интерфейс React с серверной частью Amplify. После того, как у меня была базовая настройка, я отредактировал 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;
Вид кадра
В FrameView
я хочу использовать FrameCollection
, который я создал в Amplify Studio, чтобы отображать последние видеокадры в моей таблице Изображения. Я уже подключил компонент 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. Теперь приложение начинает обретать форму:
Выберите кадр из коллекции FrameCollection
Я добавил событие 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>
. Я закончил с чем-то вроде этого:
Я не доволен этим решением по двум основным причинам:
- Это действительно должно было выглядеть хорошо.
- Я не могу легко обрабатывать действия наведения или щелчка для полей, что будет важно, когда мне нужна дополнительная информация или щелчок для редактирования.
Должен быть лучший способ
Для вдохновения я посмотрел на демо для Amazon Rekognition (которое я использовал, чтобы получить ограничивающие рамки для своего тестового контента). Демонстрация Rekognition использует относительное расположение <div>
со стилизованными границами для каждого блока. Это выглядит намного лучше (и может быть изменено с помощью CSS) и должно упростить обработку действий пользователя.
Я углублюсь в это в следующий раз…
Первоначально опубликовано на https://dev.to 31 мая 2022 г.