Anuglar7でサポートされたdrag&drapを使ってパズルゲームを作成し、Firebase Hosting機能を利用して公開するまでの流れの紹介です。
出来上がるのは、Torelloと同じ動き方をする、どうぶつパズルです。
カラムの多いTodoアプリみたいな感じです。
なぜこのようなアプリを作成したかというと、先日ゴリラチャット作りましたという記事を拝見して、僕も変なアプリを公開したい!と思ったからです。
目次
Angularとは
Angularはフロントエンドフレームワークのうちの一つです。
最近は、React.js Vue.jsにGitHubスター数で多いにひけを取っています。
が、Angular7でドラッグ&ドロップが使いやすくったのでAngularを使用します。
Rxjsを採用しているのが特徴です。
GitHubスター数
- React.js 117,853
- Vue.js 122,492
- Angular 43,616
Firebaseとは
mbaasです。
FirebaseのHosting機能を使うと簡単に自分の作成したサービスを公開することができます。
Angularプロジェクトの作成
初めての方向けに書いて行くので、既に知っているよ!という方は逐次読み飛ばしてください。
AngularCliのインストール
コマンドでアプリを作成していく為にはAngularCliをインストールする必要性があります。
グローバルでAngularCliをインストールしてください。
(sudo) npm install -g @angular/[email protected]
プロジェクトの作成
Angularで新規プロジェクトを作成するには、ng new コマンドを利用します
ターミナル上で任意のプロジェクト名を指定して、新たなプロジェクトを作成してください。
ng new animal-project //animal-projectの部分は任意のプロジェクト名
Would you like to add Angular routing?と聞かれるので、yesを選択してください。
これで、AngularのRouting機能を利用することができます。
次のWhich stylesheet format would you like to use?では、CSSメタ言語を選択することができます。
自分の好きなメタ言語を選択しましょう。
画像の分割
今回作成するアプリでは、画像を分割する必要がありました。
一々自分で切り抜くのは面倒でしたので、Split Labというアプリをインストールして分割しました。
240円で、tiffに変換されたりと少々使い勝手が悪かったですが全然許容範囲です。
元画像はPixabayから拾ってきました。
その画像をSplit Labで分割して、jpegに変換という流れです。
画像の配置
src/assetsにimagesフォルダを配置し画像を入れます。
名前はhorse_1.jpeg〜hose_24.jpegとしました。
フォルダ内画像を一括で変更するには、画像を全て選択。
フォルダ内で二本指でクリック〇〇項目の名前の変更ですることができます。
ドラッグ&ドロップを使えるようにする
Drag&DropはAngularMaterialのCDKを有効化することによって使えるようになります。
Angular Material & CDK & Animationをインストールしましょう。
npm install --save @angular/material @angular/cdk @angular/animations
app.moduleでドラッグ&ドロップ機能をインポート
app.moduleでドラッグ&ドロップ機能をインポートしてください。
import { DragDropModule } from '@angular/cdk/drag-drop';
imports: [
BrowserModule,
AppRoutingModule,
DragDropModule
],
DragDropModuleをインポートした事によって、HTMLにcdkDragと追加すると要素が動くようになります。
ドラッグ&ドロップの実装
先人が全てを教えてくれていたので、カラムを6つにしました。
Angular v7のDragDropModuleを使ってTrelloっぽいの作ってみた
app.component.html
<!--The content below is only a placeholder and can be replaced.-->
<div class="center">
<h1>
どうぶつパズル
</h1>
<div class="img-wrap">
<div cdkDropList
#columna="cdkDropList"
[cdkDropListData]="column1"
[cdkDropListConnectedTo]="[columnb, columnc, columnd,columne ,columnf]"
class="list"
(cdkDropListDropped)="drop($event)">
<img *ngFor="let item of column1" src="./assets/images/{{item}}" cdkDrag>
</div>
<div cdkDropList
#columnb="cdkDropList"
[cdkDropListData]="column2"
[cdkDropListConnectedTo]="[columna, columnc, columnd,columne ,columnf]"
class="list"
(cdkDropListDropped)="drop($event)">
<img *ngFor="let item of column2" src="./assets/images/{{item}}" cdkDrag>
</div>
<div cdkDropList
#columnc="cdkDropList"
[cdkDropListData]="column3"
[cdkDropListConnectedTo]="[columna, columnb,columnd,columne ,columnf]"
class="list"
(cdkDropListDropped)="drop($event)">
<img *ngFor="let item of column3" src="./assets/images/{{item}}" cdkDrag>
</div>
<div cdkDropList
#columnd="cdkDropList"
[cdkDropListData]="column4"
[cdkDropListConnectedTo]="[columna, columnb, columnc, columne ,columnf]"
class="list"
(cdkDropListDropped)="drop($event)">
<img *ngFor="let item of column4" src="./assets/images/{{item}}" cdkDrag>
</div>
<div cdkDropList
#columne="cdkDropList"
[cdkDropListData]="column5"
[cdkDropListConnectedTo]="[columna, columnb, columnc, columnd,columnf]"
class="list"
(cdkDropListDropped)="drop($event)">
<img *ngFor="let item of column5" src="./assets/images/{{item}}" cdkDrag>
</div>
<div cdkDropList
#columnf="cdkDropList"
[cdkDropListData]="column6"
[cdkDropListConnectedTo]="[columna, columnb, columnc, columnd,columne]"
class="list"
(cdkDropListDropped)="drop($event)">
<img *ngFor="let item of column6" src="./assets/images/{{item}}" cdkDrag>
</div>
</div>
</div>
cdkDropList を cdkDrag 要素セットの親要素に追加する
#todoList=”cdkDropList” ←のように cdkDropListへの参照をテンプレート変数化する
[cdkDropListConnectedTo]=”[doneList]”
移動先としてつなぎたい cdkDropList の参照を指定する
cdkDropListDropped イベントは、ドラッグが終了した時に発火するので、 app.component.ts で定義しておいた drop() メソッドを使う
非常にわかりやすくて助かりました。シェイシェイ。
app.component.ts
CdkDragDrop, moveItemInArray, transferArrayItemをインポートしてください。
import { Component , OnInit } from '@angular/core';
import { CdkDragDrop, moveItemInArray, transferArrayItem} from '@angular/cdk/drag-drop';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit{
title = 'animal-project';
horse: any[];
column1: any[];
column2: any[];
column3: any[];
column4: any[];
column5: any[];
column6: any[];
constructor(){
let arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24];
let a = arr.length;
while (a) {
let j = Math.floor( Math.random() * a );
let t = arr[--a];
arr[a] = arr[j];
arr[j] = t;
}
this.horse = arr;
this.column1 = [
`horse_${this.horse[0]}.jpg`,
`horse_${this.horse[1]}.jpg`,
`horse_${this.horse[2]}.jpg`,
`horse_${this.horse[3]}.jpg`,
]
this.column2 = [
`horse_${this.horse[4]}.jpg`,
`horse_${this.horse[5]}.jpg`,
`horse_${this.horse[6]}.jpg`,
`horse_${this.horse[7]}.jpg`,
]
this.column3 = [
`horse_${this.horse[8]}.jpg`,
`horse_${this.horse[9]}.jpg`,
`horse_${this.horse[10]}.jpg`,
`horse_${this.horse[11]}.jpg`,
]
this.column4 = [
`horse_${this.horse[12]}.jpg`,
`horse_${this.horse[13]}.jpg`,
`horse_${this.horse[14]}.jpg`,
`horse_${this.horse[15]}.jpg`,
]
this.column5 = [
`horse_${this.horse[16]}.jpg`,
`horse_${this.horse[17]}.jpg`,
`horse_${this.horse[18]}.jpg`,
`horse_${this.horse[19]}.jpg`,
]
this.column6 = [
`horse_${this.horse[20]}.jpg`,
`horse_${this.horse[21]}.jpg`,
`horse_${this.horse[22]}.jpg`,
`horse_${this.horse[23]}.jpg`,
]
}
public drop(event: CdkDragDrop<any[]>): void {
if (event.previousContainer === event.container) {
moveItemInArray(event.container.data,
event.previousIndex,
event.currentIndex);
} else {
transferArrayItem(event.previousContainer.data,
event.container.data,
event.previousIndex,
event.currentIndex);
}
}
}
CSSはピクセル固定でやっています。
Animationは公式のもので、レスポンシブ対応もしているんですが、スマホだと小さすぎてやる気が、、、、
Drag and Drop
app.component.scss
.center{
display: flex;
align-items: center;
flex-direction: column;
}
.img-wrap{
display: flex;
flex-wrap: wrap;
width:862px;
height:530px;
justify-content: center;
}
.list{
display: flex;
flex-direction: column;
width: calc(100% / 6);
}
.img-wrap >.list> img{
border:1px solid #dcdcdc;
box-sizing: border-box;
cursor: move;
height: 132.5px;
}
.cdk-drag-animating {
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
}
@media (max-width: 767px) {
.img-wrap[_ngcontent-c0] > .list[_ngcontent-c0] > img[_ngcontent-c0]{
height:50px;
}
}
AngularプロジェクトをFirebaseでdeploy
デプロイ用のファイルをpublicに用意します。
ng build --prod --output-path=public
次にFirebaseツールのインストールをインストールして、Firebaseにログインします。
初回利用の場合はGoogleアカウントでログインする必要性があります。
(sudo) npm install -g firebase-tools
firebase login
次にfirebase init hostingコマンド & firebase deployでサービスを公開することができます。
firebase init コマンドを実行すると、プロジェクト ディレクトリのルートに firebase.json 構成ファイルが作成されます。このファイルは、CLI を使用してサイトをデプロイするために必要です。
firebase init コマンドで聞かれた事に対しては以下のように答えてください。
What do you want to use as your public directory? public
? Configure as a single-page app (rewrite all urls to /index.html)? No
✔ Wrote public/404.html
? File public/index.html already exists. Overwrite? No
firebaseデプロイコマンドを打つと、以下のようにホスティングが開始されるので、終わり次第HostingURLにアクセスすると出来ていると思います。
Angular7プロジェクトをFirebaseでホスティングしてみる
最後に
Firebaseすごいなって。。。

WINDII

最新記事 by WINDII (全て見る)
- Nuxt.js + Contentful。HeadlessCMSでポータルサイトを作る - 2019年12月28日
- IOSアプリをAppStoreに公開する手順書(Ionic) - 2019年9月11日
- IonicAcademyでIonic&Angularでのアプリ開発を学ぶ - 2019年8月30日
この記事へのコメントはありません。