フロントエンドとコーヒー

フロントエンドとか日々のこととか

Three.jsでスケッチするのを日課にして15日が経った。

最近、WebGLを本腰入れてやりたくなったので、毎日CodePenでスケッチ書いてはシェアするというのを日課にしててみた。 とりあえず15日間つづけたので。いくつかピックアップして成果をまとめようと思います。

日々の成果まとめ

1日目

ただ立方体を回転させるだけの簡単なコード。

See the Pen WebGL Day1 Three.js Introduction by Yusuke Omi (@Im0-3) on CodePen.

5日目

カメラが動かないことに飽きてきたので、グリグリ動かしてみた。

See the Pen WebGL Day5 Three.js Change Camera Angle by Yusuke Omi (@Im0-3) on CodePen.

8日目

立方体をいろんな感じに動かしてみた結果。

See the Pen WebGL Day8 Three.js Ferris wheel by Yusuke Omi (@Im0-3) on CodePen.

11日目

金属っぽい質感をめざして、そこからちょっと変えてみた。

See the Pen WebGL Day11 Three.js Fog by Yusuke Omi (@Im0-3) on CodePen.

15日目

パーリンノイズを乗せていろいろやってみたら、スライムっぽくなった。

See the Pen WebGL Day15 Three.js Slime by Yusuke Omi (@Im0-3) on CodePen.

毎日書いてみて思ったこと

最初の方はとにかく、使い方を覚えるため、リファレンスみながら一つづつ使い方を覚えようとやってました。 でもだんだん飽きてきて、後半の方はなんとなくやりたいことを決めて、コードを書いてはリファレンスみるという形ですすめてます。

3Dって聞くとポリゴンっぽい感じのイメージになるけど、15日目のスケッチはちょっと違った質感のものができて面白かった。
あと色味とか質感とか気を配ってグリグリすると、Likeしてくれるのでそれはそれで結構モチベーションになってます。

ライティングあんまりいじってないし、テクスチャまだつかってないし、行列の計算もよくわかってないので継続して頑張ります。

とりあえず、こちらからは以上です

2015年の振り返りと2016年

久々にブログ書きます。完全に放置してました… 2015年自分が一体何をやってきたのか振り返ろうと思い年明け早々書きました。

〜 2014年

新卒のころからやっていたコーヒ屋をやめ、半年ほど独学でWeb制作の勉強をして、制作会社のWebデザイナーとして約1年ちょっと働いてました。 そこでデザインよりもエンジニアリングに興味を持ち、フロントエンドエンジニアになろうと決意。
2014年の秋頃に会社を辞めフリーでちょこちょこ仕事しながら転職活動をし始めて、2014年が終わりました。

1月

転職活動を本格的に始める。ポートフォリオサイトをつくったり、履歴書をつくったり。
このころ、前にやっていたブログをMiddleman + Github Pagesで移行してみたりした。
結局つくって満足して終わったけど…

このころフレームワークに触れてみようと思いとりあえずBackbone.jsも触ったりしてみてた。
github.com

2月

Paper.jsとかp5.jsとかCanvas系のライブラリを触る。
転職活動の末なんとか内定をいただくことができました。 正直、フロントエンドエンジニアとしてはまだまだ未熟だど感じつつの転職活動でした。
でもこれをしてようやく、自分の立ち位置見たいのが見えてきて自分のいままでやってきたことが力になってるって実感できたのがよかった。

3月

ご縁があって株式会社LIGにフロントエンドエンジニアとして入社。
入社早々に店長というあだ名をいただきました。ありがとうございます。
三日で覚えてといわれGitに再入門する。

4月

仕事のほうは入社早々いろいろと任せていだいて、ヒーヒー言いながら業務をこなす。
初のコードレビューでめっためたにされる。
このころはfrontplateのコードをひたすら読んでた記憶。

github.com

5月

現場のプロが教える WEBデザイン 新・スタンダードテクニック37への執筆の話がフロントエンドチームに舞い込んできたので、チャレンジすることに。
初のLIGブログの執筆にビビる。

6月

最初の記事が掲載される。最初の記事はHistory APIについて。
liginc.co.jp

