#出来たもの
「検索」で、指定した年度・クールごとのアニメ番組一覧を表示してくれるWebアプリ。
※実際に動くものはコチラにアップしてます。
#利用ライブラリ
・Vue.js
CDN:https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js
・Bootstrap
CDN:https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js
CDN:https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.3/js/bootstrap.min.js
・axios
CDN:https://cdnjs.cloudflare.com/ajax/libs/axios/0.21.0/axios.min.js
・ShangriLa Anime API
#やりたかったこと
新アニメが始まった時にとりあえず1話見てみて、減らしていくことが多い。(1話すら見ないこともあるが。)
始まってすぐだと、タイトルだけだと分からないことが多いので、自分用で優先順位を管理できるようなWebアプリを作ってみたかった。
・年度、クールでアニメ番組を取得して取捨選択。
・優先順付けて並び変え。または削除。
みたいなことをやりたかった。
#出来なかったこと
四苦八苦の様子、参考にしたURLなどは自分用メモとして保管してます。
Webサイトのサムネイル画像を取得して表示したかったが、上手くいかず。。
色々調べて試してみて、最終的にはWebページのOGPイメージ(og:image)を取得すれば良い考えにシフトしたが時間が足りなくイメージ画像の取得が上手くいってません。
#改善点(今後に期待)
今回時間なくて断念したが、色々改造したい。
・ちゃんとサムネイル画像を表示できるようにしたい。
・ビジュアルをもっとかっこよくしたい。
・番組の曜日、時間、PV再生など追加したい。
・検索結果の保存。
・カードの並び変えや削除。
#コード
<!-- 全体をVue.js有効にする -->
<div class="container text-center text-white bg-dark" id="app">
<!-- タイトル行 -->
<div class="row my-3">
<div class="col-sm-6 mx-auto"><h1>ANIME Watch</h1></div>
</div>
<!-- 検索フォーム -->
<div class="form-inline justify-content-center">
<input v-model:value="Year" placeholder="2020" class="form-control">
<label class="col-sm-1">年</label>
<select v-model:value="Cours" class="custom-select">
<option>春</option>
<option>夏</option>
<option>秋</option>
<option>冬</option>
</select>
<div class="col-sm-2">
<button v-on:click="Search" class="btn btn-primary">検索</button>
</div>
</div>
<!-- 全てのタスクをクリアするボタン -->
<div class="row my-3">
<div class="col-sm-6 mx-auto">
<button v-on:click="clearAll" class="btn btn-danger">検索結果のクリア</button>
</div>
</div>
<!-- タスク追加されると表示される部分 -->
<div class="flex-container">
<p v-for="Anime in AniData">{{Anime.Title}}<br>
<a v-bind:href="Anime.WebUrl" target="_blank">
<img v-bind:src="Anime.ImgUrl" width="250" height="150"></img>
</a>
</p>
</div>
</div>
const app = new Vue({
el: '#app', // Vueが管理する一番外側のDOM要素
data: {
// Vue内部で使いたい変数は全てこの中に定義する
Year: '2020', // 年
Cours: '冬', // クール
Animes: '', // APIで取得したアニメ情報JSON
AniData: [], // 表示するアニメ情報配列
},
methods: {
// 関数はココに記述
Search: async function() {
// 検索時の関数
try {
// クール値を取得
let CoursNo=4;
switch (this.Cours){
case '春': CoursNo=1; break;
case '夏': CoursNo=2; break;
case '秋': CoursNo=3; break;
case '冬': CoursNo=4; break;
}
// ShangriLa Anime API Server
let response;
response = await axios.get(`https://api.moemoe.tokyo/anime/v1/master/${this.Year}/${CoursNo}`);
this.Animes = response.data;
// アニメ情報表示用配列作成
this.AniData = [];
for (var item in this.Animes) {
var data = {Title: this.Animes[item].title,
WebUrl: this.Animes[item].public_url,
ImgUrl: ""};
this.AniData.push(data);
}
/*
// OGP取得 上手くいかないからあきらめ。
const CORS_PROXY = 'https://cors-anywhere.herokuapp.com/'
for await (var item of this.Animes) {
await fetch(CORS_PROXY + this.Animes[item].public_url)
.then((res) => res.text())
.then((text) => {
const el = new DOMParser().parseFromString(text, 'text/html')
const headEls = el.head.children
Array.from(headEls).map((v) => {
//console.log(v)
const prop = v.getAttribute('property')
if (!prop) return
if (prop == "og:image") {
//console.log(prop, v.getAttribute('content'))
var ogimg = v.getAttribute('content')
}
})
var data = {Title: this.Animes[item].title,
WebUrl: this.Animes[item].public_url,
ImgUrl: ogimg};
this.AniData.push(data);
})
}*/
} catch (error) {
console.error(error);
}
},
clearAll: function() {
// 表示クリア時の関数
this.AniData = [];
console.log('クリア');
},
},
});
.flex-container {
display: -webkit-flex;
display: flex;
-webkit-justify-content: center;
justify-content: center;
-webkit-align-items: center;
align-items: center;
flex-wrap: wrap;
}
#感想
Web開発は初でしたが、色々勉強にはなったかな。。
経験積んで、技術力を上げたいと思う。(Web開発は非常に興味あるので。)