2019/08/27
学びたてだけどVue.js + CSSアニメーション + 絵を組み合わせて作ってみたい!
という事でシンプルなカップラーメンのタイマーを作ってみました。
基本的なVue.jsで始めたばかりの方でも比較的読み進めやすいと思います。
話題のFirebaseで無料公開もとても簡単だったので方法をまとめました。
・アプリURL
https://cupramen-timer.firebaseapp.com/
・GitHub - ソースコード
https://github.com/aocattleya/Ramen-Timer
(いいねやスター貰えるととても喜びます!)
使用している物 | 説明 |
---|---|
HTML, CSS | animationプロパティを使用 |
Vue.js | JavaScriptフレームワーク |
Firebase | 無料枠でアプリを公開する |
--- | --- |
SweetAlert | アラートを簡単にデザインするライブラリ |
GoogleFonts | フォントの変更 |
FireAlpaca | ペイントツール(無料) |
レイヤーといって何枚もの板が重なっているように描かれています。
なので例えば手を消すと下に隠れている髪が出てきます。
これによって一枚描いたら背景などが簡単に変更でき、左右反転させて手を描けば2枚完成。
※猫の方が万人受けする。名前募集中!
こちらに原寸サイズ画像&レイヤーファイルを公開しています。
illustration-Original_Characters(GitHub)
それぞれ分けて解説していきます。
コードは分かりやすいように関係ない部分を大幅に省略して書いてます。
1行目、v-bind:class=""
によってclassを「右顔CSS」⇔「左顔CSS」と書き替えており、
きっかけは、それぞれの3分と5分ボタンにあるv-on:mouseover=""
<!-- キャラクター -->
<img v-bind:class="{ right_face: isRight, left_face: isLeft }" />
<div class="pick-button">
<!-- 3分ボタン -->
<input type="image" src="img/3min.png" v-on:mouseover="rotate_left" />
<!-- 5分ボタン -->
<input type="image" src="img/5min.png" v-on:mouseover="rotate_right" />
</div>
</div>
JavaScript側では下記のようにボタンをホバーした時に、
「true」⇔「false」で切り替わる処理を書いています。
const vm = new Vue({
el: "#app",
data: {
isLeft: false,
isRight: true,
},
methods: {
rotate_left: function() {
this.isLeft = true;
this.isRight = false;
},
rotate_right: function() {
this.isLeft = false;
this.isRight = true;
}
}
});
右顔のCSSアニメーション
.right_face {
border-radius: 50%;
background-image: url(../img/button_right.png);
animation: anime 0.4s linear 2;
}
@keyframes anime {
100% {
transform: rotateY(360deg);
}
}
・border-radius: 50%
で画像を丸くする。
・そしてanimation
プロパティ、長さなどを設定でき@keyframes
で動きを付けます。
上記は100%
終了時までにY軸に360度回転
としています。
3分 or 5分ボタンを押すとv-on:click="show = !show"
によって、
<div v-show="!show">
⇔ <div v-show="show">
と画面表示が切り替わります。
<!-- 3分 or 5分ボタン選択画面 -->
<div v-show="!show">
<input type="image" src="img/3min.png" v-on:click="show = !show" />
<input type="image" src="img/5min.png" v-on:click="show = !show" />
</div>
<!-- タイマー画面 -->
<div v-show="show">
<span id="minutes">{{ minutes }}</span>
<span id="middle">:</span>
<span id="seconds">{{ seconds }}</span>
<!-- 省略 -->
</div>
<!-- 3分 or 5分ボタン -->
<input type="image" src="img/3min.png" v-on:click="show = !show; threeMin()" />
<input type="image" src="img/5min.png" v-on:click="show = !show; fiveMin()" />
3分 or 5分ボタンをクリックした時に、
v-on:click="threeMin()"
又はv-on:click="fiveMin()"
が実行され、
タイマー画面でカウントする時間を3:00 or 5:00にします。
<!-- タイマー -->
<div class="timer">
<span id="minutes">{{ minutes }}</span>
<span id="middle">:</span>
<span id="seconds">{{ seconds }}</span>
</div>
<div id="buttons">
<!-- スタート -->
<input type="image" src="img/start.png" v-on:click="startTimer" v-if="!timer" />
<!-- ストップ -->
<input type="image" src="img/stop.png" v-on:click="stopTimer" v-if="timer" />
<!-- リセット -->
<input type="image" src="img/reset.png" v-on:click="resetTimer" v-if="resetButton" />
</div>
タイマーのカウントは、HTMLの{{ minutes }} : {{ seconds }}
この部分がVue.jsの処理でタイマーのように変更されていきます。
const vm = new Vue({
el: "#app",
data: {
timer: null,
pickTime: null,
totalTime: null,
resetButton: false
},
methods: {
// 3分 or 5分ボタン
threeMin: function() {
this.pickTime = 3 * 60;
this.totalTime = this.pickTime;
},
fiveMin: function() {
this.pickTime = 5 * 60;
this.totalTime = this.pickTime;
},
// スタート
startTimer: function() {
this.timer = setInterval(() => this.countdown(), 1000);
this.resetButton = true;
},
// ストップ
stopTimer: function() {
clearInterval(this.timer);
this.timer = null;
this.resetButton = true;
},
// リセット
resetTimer: function() {
this.totalTime = this.pickTime;
clearInterval(this.timer);
this.timer = null;
this.resetButton = false;
},
// 秒が一桁の場合0を追加
padTime: function(time) {
return (time < 10 ? "0" : "") + time;
},
// カウントダウン
countdown: function() {
if (this.totalTime >= 1) {
this.totalTime--;
} else {
this.totalTime = 0;
this.resetTimer();
swal("Complete!!", "", "success");
}
}
},
computed: {
// タイマーの数値
minutes: function() {
const minutes = Math.floor(this.totalTime / 60);
return minutes;
},
seconds: function() {
const seconds = this.totalTime - this.minutes * 60;
return this.padTime(seconds);
}
}
});
computed:
の部分がHTMLのタイマー{{ }}
に表示され、ボタンで各methods:
が働き、
スタートを押すとsetInterval()
により、一秒ごとにcountdown
が実行されます。
簡単にアラートがデザイン出来るライブラリ
ブラウザからCDN経由で読み込みができます。
<script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
swal("Complete!!", "", "success");
これだけ、凄い!
このアラートはスマホでも同じデザインで表示されます。
その他の使い方は下記のページが分かりやすいです。
- SweetAlertバージョン2を使ったデモ
Firebase - Google
最近とても話題のFirebaseで、作成したアプリを無料で公開。
データベースなど複雑に使う事も可能ですが、今回は簡単に無料で公開してみます。
下記はQiita用にtest
プロジェクトで進めていますが、任意の名前にしてください。
1、ログイン
Firebaseのページを開いてログイン
Googleアナリティクスの設定を聞かれます。
今回は、使用しないで進めます。
4、Node.jsのインストール
まだ入ってない方はインストールしてください。
すぐ終わります。
5、firebase-toolsをインストール
npm install -g firebase-tools
6、ログイン
firebase login
利用状況のデータを送っても良いか聞かれたら任意でY/n
次にGoogleログイン画面が表示されるので、アカウントを選び進めます。
7、デプロイ設定
cd Desktop/test
プロジェクトのフォルダに移動します。
firebase init
◉ Hosting: Configure and deploy Firebase Hosting sites
Hosting
をスペースで選択してからEnterを押します。
※スペースで選択していなとエラーとなる。
? Please select an option:
Don't set up a default project
を選択してEnter
? What do you want to use as your public directory?(public)
そのままEnter(デフォルトのpublic
となる)
? Configure as a single-page app (rewrite all urls to /index.html)? (y/N)
そのままEnter(デフォルトでN)
? File public/index.html already exists. Overwrite? (y/N)
index.htmlを上書きしていいか聞いてくるのでN(そのままEnterでN)
8、公開する
firebase use --add
上記でEnter
? Which project do you want to add?
> test-71a0e
作成したプロジェクトを選択します。
? What alias do you want to use for this project? (e.g. staging)
名前は任意です。今回はstaging
としました。
firebase deploy
firebase deploy
すればOKです。
9、Hosting URL:
をブラウザでアクセスこうして完成、簡単にFirebaseでの公開も出来ました。使ってね!
・ラーメンタイマー
https://cupramen-timer.firebaseapp.com/
・ソースコード - GitHub
https://github.com/aocattleya/Ramen-Timer
Vue.jsで何か作ってみたい、CSSアニメーションと絵も組み合わせたい!
そんな考えから作ってみたアプリでシンプルに見えて苦戦もありました。
しかし言語を学習してるだけと違い、新たな発見と理解はとても多かったです。
基本的な構文でここまで作れて達成感も大きかったのでやって凄く良かったと思います。
次はさらにレベルを上げて作ってみたいですね!
最後まで読んでくれてありがとうございました。
・【CSS3】@keyframes と animation 関連のまとめ
・SweetAlertバージョン2を使ったデモ
・Firebaseを用いて5分でセキュアなWebサイトを公開する
GitHub
https://github.com/aocattleya
🐦 Twitter
https://twitter.com/aocattleya
📗 Qiita
https://qiita.com/aocattleya