初の書籍執筆に悪戦苦闘する。
このころからシングルページWebアプリケーションの開発・運用案件にアサインされ、AngularJSついて勉強し始めた。
とりあえず、まずはToDoアプリを作るという課題を出され、いろいろ先輩方にご迷惑かけながらもAngularJSとちょっと仲良くなる。

7月

LIGブログ2記事目 liginc.co.jp

案件でマテリアルデザインを踏襲したデザインをしていたため、ひたすらマテリアルデザインのガイドラインを読み込む。
Introduction - Material design - Google design guidelines

相変わらずAngularJSに悪戦苦闘する。 このころはUI Routerの使い方とかやってた気がする。 github.com

しんどかった執筆が終わる。いい経験でした。

8月

LIGブログ3記事目 liginc.co.jp

誕生日の日に現場のプロが教える WEBデザイン 新・スタンダードテクニック37が発売されました!

現場のプロが教える WEBデザイン 新・スタンダードテクニック37

現場のプロが教える WEBデザイン 新・スタンダードテクニック37

さらに、人生初LTも誕生日に迎えることになり、皆さんにお祝いしていただきながら29歳を迎えました。

atnd.org

9月

わたわたしてる中で何を書いていいか迷い、Processing入門の記事を書く。 liginc.co.jp

弊社で持ち回りで執筆している、Web Designing記事を担当する。
このころES6について入門し始める。

babeljs.io

10月

執筆したWeb Desingingが発売される。私は後半2ページを担当しました。

book.mynavi.jp book.mynavi.jp

Web Designing 2015年10月号 [雑誌]

Web Designing 2015年10月号 [雑誌]

なんかやっぱ表現とかインタラクティブなことやりたくて衝動で気にWeb MIDI APIを触る

liginc.co.jp

ついでにMIDIコン購入

KORG USB MIDIコントローラー NANO KONTROL2 ナノコントロール2 ブラック

KORG USB MIDIコントローラー NANO KONTROL2 ナノコントロール2 ブラック

社内のフロントエンドエンジニアの勉強会でgit flowの話とかしたのも確かこの辺。 なぜかGo言語を勉強し始める。Go言語ハンズオンのイベントにも参加。 Go言語に触れて改めてJavaScriptのゆるふわ感を理解する。

このころからもっとライトに技術のことを書きたいと思いQiitaを書き始める。

11月

2回目の登壇。せいとさん執筆の最強のCSS設計出版イベントで設計について話しました。

「最近、Go言語始めました」の会。にも登壇。ここではGobotをつかったIoTについて話しました。

LIGのメンバーとPepper Appの開発をひたすら頑張る。
Pepper App Challengeに応募するも、僕らの作品は落選。
でも株式会社リノベるさんからお話をいただき、共同開発をすることに。

Pepper App Challengeに実際参加して、IoTの難しさを実感するもすごく良い経験させていただきました。

liginc.co.jp

12月

IoT縛りの勉強会! IoTLT vol.10 に登壇

Pepper App Challengeの時のことを発表。

LIGinc Advent Calendar 2015で5つ記事を執筆 qiita.com qiita.com qiita.com qiita.com qiita.com

まとめ

今年はフロントエンドエンジニアとして働き始めた年でもあり、いろいろと刺激の多い年でした。現在の会社に入社して、実際にエンジニアリングについて話せる環境があるのがすごく恵まれているなと実感してます。

後悔してるのはもっともっと外に向けてアウトプットするべきだったなとこれを書きながら思いました。 それとコンテンツの消費量が前と比べると減ったなと思ったので、Web以外にもアンテナを張るようにしたいです。

今年の目標

よりアウトプットをする

・Qiitaでアウトプットを習慣化する。(週1書く)
・自分の興味あるコンテンツ(Web以外も)をSNSで公開する。
・このブログももうちょっと活用する。

自分のサイトを作る

自分のポートフォリオサイトを一新したいと思います。もっと実験的なものを乗せるようなサイトにしたいです。

痩せる

