しかたらむーの てっくぶろ

組み込みソフトの古参エンジニアがモダンなフロントエンドエンジニアに転生 その進化の記録です

Vue.js + Typescriptで自前のアイコンを操作する

はじめに

アプリの必須アイテム アイコン。複習もかね、Vue+Typescriptでアイコンを表示しクリックイベントをハンドルする実装をシンプルに解説したいと思います。

出来上がりはこんな感じ!

いつもと同じく、まずは出来上がりのイメージから。こんな感じです。 超シンプル!です。
(テーマに特化してわかりやすくするのに至ってシンプルにしてみました)

f:id:Shikataramuno:20190124223213p:plain

コードはここです。
GitHub - Shikataramuno/icon-sample: Vue.js + Typescriptで自前のアイコンを操作する

アイコンの準備

まずはタイトルにあるとおり、アイコンを自前で作ってみましょう。ですが、長くなるので作り方はこちらの記事にまとめました。どうぞお立ち寄りください(😉)。

techblo.shikataramuno.com

⇩ 今回使うのはこのアイコンで、SampleIcon.png というファイル名です。
f:id:Shikataramuno:20190124222405p:plain

表示してみる

では、アイコン操作の実装に取り掛かりましょう。
最初はプロジェクトの作成からです。適当なフォルダで vue create icon-sampleと入力しプロジェクトのひな型を作ります。
今回はプロジェクト名をicon-sampleにしていますが、お好みの名前で問題ありません。

>vue create icon-sample
Vue CLI v3.1.1
? Please pick a preset: Manually select features
? Check the features needed for your project:
 () Babel
 () TypeScript
 () Progressive Web App (PWA) Support
 ( ) Router
 ( ) Vuex
>() CSS Pre-processors
 (*) Linter / Formatter
 ( ) Unit Testing
 ( ) E2E Testing
プロジェクトのひな型できたら、コードを実装していきます。
まず、最初に上で作成したアイコン(SampleIcon.png) を src/assets にコピーします。
そして、デフォルトで作成される src/components/HelloWorld.vue を削除し、以下の
SampleIconView.vue を作成します。
3行目でアイコンの画像ファイルを指定し、4、5行目でサイズを指定しています。

<template>
  <div class="sample-icon-field">
    <img src="../assets/SampleIcon.png" class="icon"
        width='30px'
        height='30px'/>
    <div class="message">{{message}}</div>
  </div>
</template>

<script lang="ts"> import { Component, Vue } from 'vue-property-decorator';

@Component export default class SampleIconView extends Vue { name: string = 'SampleIconView'; message: string = ' ↑ クリック2 !'; clickCount: number = 0; created(): void { console.log('SampleIconView.created'); } } </script>

<style scoped> .sample-icon-field { padding: 5px; width: 100%; } .message { line-height: 30px; } </style>

次に、src/App.vueを修正します。
3行目、9行目、13行目をそれぞれ HelloWorldからSampleIconViewに変更します。

<template>
  <div id="app">
    <SampleIconView/>
  </div>
</template>

<script lang="ts"> import { Component, Vue } from 'vue-property-decorator'; import SampleIconView from './components/SampleIconView.vue';

@Component({ components: { SampleIconView, }, }) export default class App extends Vue {} </script>

npm run serve して localhost:8080 にアクセスしてみましょう。 出来上がりはこんな感じ!の様にアイコンが表示されると思います。でも、表示されるだけで何もオモシロくありません。

クリックイベントをハンドルする

アイコンのクリックイベントハンドラーを登録してみましょう。先ほどのSampleIconView.vueを以下の様に少し変更します。 6行目でアイコンのクリックイベントにハンドラーを登録します。19~23行目でハンドラーを実装します。

<template>
  <div class="sample-icon-field">
    <img src="../assets/SampleIcon.png" class="icon"
        width='30px'
        height='30px'
        @click="iconClicked"/>
    <div class="message">{{message}}</div>
  </div>
</template>

<script lang="ts"> import { Component, Vue } from 'vue-property-decorator';

@Component export default class SampleIconView extends Vue { name: string = 'SampleIconView'; message: string = ' ↑ クリック2 !'; clickCount: number = 0; iconClicked(): void { alert('アイコンがクリックされました!'); this.clickCount++; this.message = ' アイコンが ' + this.clickCount + '回 クリックされました!'; } created(): void { console.log('SampleIconView.created'); } } </script>

これでアイコンをクリックするとアラートが表示され、メッセージがクリック回数とともに変更されていくと思います。 一応、出来上がりです。やりました!

見栄えが…

ここまでで、jpgpngなど画像データをアイコンとして表示し、イベントを補足できるようになりましたが、実は大きな課題があります。 マウスホイールをくりくりっとやってアイコンを拡大してみてください。

f:id:Shikataramuno:20190124231949p:plain

ギザギザが目立って、なんかイケてませんよね。なんとかしたいですよね。

もっとカッチョよくするには

画像データのアイコンでは拡大するとどうしてもカクカクしてしまいます。
拡大しても滑らかに、スマートにイケてる表示を維持するには?それには SVGを使うしかありません。

SVGとはScalable Vector Graphicsと言うベクター形式で拡縮自在なグラフィックスを実現するXMLベースの画像形式です。 詳しくはこちら Scalable Vector Graphics - Wikipedia
次は、このSVGを使ったアイコンの実装方法を紹介、解説したいと思います。

謝辞

最後まで読んでいただきありがとうございます。本記事の内容で、ひとまず画像でアイコンを操作できるようになりました。
次はSVGでもっとかっこいいアイコン操作に挑戦してみます。