レッドウッドで描画ボードを構築する


時々あなただけのものを記述し、他の人にすばやく送信する写真を描くことができる.あなたは全体のサービスや契約を特定のツールを使用する場合は、手だけで物事を描画し、それを送信したくない.それは私たちがこのRedwoodチュートリアルで作るつもりです.
我々は、ユーザーがすぐに画像として図面をダウンロードできるようにPostgresデータベースに図面を保存する描画ボードのアプリを作るでしょう.

Postgresのローカル設定
Postgresデータベースで動作するので、接続できるローカルインスタンスを作りましょう.あなたはdownload Postgres here あなたが働いているOSのために.
あなたが初期設定を通過している間、あなたが作成するユーザ名とパスワードに注意を払います.Redwoodの接続文字列が必要です.

レッドウッドアプリの設定
端末に移動して実行します.
yarn create redwood-app drawing-board
これはディレクトリとファイルの束を持つ新しいRedwoodアプリを作成します.お気軽にすべてをチェックアウトするが、我々は主にapi and web ディレクトリ.我々が扱う必要がある1つの速いことはそのデータベース接続ストリングを更新することです.
インサイド.env ファイルのコメントDATABASE_URL 行とローカルインスタンスに一致するように変更します.これは次のようになります.
DATABASE_URL=postgres://postgres:admin@localhost:5432/drawing_board
これはschema.prisma ファイルが更新されますが、スニークピークとして、ここではそれが使用されます.ここで何かを変更する必要はありません.
datasource db {
  provider = "postgresql"
  url = env("DATABASE_URL")
}
我々は、アプリケーションのバックエンドは、データベースと通信できるように場所でこれを必要とするでしょう.

モデル作成
画像を保持するテーブルのモデルを書きましょう.インapi > db , オープンschema.prisma そして、我々が更新する最初のものはprovider 値.これはpostgresql の代わりにsqlite .
次に、例のユーザーモデルをファイルから削除し、それを自分で置き換えます.このモデルは、キャプチャするキャンバスイメージごとに保存するデータを表します.
model Capture {
  id   Int    @id @default(autoincrement())
  name String
  url  String
}
我々がしているすべては、イメージのために名前とURLストリングを保存することです.私たちはPostgresのイメージのためにデータURLを保存するでしょう、しかし、これはAWSまたはCloudinaryのようなオンライン保管サービスへのリンクでありえました.

移動を実行する
これは、我々はこのアプリを持っている唯一のモデルですので、今すぐに移動を実行するのは安全です.
yarn rw prisma migrate dev
移行に名前を付けるよう促されますが、他のすべてが自動的に起こります.データベースが設定されているので、バックエンドで作業を開始します.

バックエンドを作る
レッドウッドはバックエンドですべてを処理するためにGraphqlを使用しています.それで、フロントエンドを要求して、データをデータベースに得るために、若干のタイプとリゾルバを必要とするつもりです.このコマンドを実行して、Capture モデル.
yarn rw g sdl capture
RedWoodは、新しいフォルダとファイルを作成しますapi > src > graphql とクエリリゾルバapi > src > services のためにCapture モデル.今、我々はちょうどいくつかのものを修正しなければなりません.

キャプチャのためのCREATE突然変異の追加
我々は、データベースに描画ボードからキャプチャを保存する機能を与えるために新しいタイプを追加する必要があります.次に、実際にデータをデータベースに追加するレゾルバを追加する必要があります.
第一に、我々はcaptures.sdl.js ファイル名api > src > graphql ディレクトリ.我々は、ちょうど以下の新しい突然変異タイプを加えるつもりですUpdateCaptureInput .
type Mutation {
  createCapture(input: CreateCaptureInput!): Capture!
}
これによりフロントエンドからリクエストをアクセスできるようになります.次に、我々は行きますcaptures.js ファイルを開き、クエリの下のデータベースにデータを保持する突然変異を追加します.
export const createCapture = ({ input }) => {
  return db.capture.create({
    data: input,
  })
}
我々は今、完全に機能するGraphSQLサーバーがあります!実際には、アプリケーションを実行する場合yarn rw dev そして、http://localhost:8911/graphql ブラウザでは、GraphSQLエクスプローラーに我々が追加した変異を参照してください.


フロントエンドを作る
我々はバックエンドの作業を持っているので、それは最終的にフロントエンドを構築する時間です.我々は、ボタンをクリックして図面をキャプチャ使用するページにキャンバスを持っているでしょう.ページの下部には、既存のキャプチャ図面の小さなビューがあります.

製図板
図面板のページを作り始めましょう.我々は、これのためにもう一つのRedwoodコマンドを利用します.
yarn rw g page capture /
これは、ページコンポーネントを生成するStorybook ストーリー、コンポーネントのジェストテスト.また、自動的に新しいページのルートを追加しますRoutes.js . このページは、私たちが持っている理由は、アプリケーションのベースのURLになります/ intページの作成コマンド.
また、インストールする必要がありますfabric 我々がキャンバスで働くことができるように、パッケージ.端末では、web ディレクトリと実行
yarn add fabric
この後、端末のディレクトリレベルを上書きしてください.この方法では、適切な場所にコマンドを実行されます.
それでは私たちは行きますweb > src > pages > CapturePage と編集CapturePage.js ファイル.あなたは中のすべてを削除することができますCapturePage 私たちはそれを使用していないので、コンポーネント.まず何かを輸入しましょう.
import React, { useState, useEffect } from 'react'
import { fabric } from 'fabric'
次に、新しい状態をCapturePage 画像を描画・保存できるように、キャンバスオブジェクトを初期化するコンポーネント.
const [canvas, setCanvas] = useState('')