前職で激太りをして、2014年始め70キロ体重があったのですが、徐々に減って今64キロぐらいまで落ちました。 30歳が近くなり、徐々に体力の低下を感じてきているのでしっかり運動する習慣をつけてもう少し健康的に痩せたいと思います。

写真を撮る

大学時代は写真部で撮っていたのですが、最近あまり取れていなかったのでこれも積極的にやりたいです。

去年は大きな変化のあった年だったので、今年はより積極的に飛躍の年にしたいと思います。 どうぞ宜しくお願いいたします。

【AngularJS】 Directiveのreqireプロパティと親子の関係

今日は Directiveのrequireプロパティと親子関係について。

ディレクティブは入れ子にした場合、子のディレクティブのreqireプロパティから親のティレクティブのコントローラーを呼ぶことができます。

まずはデモのソースから。

DEMO

HTML

<my-directive parent="hoge">
  <child-directive child="1"></child-directive>
  <child-directive child="4"></child-directive>
  <child-directive child="8"></child-directive>
</my-directive>

JavaScript

//コントローラー関数
function myCtrl(){
  this.list = [];
  this.add = function(item){
    this.list.push(item);
  }
  this.sum = function(){
    var value = 0;
    for (var i = 0; i < this.list.length; i++) {
      value += this.list[i];
    }
    return value;
  }
}

//親のディレクティブ
function myDirective(){
  return {
    controller: myCtrl,
    scope: {
      parent: '@',
    },
    link: function(scope, element, attrs, ctrl){
      element.html('parent is ' + scope.parent + '<br>');
      element.append('Total child value is' + ctrl.sum());
    }
  }
}
angular.module('app').directive('myDirective', myDirective);

//子のディレクティブ
function childDirective(){
  return {
    require: '^myDirective',
    scope: {
      child: '@',
    },
    link: function(scope, element, attrs, ctrl){
      ctrl.add(parseInt(scope.child));
    }
  }
}
angular.module('app').directive('childDirective', childDirective);

解説

myDirectiveの中にchildDirectiveが含まれた構造になっています。
myDirectiveにはparent、childDirectiveにはchildという属性をつけて、それぞれのディレクティブのscopeプロパティで文字列としてscopeに追加しています。

そしてこのディレクティブ全体の制御するために、myCtrlというコントローラーを用意しました。

コントローラーで主な処理を行い、最終的にmyDirectiveでparent属性と、child属性の合計の数を出力します。

f:id:Im0_3:20150625205950p:plain

ここで用意したコントローラーはmyDirectiveのcontrollerプロパティで指定します。

function myDirective(){
  return {
    controller: myCtrl,
    //中略
    link: function(scope, element, attrs, ctrl){
      //中略
      element.append('Total child value is' + ctrl.sum());
    }
  }
}

controllerプロパティで指定するとlink関数の第4引数でコントローラーを引っ張ってくることができます。 ここではsum()という関数を引っ張ってきています。

次に子のディレクティブです。

function childDirective(){
  return {
    require: '^myDirective',
    scope: {
      child: '@',
    },
    link: function(scope, element, attrs, ctrl){
      ctrl.add(parseInt(scope.child));
    }
  }
}

子のディレクティブのlink関数の第4引数はどのコントローラーを指すのか。実は親のディレクティブが持つコントローラーを指しています。

それを指定することができるのがrequireプロパティです。

require

requireには依存するディレクティブを指定します。指定すると、そのディレクティブのコントローラーをlink関数の第4引数として受け取ることができます。

requireプロパティには以下の様なオプションが存在します。

  • ? : requireで指定したディレクティブを省略可能にする
  • ^ : 依存するディレクティブを先祖の要素から探す

今回は先祖の要素から探すため^を付けて、親のディレクティブ名を指定しました。 このため、myCtrladd()が使用することが出来ました。

もし何も付けないで使用する場合はディレクティブにng-model属性をつけて使うパターンが多いようです。

HTML

<another-directive ng-model="item"></another-directive>

JavaScript

function anotherDirective(){
  return {
    require: 'ngModel',
    scope: {
      child: '@',
    },
    link: function(scope, element, attrs, ctrl){
      //何らかの処理
    }
  }
}

この場合はng-modelに指定したティレクティブに依存するようになります。

