- 投稿日:2020-11-29T23:50:25+09:00
【Vue.js】cowsayをブラウザ上に表示させてみた
はじめに
cowsayがかわいいのでVue.jsでブラウザ上に表示させたくなりました。インストール
cowsay-browserを使用します。
ターミナルnpm install cowsay-browserインポート
cowsay-browser
をインポートします。とりあえずコンソールに表示させてみます。
App.vue<script> import cowsay from 'cowsay-browser' export default { created() { console.log(cowsay.say({text : "Hello!"})); } } </script>来た!!
あとはブラウザに表示させるだけです。
ブラウザへ
App.vue<template> <div> <pre>{{ cowsay }}</pre> </div> </template> <script> import cowsay from 'cowsay-browser' export default { data() { return { cowsay: '' } }, created() { this.cowsay = cowsay.say({text : "Hello!"}); } } </script>
な、なんかズレて...る.......
調整する
せっかくなので少しソースコードをいじります。
node_modules>cowsay-browser>lib>cow-definitions.jsをいじればいけそうです。cow-definitions.js//-------省略 "default": "$the_cow = <<\"EOC\";\r\n $thoughts ^__^\r\n $thoughts ( $eyes )\\\\_____\r\n (__)\\\\ )\\\\/\\\\\r\n $tongue ||-------w |\r\n || ||\r\nEOC\r\n", //-------省略おしまい
- 投稿日:2020-11-29T23:15:00+09:00
svelte.jsでゲームをつくってみた
この記事の概要
svelte.js
で間違い探しゲームをつくってみました。いろいろとハマったポイントもあったので忘れないようにメモしていきます。作ったモノの概要
ピクトグラムを使った間違い探しゲームです。
チュートリアルも実装されています。
公開先
ソース
公開先URL(実際に遊べます)
使ったフレームワーク
- svelte.js (JavaScript全体のフレームワーク)
- driver.js (チュートリアル用のライブラリ)
- bulma (CSSのフレームワーク)
svelte.jsを使って困ったこと
npm installで他のパッケージが上手くインストールできない
webpackあたりでエラーが出てインストールできなかったモノがあったので、一旦は
index.html
にCDN
で利用するようにしました。ここらへんはもう少し調査が必要そうです。今回は作ることを優先したので一旦CDN
で利用する形を取りました。配列を追加しても再描画されない
公式のドキュメントにも書いていますが配列を追加しただけだと画面上のオブジェクトが更新されません。
ログで出力するとちゃんと変数に入っているので、結構ココでハマるポイントかもしれません。
それじゃどうすればいいのかというと、変数として再代入することで解決します。svelte.js
の仕様上、変数に再代入されたときだけちゃんと再描画として認識するようです。vue.js
で慣れていると「ナンデダヨ!!」っていう部分です。
- 参考サイト
- https://svelte.dev/tutorial/updating-arrays-and-objects
- 以下のnumberにプッシュしてからの再代入がなんとも・・・
- numbers.push(numbers.length + 1);
- numbers = numbers;
ちなみに今回のソースで該当の部分は以下のとおり
<script> export const changeImage = () => { setAnimation(); imgArray = []; const appearRnd = Math.ceil(Math.random() * appearImg) - 1; const imageRnd = Math.ceil(Math.random() * imageCount); for (let step = 0; step < appearImg; step++) { if (appearRnd == step) { // imgArray.push(`pict_img/${imageRnd}-A.png`); // ※pushの場合は変数に再代入する必要がある // imgArray = imgArray; imgArray = [...imgArray, `pict_img/${imageRnd}-A.png`]; } else { // imgArray.push(`pict_img/${imageRnd}-B.png`); imgArray = [...imgArray, `pict_img/${imageRnd}-B.png`]; } } }; </script> {#if isVisible} <div transition:fly={{ y: 100 }} class="container has-text-centered"> {#each imgArray as img} <BtnPict imagePath={img} clickFunc={clickAction} /> {/each} </div> {/if}使う機能をimportする必要がある
vue.js
だと初期で読み込むcreated
やmounted
などはimportせずに利用できます。svelte.js
の場合は以下のように、その都度読み込む必要があるため面倒です。もしかすると上手くやる方法があるかもしれません。<script> // onMountを使うなら毎回宣言する必要がある import { onMount } from "svelte"; </script>動的にon:clickに対して関数を設定するときに注意が必要
on:click
に関数を設定するときにそのまま設定すると死にます。引数がない場合は()
なしで設定すればよいのですが、引数付きの関数の場合は気をつける必要があります。以下はダメパターン。
<script> export let clickFunc = (msg) => console.log(msg); </script> <p on:click={clickFunc ('コンソールログがタイヘンなことに・・・')}>TEST</p>以下はイイパターン。
<script> export let clickFunc = (msg) => console.log(msg); </script> <p on:click={() => {clickFunc ('ヤッホー')} }>TEST</p>svelte.jsを使ってよかったこと
変数の扱いがわかりやすい
vue.js
に比べてそのままJavaScript
の変数を扱うような感じです。具体的にいうとvue.js
の場合はテンプレートに渡す変数はprops
として渡す必要があります。そしてprops
から渡ってきた変数はそのまま再代入するとwarning
で怒られます。data
で変数を宣言しなおして再代入することが正しいわけです。
vue.js
ですが以下はwarningで怒られます。export default { props: { propsValue: Number }, methods: { editValue() { this.propsValue = 20 } }
vue.js
では以下が正しい姿export default { props: { propsValue: Number }, data() { // プロパティの値を設定 dataValue: this.propsValue }, methods: { editValue() { // データに定義した値を変更 this.dataValue = 20 } }ここまで
vue.js
のことを書いてきましたが、props
やdata()
でそれぞれの変数の扱いがありますが、svelte.js
だとそういった扱いの違いがなく直感的に扱えるのは良い点だと思いました。
svelte.js
で違うコンポーネントに渡したい場合は・・・■ App.svelte
<script> import Nested from './Nested.svelte'; </script> <Nested answer={42}/>
export
をつけるだけで渡せます。■ Nested.svelte
<script> export let answer; </script> <p>The answer is {answer}</p>読み取り専用のストアの変数を設定できる
上記のようにコンポネントで変数を渡し合うことでどこで何の変数が使われているか把握しづらくなります。1対1で渡すだけならいいのですが、コンポネントに渡してその先のコンポネントに渡してのバケツリレーになったりすると悲惨です。
そのためにアプリケーションで扱うデータセットを
store
と呼ばれる領域で一元管理することで、各コンポーネントはstore
にアクセスすれば常に共通の値を参照する仕組みがあります。これはvue.js
でも同様でいろいろなコンポネントから値を参照する場合に有効だったりします。ここでも
vue.js
の話になりますが、vue.js
の場合はstore
にgetter
やsetter
を記述して、store
の変数を参照したいときはgetter
を使い、store
の変数を更新したいときはsetter
を使うわけです。
svelte.js
でもstore
を使えるわけですがよりわかりやすく使用できます。■store.js
import { writable } from 'svelte/store'; export const ST_score = writable(0);■App.js
<script> import { ST_score, ST_gamestart } from "./stores.js"; import { get } from "svelte/store"; //更新 ST_score.set(100); //他のコンポネントから更新されたか検知したい場合はsubscribeを利用 let score = 0; ST_score.subscribe((value) => { score = value; }); //ちなみにsvelte/storeのgetでも取得はできる //(ただし他での更新は検知されない) //初期値を代入するときに利用できそう console.log(get(ST_score)); </script>ただし扱いやすくなる反面、使われたくないタイミングで使われるケースもあるわけです。例えば、変なところで変数を更新されたくないため、読み取り専用にしたいな~というケースもあるわけです。そこで
svelte.js
ではJavaとかでいうところのカプセル化のような隠蔽化するような仕組みもあります。今回の作ってみたモノではハイスコアを読み取り専用にしてスコアの状態からハイスコアを更新するようにしています。ちなみにハイスコアはローカルストレージに保存するようにしています。
import { readable, writable } from 'svelte/store'; import { get } from 'svelte/store'; const lsKey_hiScore = "hiscore" let lsHiScore = localStorage.getItem(lsKey_hiScore); lsHiScore = lsHiScore ? lsHiScore : 0; export const ST_score = writable(0); export const ST_hiScore = readable(null, function start(set) { //readableで初期値をセットできる set(lsHiScore); //この中だけで値の更新ができる //スコアの変更を検知して条件によって更新する ST_score.subscribe(value => { console.log('hi-score: ' + get(ST_score)); if (lsHiScore < value) { set(value); localStorage.setItem(lsKey_hiScore, value); } }); });最初から使えるトランジションが便利(効果や演出がラク)
フェードインやスクロールインのアニメーションなどカンタンに使えます。
時間の設定なども細かくできるので他のCSSのライブラリとか使わずアニメーションを設定出来るのは便利かなと。
ただし、使うトランジションごとにインポートは必要で、コンポネント各所で利用すると思ったとおりの演出にならないこともあるので、イイカンジにお付き合いする必要があります。
実際にトランジションを使う場合は、if
などで切り替わることでトランジションを発生させることができるようです。もしも初回の表示でトランジションを使いたい場合は、onMount
などで切り替えるとよさそうです。<script> import { onMount } from "svelte"; import { fly } from "svelte/transition"; let isVisible = false; onMount(() => { let isVisible = true; }); </script> {#if isVisible} <p transition:fly={{ y: 100 }}> 下から上にせり上がる感じのやーつ </p> {/if}総評
最初こそはいろいろと
vue.js
との違いで文句があったりしましたが、あとになればなるほどサクサク書けるようになりました。
store
によるreadable
ですが設定することで他のstore
の変数
をトリガーにする形にしているので面倒くさいことになったかなと。
あとは1つのコンポネントが大きくなってきたら細かく分けたり、ここらへんはvue.js
と同様のセンスが必要だったりします。
あとはチュートリアルのライブラリがかゆいところに手が届かなくて試行錯誤したのが苦労したところかなと思います。
- 投稿日:2020-11-29T21:51:48+09:00
【Vue.js】Vue-Cli(4.5.4)でSCSSを読み込む
- 投稿日:2020-11-29T18:07:34+09:00
Vuexを使ってStoreに保存した値を使用する
src/pages/PageFood.vue<template> <div class="container"> <div class="row"> <ul v-for="food in foods" :key="food.id"> <li>Name:{{ food.name }}</li> <li>Description: {{ food.description }}</li> </ul> <div> <div> </template> <sctipt> import { mapGetters } from 'vuex' //vuexからmapGettersというものをインポートする export default { data() { return {} }, computed: { ...mapGetters('foods',['foods']) } } </script>store/store-foods.jsimport Vue from 'vue' const state = { foods: [ { name: 'ハンバーガー', description: 'アメリカ合衆国を代表する国民食とされる。マクドナルドがフランチャイズを成功させ、ファストフードの代名詞となっている。付け合わせはフライドポテトが定番となっている。', }, { name: 'ピザ', description: '日本で初めて紹介されたピザは一般的ではなかったが、1980年代後半より始まったバブル景気の最中(さなか)に起きたイタリア料理ブームに伴い、次第にイタリア風のものも広く知られるようになっていった。', }, { name: 'そら豆', description: '塩ゆでするか、さやごと焼いて、中のマメをそのまま食べる。', }, ] } const getters = { foods(state) { return state.foods //stateのfoodsを返す } } export default { namespaced: true, getters }store/index.jsimport Vue from 'vue' import Vuex from 'vuex' import foods from './store-foods' Vue.use(Vuex) export default function (/* { ssrContext } */) { const Store = new Vuex.Store({ modules: { foods }, // enable strict mode (adds overhead!) // for dev mode only strict: process.env.DEV }) return Store }
- 投稿日:2020-11-29T17:40:29+09:00
5000兆回LGTMしたい!無限にLGTMできるネタアプリを作った
こんなやつ
5000兆円欲しい!という古のネタに触発された。(PCのみ対応)
URL: https://i-want-to-5senchou-lgtm.netlify.app/
GitHub: https://github.com/crypt0box/i_want_to_5senchou_lgtm
作った理由
1. 5000兆回いいねしたかった
Qiitaに溢れる幾多の良記事に1LGTMしかできないのって欠陥じゃない!?!?!?!?
何時間もハマったエラーを解決できたときに、オラァッ!!!!
と感謝の5000兆LGTMをしたいがために作りました。2.CSSの勉強
CSSフレームワークに頼ってばかりだったのでCSSだけで実装してみたかった3.TypeScriptの勉強
TypeScript+Vueの書き方を学びたかった4.Vue.js単体テストの勉強(これから)
テストの書き方がいまだにわかっていないのでシンプルなアプリで試してみたかった使用技術
- TypeScript 3.9.3
- Vue 2.6.11
- axios 0.21.0
- Netlify
Qiitaからトレンドを持ってくるAPIは@HelloRusk様の素晴らしいAPIを使わせて頂きましたm(_ _)m
Netlify Functions を使って Qiita のトレンド API を非公式で作ってみたおわりに
これからは下記の対応をしていこうと思います。
- テストコードの実装
- レスポンシブ対応
- LGTMボタンのチェックボックス化
- 投稿日:2020-11-29T17:13:18+09:00
診察番号表示WEBアプリの作成
概要
耳鼻科の開業医をしています。自院の予約システムをGASを使ったLINE Botで作成し改良してきました。これまでに4500人ほどの患者さんが利用しています。
1時間で出来る LINE×GASで順番取り予約システムの作成
LINE×GASで作成した順番取り予約LINE Botを改良
診察予約システム(LINE×GAS)にプッシュメッセージ機能を追加待合室の患者さんが現在診察中の番号が分かりように今までは既存の無料番号アプリを使って手動で番号を更新していました。自動化できないかと今回も友人に手取り足取り教えてもらいながら作成しました。
実装内容
予約システムのバックエンドはGoogle Spread Sheetを利用、App Script(GAS)でLINE botと連携しています。
作成法はこちら 1時間で出来る LINE×GASで順番取り予約システムの作成
Spread SheetのA1セルが発券済み番号、B1セルが診察中番号、C1セルが「1」の時に発券停止、D1セルが一人当たりの待ち時間(分)、E列に予約券を発行した患者さんのLINE userIDです。今回診察中番号であるGASのB1セルの内容を2秒おきに取得し表示するWEBアプリを作成しました。
機能を追加
1.GASにブラウザからB1セルの内容を取得できるコードを追加
//B1セルの中身を取得できるように追加 function doGet(e) { var result = getNumberB1(); return ContentService.createTextOutput( JSON.stringify({ number: result }) ).setMimeType(ContentService.MimeType.JSON); }2.WEBアプリ用のindex.htmlを作成
<script> // Vue.jsの設定 const app = new Vue({ el: '#app', // <div id="app"></div>をVue.jsの管理対象に指定 data() { return { number: 0, } }, async mounted() { await this.updateView(); setInterval(async () => { await this.updateView(); }, 2000); }, methods: { async getNumber() { const result = await axios.get('GASのURL'); return result.data.number; }, async updateView() { const result = await this.getNumber(); this.number = result; }, async updateViewManually() { try { await this.updateView(); setTimeout(() => { alert('更新しました。'); }, 500); } catch(e) { alert('更新に失敗しました。'); } }, } }); </script>3.WEBアプリ用style.cssを作成
4.Herokuにデプロイ
公式はこちらDeploying with Git
gitが認識されない時はgitをインストール https://git-scm.com/cd myapp heroku create git init git add . git commit -m "commit" heroku git:remote -a アプリ名 git push heroku masterエラーが出る
remote: ! No default language could be detected for this app. remote: HINT: This occurs when Heroku cannot detect the buildpack to use for this application automatically. remote: See https://devcenter.heroku.com/articles/buildpacks remote: remote: ! Push failed「No default language could be detected for this app.heroku html」で検索するとこちらの記事がトップに出てくる。
単純なHTML/CSS/JSをHerokuにデプロイする時つまずいたこと
HerokuはHTMLとCSSだけのデプロイは基本許してないサービスだが、PHP追加するとかわせるよう。
5.こちらの記事を参考にindex.phpとcomposer.jsonを追加
Gitのコマンドは基本、add → commit → pushが1セットなので、変更したら必ずこの3つを実行する
完成
おおおお!!!出来たー!!!
欲しいものが作れるとすごく楽しいですね。明日から実際に使ってみます。
Takahiro Mitsuokaさん(マイページはこちら)ありがとうございました!
- 投稿日:2020-11-29T17:13:18+09:00
診察中番号表示WEBアプリの作成
概要
耳鼻科の開業医をしています。自院の予約システムをGASを使ったLINE Botで作成し改良してきました。これまでに4500人ほどの患者さんが利用しています。
1時間で出来る LINE×GASで順番取り予約システムの作成
LINE×GASで作成した順番取り予約LINE Botを改良
診察予約システム(LINE×GAS)にプッシュメッセージ機能を追加待合室の患者さんが現在診察中の番号が分かりように今までは既存の無料番号アプリをipadで表示し手動で番号を更新していました。自動化できないかと今回も友人に手取り足取り教えてもらいながら作成しました。
実装内容
予約システムのバックエンドはGoogle Spread Sheetを利用、App Script(GAS)でLINE botと連携しています。作成法はこちら 1時間で出来る LINE×GASで順番取り予約システムの作成
Spread SheetのA1セルが発券済み番号、B1セルが診察中番号、C1セルが「1」の時に発券停止、D1セルが一人当たりの待ち時間(分)、E列に予約券を発行した患者さんのLINE userIDです。
今回診察中番号であるGASのB1セルの内容を2秒おきに取得し表示するWEBアプリを作成しました。
機能を追加
1.GASにブラウザからB1セルの内容を取得できるコードを追加
//B1セルの中身を取得できるように追加 function doGet(e) { var result = getNumberB1(); return ContentService.createTextOutput( JSON.stringify({ number: result }) ).setMimeType(ContentService.MimeType.JSON); }2.WEBアプリ用のindex.htmlを作成
<script> // Vue.jsの設定 const app = new Vue({ el: '#app', // <div id="app"></div>をVue.jsの管理対象に指定 data() { return { number: 0, } }, async mounted() { await this.updateView(); setInterval(async () => { await this.updateView(); }, 2000); }, methods: { async getNumber() { const result = await axios.get('GASのURL'); return result.data.number; }, async updateView() { const result = await this.getNumber(); this.number = result; }, async updateViewManually() { try { await this.updateView(); setTimeout(() => { alert('更新しました。'); }, 500); } catch(e) { alert('更新に失敗しました。'); } }, } }); </script>3.WEBアプリ用style.cssを作成
4.Herokuにデプロイ
公式はこちらDeploying with Git
gitが認識されない時はgitをインストール https://git-scm.com/cd myapp heroku create git init git add . git commit -m "commit" heroku git:remote -a アプリ名 git push heroku masterエラーが出る
remote: ! No default language could be detected for this app. remote: HINT: This occurs when Heroku cannot detect the buildpack to use for this application automatically. remote: See https://devcenter.heroku.com/articles/buildpacks remote: remote: ! Push failed「No default language could be detected for this app.heroku html」で検索するとこちらの記事がトップに出てくる。
単純なHTML/CSS/JSをHerokuにデプロイする時つまずいたこと
HerokuはHTMLとCSSだけのデプロイは基本許してないサービスだが、PHP追加するとかわせるよう。
5.こちらの記事を参考にindex.phpとcomposer.jsonを追加
Gitのコマンドは基本、add → commit → pushが1セットなので、変更したら必ずこの3つを実行する
完成
おおおお!!!出来たー!!!
欲しいものが作れるとすごく楽しいですね。明日から実際に使ってみます。
Takahiro Mitsuokaさん(マイページはこちら)ありがとうございました!(2020年12月1日追記)
「あれ?Vue.jsがちゃんと表示できてない!?」
とても古いiPadを使っていたからのようです。少し新しいiPadにしたら表示されました。スタッフも喜んでました。
待合患者さん用に診察中番号を表示するWEBアプリを自作し連動させる pic.twitter.com/yPvErYCyXz
— 病気のセルフチェック (@Selfcheckhealt1) December 1, 2020予約システムの動画はこちら
クリニックの予約システムを自作しました。 pic.twitter.com/Auesn6dyUn
— 病気のセルフチェック (@Selfcheckhealt1) December 1, 2020
- 投稿日:2020-11-29T15:11:25+09:00
Vue.js Props $emit 個人チート
propsについて
- 親子間でのデータの受け渡しを行う為に使用する。
- 親では任意の属性名でを子コンポーネントタグで作成して、渡したいデータの定義を行う
親コンポーネント <template> <div id="app"> <Nav :data="message" /> <router-view /> <input type="text" v-model="message" /> <Footer /> </div> </template> <script> import Nav from './component/Nav.vue'; export default { conponents: { Nav, }, data () => { message: 'this is props' } } </script>受け取るには子の方でpropsとして配列で受け取る。
親は属性名にデータが格納された変数と考えよう。なのでpropsに登録するのは属性名。<template> <div> <p>{{ message }}</p> <p>Navです</p> </div> </template> <script> export default { props: ["message"], }; </script> required: true,ちなにオブジェクトとして受けて、型のチェックもできる。
詳しい内容は公式でキュメンとで: Vue.js,props<template> <div> <p>{{ message }}</p> <p>Navです</p> </div> </template> <script> export default { props: { message: { type: String, required: true, }, }, }; </script>reactと比較すると
//親 import React from "react"; import { Nav } from "./Nav"; export default function App() { const message = "this is props"; return ( <> <p>親</p> <Nav message={message} /> </> ); } //子コンポーネント import React from "react"; export const Nav = (props) => { const { message } = props; return <>{message}</>; };ここで忘れてはいけないのは親、子、ひ孫というコンポーネント管理があったとしたら、親→ひ孫へのデータ渡しはできない。
なので上記の方法と一緒でpropsを経由して一つ一つデータを渡して行かないといけない。
流石にこれではprops地獄になるので大規模になればデータの一元管理はVuexが望ましい。$emit
- 子から親へデータを渡す際に活用する。
- 子コンポーネントでmethodsとして$emitを活用する。
- $emit()第1引数はカスタムイベント名、第2引数は渡したいデータ。親はこの第1引数のカスタムイベント名を使用する。登録はケバブ出ないとダメ
<template> <div> <p>{{ message }}</p> <p>Navです</p> <button @click="send">親にデータ送ります</button> </div> </template> <script> export default { props: { message: { type: String, required: true, }, }, data() { return { emitData: "this is emit", }; }, methods: { send() { this.$emit("send-emit-data", this.emitData); }, }, }; </script>
- 親でデータを受け取る。
- データを送ってきた子コンポーネントタグで$emitで送られたエベント名を使用する。
- 今回は引数にメソッドを定義している。
- メソッドの引数はvalueとして受け取る。これが$emitで送信したデータ。後はこれをデータプロパティに代入するだけ。
<template> <div id="app"> <Nav :message="message" @send-emit-data="receive" /> </div> </template> <script> import Nav from "./components/Nav"; export default { components: { Nav, }, data() { return { emitData: "", }; }, methods: { receive(value) { this.emitData = value; console.log(this.emitData); }, }, }; </script>終わりに
実践的チートシートにするべく再度編集予定
- 投稿日:2020-11-29T15:05:45+09:00
オンライン配信授業で、手を挙げたら【●●さん】とさしてくれるwebアプリを作ってみた
自己紹介
大学時代C言語を学んでから十数年以来のプログラミングを始めています。
本業はweb制作で、お客様から悩みや感じている課題についてに相談を受ける事も多いです。
LINEbotを中心に、webの技術を利用してどのようにお客様の悩みや課題を解決出来るのか、広く学んでいます!今回は、Teachable Machineというgoogleが提供する機械学習が簡単に行えるウェブブラウザツールを知り、普段の生活に取り入れてみる事にしました!
【オンライン授業でのメンタルサポートAI】
実際に小学校中学年の子どもがオンラインで配信される塾の授業を受けているのですが、テレビ同様一方通行の授業なので、子供のやる気に波があるんです。
すぐに画面からいなくなったり、気が付いたら違う事をしていたり。。。
やっぱり対面での先生の問いかけがあったら、もっと積極的に授業に参加できるのになとは思いますが、このようなご時世なのでオンラインの方が安心ですよね。家での経験だけではなく、オンライン授業が浸透してきいるなという実感が最近ありました。先日とある塾の保護者会で、通学に不安を感じる低学年向けに配信授業コースを開設するという話がありました。
その時に、低学年だとさらに親が管理をする負担が大きいな~と思っていた所、オンライン授業をサポートするAIがあったら面白い!と思いついたので早速実装してみる事にしました。
シュミレーションです。
こんな機能があったら良いなと思ってます。子どもの表情や動きを機械学習して、状況を判断して問いかけます。
全体の流れ
今回は、機械学習初心者なので単純に
「手を挙げたらさしてくれる」
をまずはwebアプリとして実装します。
実際に作ったもの
webにアップしているのでクリックしていただくと体験できます
開発環境・利用ツール
・Teachable Machine
・Visual Code
・Line API
・node.js
・vue.jsTeachable Machineで画像サンプルを登録
Teachable Machineの使い方は【備忘録】Teachable Machineの利用方法で紹介しています。
1.手を挙げない
2.手を挙げるこの2パターンの画像を学習させます。
登録をしたらトレーニング
トレーニングしてTeachable Machine上では成功!
#Visual Conde
いよいよ、node.jsを利用して、Teachable Machineで作成したモデルを利用して、web上で動作させるようにしたいと思います。<body> <div class="wrap"> <h1>わかったらてをあげてくださいね!</h1> <div id="app"> <input v-model="name" placeholder="おなまえをおしえてください" size="30"> <p>おななえ: {{name}}</p> <p>よろしく おねがいします</p> <p>わかったら てのひらがみえるように てをあげてくださいね</p> <p class="res">{{result}}</p> <video id="video" width="640" height="480" autoplay></video> </div> </div> <script src="https://unpkg.com/ml5@latest/dist/ml5.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> const imageModelURL = 'https://teachablemachine~始まるコードを入力します。'; let video; // let classifier; const app = new Vue({ el: '#app', data: { modelStat: 'モデルロード中...', detectedName: '見つかってない', name: '', result: '', }, //最初の1度だけ実装 async created() { // カメラからの映像取得 const stream = await navigator.mediaDevices.getUserMedia({ audio: false, video: true, }); // html内のidがvideoのdomを取得 video = document.getElementById('video'); // videoにカメラ映像を適用 video.srcObject = stream; // 自作モデルのロード classifier = await ml5.imageClassifier( imageModelURL + 'model.json', video, modelLoaded ); // モデルのロード完了時に実行される async function modelLoaded() { console.log('Model Loaded!'); app.modelStat = 'モデルデータのロード完了'; } async function interval() { // 挙手しているかjudge const myHandResults = await classifier.classify(); const myHand = myHandResults[0].label; if (myHand == "手を挙げる") { app.result = app.name + "さんっ!"; } else { app.result = ""; } console.log(myHand); } setInterval(interval, 3000); // 3秒ごとに処理 }, }); </script> </body>今回ポイントとなったのは2か所
Vue.jsのフォーム入力バインディングを使って、入力した内容を簡単に出力しています。
Vue.jsのドキュメント<input v-model="name" placeholder="おなまえをおしえてください" size="30"> <p>おななえ: {{name}}</p>リアルタイム処理をしたいので3秒間隔で判断しています。
setInterval(interval, 3000); // 3秒ごとに処理さいごに
実装していて、色々なアイディアが出てきました。
また、顔の表情を認識して、眠そうであれば楽しそうな音楽を流す等反応するAIも面白いと思いました。ただ、表情のサンプルを子供から撮るのが難しくて失敗。
その他にも、百人一首の正誤判定する音声認識も企画しましたが、2秒しか音声サンプル入力できないので、出だしの「ありあけの~」で終わってしまうので、これも失敗。
結果として、今回は手を挙げているか挙げていないかだったので、高確率で判断してくれる機械学習を体験する事が出来ました。ポーズを使うと骨格が取れるので、より高度に認識できるみたいです。
機械学習を使って、一方通行のオンライン配信授業でも授業に参加しているような感覚を体験する事で、オンライン授業がより充実したものになっていくのではないかな~と思いました。
- 投稿日:2020-11-29T10:52:22+09:00
【Vue.js】v-onを使ってカウントアップする【初心者向け】
はじめに
Vue.jsを使うと、簡単に動的なサイトを作れるようになります。
ここでは、v-onというVue.jsの基本構文を使って、クリックで数字をカウントアップさせるサイトを作成していきます。この記事が役立つ方
・Vue.jsを学ぼうか迷っている人
・Vue.jsを学び始めた人この記事のメリット
・Vue.jsでどんなことができるのか、知ることができる
・Vue.jsで使えるv-onに関する基本構文を知ることができる環境
・MacOS Catalina 10.15.7
・vue.js 2.6.12完成形
ボタンを押すと数字がカウントされるビュー。
v-onとは?
(例)
・マウスをクリックした
・ボタンをクリックした
・マウスが動いたという『瞬間』に動作を発火させたいときに使う。
今回は、ボタンをクリックするたびに数字を増やす『v-on:click』で作成。基本構文
index.html<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <p>現在{{ number }}回クリックされています</p> <button>カウントアップ</button> </div>vue.jsnew Vue({ el: '#app', data: { number: 0 } })このままでは動きません・・・。
index.html<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <p>現在{{ number }}回クリックされています</p> <!-- 以後ここから --> <button v-on:click="countUp">カウントアップ</button> <!-- ここまでで記載 --> </div>vue.jsnew Vue({ el: '#app', data: { number: 0 }, <!-- 以後ここから --> methods: { countUp: function() { this.number += 1 } } <!-- ここまでで記載 --> })無事、カウントアップされるようになりました!
おわりに
Vue.jsを使うと、HTMLやCSSだけでは表現できないことも行えるようになります。
最初はとっつきづらいかもしれませんが、実際に動作させていくと、楽しみを覚えると思います!参考
『超Vue.js 2 完全パック - もう他の教材は買わなくてOK! (Vue Router, Vuex含む)』
https://www.udemy.com/course/vue-js-complete-guide/
(動画教材は非常に分かりやすいので、オススメです!)
- 投稿日:2020-11-29T04:58:46+09:00
Laravel 6.x 非同期通信(Ajax) 【JavaScript】 【jQuery】 【axios】 【Vue.js】 各記述方法 ~Vue.js × axios編~
制作環境
Windows 10
Laravel : 6.18.35
Laravel/ui : 1.0
Laravel-mix : 5.0.1
Bootstrap : 4.0.0
axios : 0.19
Vue : 2.5.17
XAMPP
PHP : 7.4.3
Visual Studio Codeはじめに
この記事はプログラミングをはじめたばかりの素人が、できたことをメモするのに利用しています。
内容には誤りがあるかもしれません。前回のつづきになります。
関連記事
Laravel 6.x 非同期通信(Ajax) 【JavaScript】 【jQuery】 【axios】 【Vue.js】 各記述方法 ~事前準備編~
Laravel 6.x 非同期通信(Ajax) 【JavaScript】 【jQuery】 【axios】 【Vue.js】 各記述方法 ~JavaScript編~
Laravel 6.x 非同期通信(Ajax) 【JavaScript】 【jQuery】 【axios】 【Vue.js】 各記述方法 ~jQuery編~
Laravel 6.x 非同期通信(Ajax) 【JavaScript】 【jQuery】 【axios】 【Vue.js】 各記述方法 ~JavaScript × axios編~
Laravel 6.x 非同期通信(Ajax) 【JavaScript】 【jQuery】 【axios】 【Vue.js】 各記述方法 ~jQuery × axios編~
Laravel 6.x 非同期通信(Ajax) 【JavaScript】 【jQuery】 【axios】 【Vue.js】 各記述方法 ~JavaScript × FetchAPI編~
Laravel 6.x 非同期通信(Ajax) 【JavaScript】 【jQuery】 【axios】 【Vue.js】 各記述方法 ~jQuery × FetchAPI編~今回作成するもの
Vue.jsとaxiosを利用し非同期通信を行い、自動で仕入れ先が入力される機能を実装します。
以下作成条件
- Vue.jsを使用し通信にはaxiosを使用します。
- 数字が4桁入力されたら自動で仕入れ先を検索し、反映します。
- 検索するのにクリック操作を必要としません。
input
に入力されたら検索します。- スクリプトの読み込みには
Laravel-mix
を使用します。- 前回作成した
test.js
は使用しません。app.jsの編集
今まで使用してきたtest.jsは今回使用しません。
resources>js
内のapp.js
を開き、読み込みがされないように以下の内容をコメントアウトするか、削除してください。app.jsrequire('./test');続けて
Vue.js
の記述を行います。
app.js
の下の部分に記載があるconst app = new Vue
を以下の用に修正します。app.js// 変数appにVueクラスをインスタンス化(実体化)して代入します // その際引数で初期設定を渡します const app = new Vue({ // id="app"のDOM要素に対しVueインスタンスを与えます // このidをもつ要素の範囲がVue.jsが使える範囲(仮想DOM)になります el: '#app', // キーと値の初期値を設定します data() { return { code: '', supplier: '', } }, // メソッド(機能)を作成します methods: { // 新たにgetSupplierというメソッドを作成し、処理を記述します getSupplier() { // bladeテンプレートipnutの値をtraderCodeに代入します let traderCode = this.code // 業者コードが4桁未満の場合は検索させないようにします if (traderCode.length < 4) { return } // アクセス先のURLを作成し、urlに代入します let url = '/form_search?trader_code=' + traderCode // 次の処理の中ではthis.supplierのように、thisを使えないため // 任意の変数に代入することで使えるようにします var that = this // axiosで指定したURLにGETでアクセスします // .thenで通信に成功した場合の処理を記述します // 引数に変数をいれることで、コントローラからのデータ(検索結果)を受け取れます // ここでは変数responseでデータを受け取っています axios.get(url).then(function(response) { // 受け取ったデータから必要なものだけ取り出し変数に代入します let data = response.data // 受け取ったデータ(検索結果)が仕入れ先のvalueに反映されるよう // supplierに値を代入します that.supplier = data[0].trader_name }) } } });コンパイル
ターミナルを起動し、以下を実行してください。
※node.jsが必要です。インストールされていない方は、インストールを行ってください。node.js
https://nodejs.org/ja/npm run devビューの修正
resources>views
内のindex.blade.php
を開き、以下の部分だけ修正します。index.blade.php<div> <label>業者コード: <input type="text" id="code" v-model="code" @input="getSupplier()"></label> <label>仕入れ先: <input type="text" id="supplier" name="supplier" v-model="supplier"></label> </div>v-model
v-modelを記述するだけで、双方向データバインディング(Two-way Data Binding)を実装できます。
以前記事を投稿しているので、詳しくはこちらを確認してください。
https://qiita.com/Charry/items/a1e6a93f05c7f686b505@input
@input
はv-on:input
の省略型です。
今回は業者コードが入力されたら検索処理を行うので、@input="getSupplier()"
とすることでgetSupplierメソッドを呼び出しています。Vue.jsの場合データの受け渡し方法がわかっていないと、ちょっとわかりづらいですね。
以上で終了です。
お疲れさまでした。