はじめに
この記事はOIC ITCreate Club Advent Calendar 2019の25日目の記事です。
きっかけ
弊部の忘年会の際にプレゼント交換をすることになったのですが、先輩から「なんか作れない?」という無茶振りを受け、作成しました。
実装
※忘年会前日に6時間で作成したものです。
完成したものはGitHub Pagesで公開しています。
こちらからアクセスできます。
早く作りたかったので使い慣れたNuxt.jsで開発しています。またBootstrapVueも使用しています。
詳しく知りたい方は、リポジトリを拝見下さい。
1 ... 人数を入力する画面
急遽キャンセルが出るとまずいので参加人数を入力できるようにします。
参加人数を入力後、スタートボタンを押すとstart()
メソッドが呼び出されます。start()
メソッド内では、入力された人数が0以下ならエラー文を表示します。また、data
内で定義したstarted
をtureにし、参加人数の入力画面からガチャを回す画面へと移ります。移る前に、gachaList
へ人数分の長さを持つ配列を代入します。
<template><divclass="container p-5"><h1class="c-title text-center mb-5">ITC忘年会~プレゼント交換~</h1>
// 1
<formv-if="!started"@submit.prevent="start"><divclass="mb-5"><p>人数を入力してね!</p><divclass="d-flex align-items-end"><inputtype="number"class="form-control w-25 mr-3"v-model="peoples"/><div>人</div></div><pv-if="notPeoples"class="text-danger">1人以上入力してください。</p></div><divclass="text-center"><buttonclass="btn btn-primary px-5 py-2"@click="start">スタート</button></div></form></div></template><script>exportdefault{data(){return{peoples:1,notPeoples:false,gachaList:[],started:false}},methods:{start(){this.notPeoples=false;if(this.peoples<=0){this.notPeoples=true;return;}for(leti=1;i<=this.peoples;i++)this.gachaList.push(i);this.started=true;}}}</script><stylescoped>.c-title{font-size:64px;}</style>
2 ... ガチャを回す画面
スタートボタンが押された後に表示する画面です。
少し凝ったものを作成したかったため、CSSでガチャガチャを作成しました。また、回すボタンを押すとガチャガチャを回すアニメーションも作成しました。呼び出す側(親)からstartAnimation
をガチャガチャコンポーネント(子)へ渡し、それがtrue
の場合アニメーションが再生されるように実装しています。
ガチャガチャのCSSに関してはCodePenで公開しましたのでそちらをご確認下さい。
<template><divclass="container p-5"><h1class="c-title text-center mb-5">ITC忘年会~プレゼント交換~</h1>
// 1
<formv-if="!started"@submit.prevent="start">
...
</form>
// 2
<divv-if="started"><div>残りカプセル:{{gachaList.length}}個</div><Gacha:startAnimation="startAnimation"/><divclass="text-center"><buttontype="button"class="btn btn-primary px-5 py-2"@click="turn">回す</button></div></div></div></template><script>importGachafrom"~/components/Gacha"exportdefault{components:{Gacha},data(){return{...startAnimation:false}},methods:{...turn(){this.startAnimation=true;}}}</script>
...
<template><divclass="c-gacha"><divclass="c-gacha-container"><divclass="c-gacha-box"><divclass="c-gacha-capsule c-move-1"><divclass="c-gacha-capsule-color c-red"/></div><divclass="c-gacha-capsule c-move-2"><divclass="c-gacha-capsule-color c-blue"/></div>
...
</div><divclass="c-gacha-body"><divclass="c-gacha-handle"><divv-if="startAnimation"class="c-gacha-handle-bar c-rotate-animation"/><divv-elseclass="c-gacha-handle-bar"/></div><divclass="c-gacha-exit"><divv-if="startAnimation"class="c-gacha-capsule c-show-animation"><divclass="c-gacha-capsule-color":style="{background: returnColor()}" />
</div></div></div></div></div></template><script>exportdefault{props:{startAnimation:{default:false}},data(){return{colorClass:['red','blue','green','yellow']}},methods:{returnColor(){returnthis.colorClass[Math.floor(Math.random()*4)];}}}</script><stylescoped>...</style>
3 ... どのプレゼントが当たったかを表示するモーダル
ガチャを回した後にどのプレゼントが当たったかを表示するモーダルです。
※事前にプレゼントに番号を振っておきましょう
回すボタンを押すとランダムな値(0 〜 gachaList
の長さ - 1の間)を生成します。それを使用しモーダルに表示する数字を決定します。
ガチャガチャのアニメーションが終了してからopenModal()
メソッドを呼び出し、showModal
をtrue
にすることでモーダルを表示しています。また、自分のプレゼントを引いてしまった場合を考慮し、モーダルにはカプセルを戻すボタンも付けました。
ガチャを続けるボタンを押すとsplice()
メソッドを使用しgachaList[ランダムな値]
を取り除きます。
<template><divclass="container p-5"><h1class="c-title text-center mb-5">ITC忘年会~プレゼント交換~</h1>
// 1
<formv-if="!started"@submit.prevent="start">
...
</form>
// 2
<divv-if="started">
...
</div>
// 3
<modalv-if="showModal":number="hitPeopleNumber"@returnCapsule="returnCapsule"@continueGacha="continueGacha"/></div></template><script>...importModalfrom"~/components/Modal"exportdefault{components:{...Modal},data(){return{...randomIndex:0,hitPeopleNumber:0,showModal:false}},methods:{...turn(){...this.randomIndex=Math.floor(Math.random()*this.gachaList.length);this.hitPeopleNumber=this.gachaList[this.randomIndex];setTimeout(this.openModal,4000);},openModal(){this.showModal=true;},returnCapsule(){this.startAnimation=false;this.showModal=false;},continueGacha(){this.gachaList.splice(this.randomIndex,1);this.startAnimation=false;this.showModal=false;}}}</script>
...
<template><div><divclass="c-modal"><divclass="c-modal-content"><h3class="c-modal-title">{{number}}</h3><divclass="c-modal-footer"><buttonclass="btn btn-danger mb-3"@click="returnCapsule">カプセルを戻す</button><buttonclass="btn btn-primary mb-3"@click="continueGacha">ガチャを続ける</button></div></div></div></div></template><script>exportdefault{props:{number:{default:1}},methods:{close(){this.$emit('closeModal');},returnCapsule(){this.$emit('returnCapsule');},continueGacha(){this.$emit('continueGacha');}}}</script><stylescoped>.c-modal{width:100vw;height:100vh;background-color:rgba(100,100,100,0.4);position:fixed;top:0;left:0;}.c-modal-content{width:50%;height:500px;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);background-color:white;text-align:center;}.c-modal-title{position:absolute;top:42.5%;left:50%;transform:translate(-50%,-50%);font-size:150px;}.c-modal-footer{display:flex;flex-wrap:wrap;position:absolute;width:100%;justify-content:space-around;bottom:30px;padding:020px;}</style>
4 ... 終了を表示するモーダル
ガチャガチャを回し終わった後に表示するモーダルです。
ガチャガチャを人数分回しgachaList
の長さが0になると、finished
がtrue
となり、終了を表示するモーダルが表示されます。モーダルの閉じるボタンを押すと参加人数を入力する画面へ切り替わります。
<template><divclass="container p-5"><h1class="c-title text-center mb-5">ITC忘年会~プレゼント交換~</h1>
// 1
<formv-if="!started"@submit.prevent="start">
...
</form>
// 2
<divv-if="started">
...
</div>
// 3
<modal.../>
// 4
<finish-modalv-if="finished"@close="closeFinishModal"/></div></template><script>...importFinishModalfrom"~/components/FinishModal"exportdefault{components:{...FinishModal},data(){return{...finished:false}},methods:{...continueGacha(){...if(this.gachaList.length===0)this.finish();},finish(){this.finished=true;},closeFinishModal(){this.started=false;this.finished=false;}}}</script>
...
<template><div><divclass="c-modal"><divclass="c-modal-content"><h3class="c-modal-title">終了しました!</h3><buttonclass="btn btn-primary px-5 c-modal-btn-primary"@click="close">閉じる</button></div></div></div></template><script>exportdefault{methods:{close(){this.$emit('close');}}}</script><stylescoped>.c-modal{width:100vw;height:100vh;background-color:rgba(100,100,100,0.4);position:fixed;top:0;left:0;}.c-modal-content{width:50%;height:500px;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);background-color:white;text-align:center;}.c-modal-title{width:100%;position:absolute;top:42.5%;left:50%;transform:translate(-50%,-50%);font-size:50px;padding:020px;}.c-modal-btn-primary{position:absolute;bottom:50px;left:50%;transform:translateX(-50%);}</style>
これで完成です。
再度ですが、こちらから完成したサービスを確認することができます。
最後に
実際の忘年会ではこのWebサービスを使用し、プレゼント交換が楽しく行われました。
参加して下さった方々が楽しそうにしていたので、作成した甲斐があったと思います。