上記のコードで、ng-model属性をつけ忘るとエラーが発生します。ただしrequreプロパティの先頭に?をつけると、省略が可能になるのでエラーが発生しなくなります。

まとめ

今回のようにディレクティブが入れ子になる際はrequireプロパティを使用すると、同一のコントローラーを使用できるようになります。 複数のディレクティブで構成されたコンポーネントを作る際は重要になりそうなので、ちゃんと使えるようになりたいですね。

AngularJSはまだまだ奥が深いけど、関係を少しずつ理解してくると楽しい。

【AngularJS】Directiveのscopeプロパティを理解する

最近AngularJSを触るようになって。一番最初に詰まったのがControllerとDirectiveの関係性でした。 今回はそこで必要になってくるDirectiveのscopeプロパティについてメモ。

scopeプロパティがfalseの時

HTML

<div ng-controller="MyCtrl">
  <div>Controller: {{ test }}</div>
  <my-directive></my-directive>
</div>

JavaScript

function myDirective(){
  return {
    scope: false,
    template: '<div>Directive: {{ test }}</div>',
    link: function(scope){
      scope.test = 'test!!!!';
    }
  }
}

angular.module('app').directive('myDirective', myDirective);

ディレクティブのscopeプロパティにfalseを指定すると、ディレクティブを使用している箇所のスコープを共有します。 なので、この場合はMyCtrlのスコープを共有することになります。

そのため、ディレクティブのscope.testはコントローラー側でも取得できるため、両方に'hoge'の文字が表示されます。

f:id:Im0_3:20150624194554p:plain

なお、scopeプロパティを省略した場合はfalseと同じ挙動になります。

scopeプロパティがtrueの時

function myDirective(){
  return {
    scope: true,
    template: '<div>Directive: {{ test }}</div>',
    link: function(scope){
      scope.test = 'hoge';
    }
  }
}

angular.module('app').directive('myDirective', myDirective);

次にscopeプロパティをtrueに変更します。 すると、今度はディレクティブを使用している箇所のscopeのインスタンスがディレクティブに渡ります。

そのため、この場合はコントローラー側の{{ test }}にはデータが渡らず、ディレクティブのみ'hoge'が表示されます。

f:id:Im0_3:20150624194639p:plain

このscopeは共有のスコープでもプロトタイプ継承をしたものでもなく新しいscopeとして存在しています。

もし親のscopeにアクセスしたい場合は$parentを使用します。

function myDirective(){
  return {
    scope: true,
    template: '<div>Directive: {{ test }}</div>',
    link: function(scope){
    }
  }
}

angular.module('app').directive('myDirective', myDirective);

このように、$parentを使用した場合は親のscopeのtestに'hoge'が追加されるので、結果は以下のようになります。

f:id:Im0_3:20150624194554p:plain

分離スコープを使う

スコープにはもうひとつ、分離スコープを使用する方法があります。
分離スコープはディレクティブの属性に値を指定すると、それがディレクティブのスコープとして登録されます。

スコープの渡し方は以下のように指定します。

  • = : データバインディングとして受け取る
  • @ : 文字列として受け取る
  • & : 関数として受け取る

以下がその例です。

HTML

<div ng-controller="MyCtrl">
  <input type="text" ng-model="name">
  <my-directive my-name="name" message="Hello" action="sayHello"></my-directive>
</div>

JavaScript

function myDirective(){
  return {
    scope: {
      myName: '=',
      message: '@',
      action: '&'
    },
    template: '<button ng-click="action()">Say {{message}} to {{myName}}.</button>'
  }
}

angular.module('app').directive('myDirective', myDirective);

まずディレクティブに属性を指定します。属性名が複数の単語になる場合はハイフンで指定します。

そして、ディレクティブのscopeプロパティで先ほど指定した属性の値の受け取り方を指定します。 先ほどの属性名をプロパティ名に指定します。プロパティ名はキャメルケースで記述します。

scope.myNameはデータバインディングとして渡しているため、フォームの中身を変更すると、自動的にディレクティブにも反映されます。

f:id:Im0_3:20150624194731p:plain

