はじめに
DMM WEBCAMP Advent Calendar 2021 の14日目を担当させて頂く、yuukaです!(о´∀`о)
個人開発でマッチングアプリを作成した際にボタンのクリックだけでなく
スマホアプリのような滑らかなスワイプだったらかっこいいな〜
と考えて、実装した時のことを書いていこうと思います。
今回はjTinderを使って滑らかなスワイプを実装し、ajax通信でDBに値を保存していきす。☺️
プレビュー
前提
- laravel5.5を使用
- laravelの環境構築を終えている
- DBとの接続を終えている
- 新規登録、ログインの実装を終えている
実装手順
1.ER図を確認する
2.新規登録での画像アップロード機能
3.jTinderの導入
4.viewを作成
5.jQueryの記述
6.jQueryの説明
7.DBを確認してみる
#1.ER図を確認する
今回、マッチングの実装には触れずにスワイプの部分の実装
になるのですが
イメージしやすいように全体のER図を作成しました。
マッチングはユーザ同士の繋がりになるので、多対多の関係です。
そのため、ここで作成しているMatchテーブルは、中間テーブルになります。
Matchテーブルには、3つのカラムがあります。
カラム名 | |
---|---|
from_user_id | いいな,イマイチだなと判断するユーザのid (FK) |
to_user_id | いいな,イマイチだなと判断されるユーザのid (FK) |
is_like | いいなと思って貰えるとtrue、イマイチだとfalseをDBに保存 |
#2. 新規登録での画像アップロード機能
マッチングアプリですので、新規登録時に画像を登録する必要があります。
今回、新規登録での画像アップロード機能の実装は省略しています。
まだの方は先にそちらの実装からお願いします。
以下のサイトは、とても分かりやすかったです。
#3. jTinderの導入
公式ドキュメント
1.公式のドキュメント内のjTinder.cssから必要なcssの部分をコピーする
公式のドキュメントで使用している画像は必要ないよ。
という方は、以下のようなコードはコピーしなくて大丈夫です。
可読性を高めるために、必要のないコードは省いていきましょう。
/* jTinder images */
#tinderslide .pane5 .img {
background: url("../img/pane/pane5.jpg") no-repeat scroll center center;
background-size: cover;
}
#tinderslide .pane4 .img {
background: url("../img/pane/pane4.jpg") no-repeat scroll center center;
background-size: cover;
}
~省略~
2.resources/assets/sass
の配下に_jTinder.scss
を作成
以下のような配置になっていれば、大丈夫です。
そして、作成した_jTinder.scss
の中に1.でコピーした内容を貼り付けましょう。
3.作成した_jTinder.scss
をapp.scssでimportする
// Variables
@import "variables";
+ @import "jTinder";
4.jsも同じように作業
公式のドキュメントの
js/jquery.jTinder.js
とjs/jquery.transform2d.js
の中身をコピーします。
resources/assets/js
の配下に
jquery.jTinder.js
とjquery.transform2d.js
を作成します。
以下のような配置になっていれば、大丈夫です。
5.作成した2つのファイルをapp.jsでrequireする
require('./bootstrap');
+ require('./jquery.jTinder');
+ require('./jquery.transform2d');
#4. viewを作成
まずは、resources/views/users
の中にindex.blade.phpを作成します。
@foreach
を使用し、ユーザーの表示画面を実装していきます。
1行目に書かれているid="tinderslide"でjsが発火。
4行目のdata-user_id="{{ $user->id }}"でユーザのidを送っています。
この2箇所を書き忘れないようにしましょう。
<div id="tinderslide">
<ul>
@foreach ($users as $user)
<li data-user_id="{{ $user->id }}">
<img src="{{ Storage::url($user->image) }}" />
<div class="like">
<img src="{{ asset('images/like.png')}}" alt="like" />
</div>
<div class="dislike">
<img src="{{ asset('images/nope.png')}}" alt="dislike" />
</div>
</li>
@endforeach
</ul>
~省略~
ポイントはlikeクラスとdislikeクラスです。
このクラスを呼び出すとプレビューのように顔写真の上に
LIKEやNOPEの画像をかっこよく表示してくれます。
今回、オリジナルの画像を使用していますが、icon, Font Awesomeなどを活用しても可愛いと思います!😊
表示する位置などを変更したい場合はjTinder.css
の以下のコードを編集しましょう。
該当のcssコード
/* Like & dislike badge images */
#tinderslide .like,
#tinderslide .dislike {
opacity: 0;
height: 80px;
position: absolute;
width: 170px;
left: 45px;
top:40px;
z-index: 1;
overflow: hidden;
-webkit-transform: translate3d(0%,0,0) scale3d(1,1,1);
-moz-transform: translate3d(0%,0,0) scale3d(1,1,1);
-ms-transform: translate3d(0%,0,0) scale3d(1,1,1);
-o-transform: translate3d(0%,0,0) scale3d(1,1,1);
transform: translate3d(0%,0,0) scale3d(1,1,1);
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
#5. jQueryの記述
まだまだ、リファクタリングできると思いますので、アドバイス頂けると嬉しいです。
次の章で詳しく説明していきたいと思います。
$("#tinderslide").jTinder({
onDislike: function (user) {
let user_id = user[0].dataset.id;
postMatch(user_id, 0)
},
onLike: function (user) {
let user_id = user[0].dataset.id;
postMatch(user_id, 1)
}
});
let postMatch = function (user_id, is_like) {
$.ajax({
type: "post",
url: "/users",
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
data: {
to_user_id: user_id,
is_like: is_like,
},
}).then((res) => {
console.log(res);
}).fail((error) => {
console.log(error.statusText);
});
};
#6. jQueryの説明
$("#tinderslide").jTinder({
onDislike: function (user) {
let user_id = user[0].dataset.id; // $user->id が取得できる
postMatch(user_id, 0)
},
onLike: function (user) {
let user_id = user[0].dataset.id;
postMatch(user_id, 1)
}
});
~省略~
初めに、1行目の記述によって発火します。
そして、viewを作成で記述した<li data-id="{{ $user->id }}">
で
送った値は、datasetの中のid
に入ります。
今回は、引数をuserと指定しているため、user[0].dataset.id
で値が取得できます。
$("#tinderslide").jTinder({
onDislike: function (user) {
//
},
onLike: function (user) {
//
},
左にスワイプさせると2行目のonDislike:
右にスワイプさせると5行目のonLike:
に飛びます。
この部分の仕組みが気になる方は、jquery.jTinder.js
の記述を調べてみてください。
onLike: function (user) {
let user_id = user[0].dataset.id;
postMatch(user_id, 1)
},
今回は、onLikeの中身を詳しく見ていきます。
1行目の function (user) {
で引数をuserと指定しています。
ここがitemだった場合、item[0].dataset.id
になります。
2行目でuser[0].dataset.id
をuser_id
に代入しています。
3行目でpostMatch
という関数を呼びだしています。
そして、2つの引数を送っています。
1つ目はuser_id
、2つ目はis_like(boolean型)
の値を送っています。
onLike
だと1、onDislike
だと0を引数に設定しています。
0 ... false
1 ... true
続いて、postMatch
という関数について説明していきたいと思います。
この関数の中で、ajax通信を行っています。
const postMatch = function (user_id, is_like) {
};
先ほどのpostMatch(user_id, 1)
が
第一引数と第二引数の(user_id, is_like)
に入ります。
次に、ajax通信の書き方になります。
LaravelでajaxのPOST送信を行うときは、上の4行目で記述しているように
CSRFトークンを追加する必要があります。
忘れてしまうと419エラーなどが起きてしまいます。
$.ajax({
type: "post", // dbに新規登録するのでpostと指定
url: "/users", // 保存する記述をしているコントローラーのurlを指定
headers: { // CSRFトークンを追加
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
data: { // 左側にカラム名、右側に保存したいデータ
to_user_id: user_id,
is_like: is_like,
},
}).then((res) => {
console.log(res);
}).fail((error) => {
console.log(error.statusText);
});
ajax通信が終わり、dbに保存が成功した時は.then
どこかで予期せぬエラーが起きてしまった時は.fail
にとぶように設定します。
#7. DBを確認してみる
スワイプした後にデータがきちんと入っているか確認してみましょう。
is_like
のtureかfalseの判定が間違えていないかもチェックしてみてください。
終わりに
今回は、laravelというよりもjQueryがメインになってしまいました😔
ajax通信やjTinderは、初めての実装だったので楽しかったです!
ぜひ、参考にしてもらえたら嬉しいです😳
今回は、マッチング機能には触れていないのでルーティングやコントローラーの記述は省略しています。
参考文献のYoutubeがとてもわかりやすく説明してくださっているので、実装したいな!と思った方はのぞいてみてください💁
参考文献
この記事は以下の情報を参考にして執筆しました。
jTinderについての実装
マッチングアプリの要件や実装の考え方