useEffect(() => {
  setCanvas(initCanvas())
}, [])

const initCanvas = () =>
  new fabric.Canvas('capture', {
    height: 500,
    width: 500,
    backgroundColor: '#F6F6F6',
    isDrawingMode: true,
  })
The initCanvas ファブリックキャンバスオブジェクトの新しいインスタンスを設定します.そして、それはcapture . それから、我々はページのサイズを制限する若干の局面を与えました.それはバックグラウンドの色を持っているので、ユーザーはそれが相互作用する別の要素であることを知っている.最後に、我々は、ユーザーがキャンバス上で描画することができますので、我々は彼らが描く図面を保存することができます描画モードを有効にしている.
使用するuseEffect このキャンバスを初期化するには、ページが読み込まれたときのみ、このキャンバスにアクセスできるように状態を設定します.
返される文のフラグメント内にキャンバス要素を追加します.
return (
  <>
    <canvas id="capture" />
  </>
)
あなたが今アプリを実行する場合yarn rw dev , このようなブラウザが表示されます.


図面の保存
次に、そのアクションをトリガーするボタンを追加する必要があります.GraphSQLの作成突然変異を使用できるように、別のインポートを追加する必要があります.
import { useMutation } from '@redwoodjs/web'
次に、作成したいGraphSQLリクエストの定義を記述する必要があります.インポートの下で、次のように書きました.
const CREATE_CAPTURE_MUTATION = gql`
  mutation CreateCaptureMutation($input: CreateCaptureInput!) {
    createCapture(input: $input) {
      id
    }
  }
`
これはcreateCapture 突然我々は図面を保存するために使用します.定義があるので、突然変異リクエストを作成する必要があります.内部のCapturePage コンポーネントをキャプチャ状態の直前に追加します.
const [createCapture] = useMutation(CREATE_CAPTURE_MUTATION)
このフックを使用すると、この突然変異のために呼び出すことができる関数へのアクセスを与えます.さて、Saveボタンをクリックすると呼び出されるメソッドを定義する必要があります.下にinitCanvas コールします.
const saveCapture = () => {
  const imageUrl = canvas.lowerCanvasEl.toDataURL()

  const input = {
    name: `Capture${Math.random().toString()}`,
    url: imageUrl,
  }

  createCapture({
    variables: { input },
  })
}
あなたが生地がキャンバスを扱う方法を見るならば、我々が我々が我々がイメージとして絵を保存することができるようになるために欲しい内部のキャンバスがあります.それで、一旦我々が正しいキャンバスを持っているならば、我々はイメージのためにデータURLを得て、突然変異入力の一部としてそれを保存します.
画像のランダムな名前を作るために多くのより良い方法がありますが、我々は彼らにユニークな名前を与えるために乱数を使用している.それから、我々はちょうど我々が定義した入力で突然変異を呼びます、そして、それは図面をデータベースに保存します!

図面の表示
ちょうどあなたが図面が実際にそこにあるのを見るので、2、3つのものを落書きして、彼らを救ってください.今、我々はすべてのイメージを取得し、flex要素でそれらを表示するクエリを追加します.
既存のインポートに新しいフックを追加することから始めましょう.
import { useMutation, useQuery } from '@redwoodjs/web'
次に、突然変異の下のすべてのキャプチャのクエリを追加します.
const GET_CAPTURES = gql`
  query {
    captures {
      name
      url
    }
  }
`
これはデータベースにあるすべてのキャプチャを持つ配列を返します.私たちは、この定義を私たちがCapturePage コンポーネント.
const { data } = useQuery(GET_CAPTURES)
最後に、返されたすべてのキャプチャを表示する要素を追加します.これは、右の下に行くことができます<canvas> 要素.
<div style={{ display: 'flex' }}>
  {data?.captures &&
    data.captures.map((capture) => (
      <img
        key={capture.name}
        style={{ padding: '24px', height: '100px', width: '100px' }}
        src={capture.url}
      />
    ))}
</div>
これは、キャプチャのすべてをマップし、ページ上の小さな画像として表示されます.それで、あなたはこれに類似した何かを見ます.

それだ!今、あなたは滑らかなインターフェイスや画像を格納する空想的な方法を持ってこれを微調整することができます.

完成コード
フロントエンドをチェックアウトできますCode Sandbox または、完全なコードを見ることができます drawing-board folder of this repo .
コードサンドボックスをチェックアウトすると、コードが少し異なります.これは、我々がRedwood Mono Repoをこのツールで走らせることができないので、フロントエンドがどのように働くかの例がコードサンドボックスで見るものです.完全なコードを得るには、Githubのレポを見てみるほうがいい.

結論
私たちが行うことの多くは、仮想であるので、それはまだ自然を感じるWebとのインターフェイスに方法を持っていることができます.描画ボードはもっとうまくいけば、これは便利です人気になっている!