messageは文字列として受け取っているため、Helloという文字がそのまま渡されます。 actionにはsayHelloという関数が渡されています。ボタンをクリックした際に、その関数が実行されます。

f:id:Im0_3:20150624194745p:plain

分離スコープを利用すると、親のスコープの影響を受けにくくなります。コンポーネントとしていろいろな箇所で使う際には分離スコープを使用するほうがよさそうです。

LINEに送るボタンにtarget="_blank"は付けない

すごい小ネタだけどハマったのでメモ。

最近使用するサイトも増えてるLINEに送るボタン。

media.line.me

iOS8で閲覧時、このボタンをリンクで使用する際、target="_blank"をつけると、どうやらApp Storeに飛んでしまうようです。

なので以下のコードにはtarget="_blank"は付けない。

<a href="http://line.me/R/msg/text/?LINE%E3%81%A7%E9%80%81%E3%82%8B%0D%0Ahttp%3A%2F%2Fline.me%2F"><img src="[ボタン画像のURL]" width="[ボタン幅]" height="[ボタン高さ]" alt="LINEで送る" /></a>

LINEのアプリが入ったAndroidとかで確認してないので、確認したら追記する。

webpack + bowerで依存解決がうまくいかない時はaliasをつかうとよいかも

webpack + bowerでライブラリの依存解決がちょっとうまくいかないことがあったのでメモ。

以下はusage with bowerのConfigurationのコードです。

var path = require("path");
var webpack = require("webpack");
module.exports = {
    resolve: {
        root: [path.join(__dirname, "bower_components")]
    },
    plugins: [
        new webpack.ResolverPlugin(
            new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin("bower.json", ["main"])
        )
    ]
}

resolve.rootでbower_componentsのディレクトリへのパスを指定。

そしてResolverPlugin.FileAppendPluginを使用することでwebpackにbowerでインストールしたライブラリを

var $ = require('jquery');

このような形で呼び出すことができるようになります。

ResolverPlugin.FileAppendPluginは一体なにをしているかというと、bower_components内の各ライブラリのフォルダのbower.jsonファイルを確認して、mainに書かれているファイルを取得していくれます。

例えばjQueryのbower.jsonの場合

{
  "name": "jquery",
  "version": "2.1.3",
  "main": "dist/jquery.js",
  "license": "MIT",
  "ignore": [
    "**/.*",
    "build",
    "speed",
    "test",
    "*.md",
    "AUTHORS.txt",
    "Gruntfile.js",
    "package.json"
  ],
  "devDependencies": {
    "sizzle": "2.1.1-jquery.2.1.2",
    "requirejs": "2.1.10",
    "qunit": "1.14.0",
    "sinon": "1.8.1"
  },
  "keywords": [
    "jquery",
    "javascript",
    "library"
  ]
}

このmainに書かれているdist/jqurey.jsを取得してくれているのです。

ただ今回、bowerでインストールしたライブラリの中にbower.jsonが含まれていないものがあったんです。 もちろんうまく読み込むことができませんでした。

なのでそのライブラリに関しては個別に依存を解決することに。

個別に外部ライブラリを読み込むにはresolve.aliasを使います。

var path = require("path");
var webpack = require("webpack");
module.exports = {
    resolve: {
        root: [path.join(__dirname, "bower_components")],
        alias: {
            hoge: 'path/to/hoge.js'
        }
    },
    plugins: [
        new webpack.ResolverPlugin(
            new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin("bower.json", ["main"])
        )
    ]
}

こうすることで

var fuga = require('hoge');

このように呼び出すことができます。

ちなみに指定するパスはbower_componentsからのパスです。

結局はてなブログはじめました

2013年7月からWebデザイナーとして働いていたんですが、今年の3月からフロントエンドエンジニアにジョブチェンジしました。

なので心機一転、はてなブログ始めます。 基本はフロントエンドに関することを書いていくつもりです。

実はいままでもWordPressとかGithub + Middlemanでブログ書いてたんだけど、完全にこっちにシフトしようかと思ってます。

とりあえず小さいネタでもいいからちょこちょこ書いていきたいと思います。

よろしくお願いします。