marcwoozie blog

都内のwebエンジニア2年目です

HTML5 Conference 2015に参加して、Web Components革命に影響された話

先日、東京電機大学千住キャンパスにてHTML5Conference2015が開催されましたが、僕はボランティアスタッフとして参加させていただきました。

ボランティアとはいえ、こういったイベントにスタッフとして参加したのは初めてでした。
スタッフ側で参加すると、一般として参加するのとはやはり違うもので、有名な方と業務上であれ関わることが出来るのは良い経験になるなあ。と思いました。


さて、表題の件「Web Components革命に影響された」という部分ですが、そもそもWeb Componentsとはウェブブラウザ向けに作られたAPIの一式のようなもので、2015年1月現在では下記の5つ要素で構成されている。

・Templates
・Decorators
・Shadow DOM
・Custom Elements
・Imports

上の方で偉そうに言っていますが、カンファレンスに参加するまでWeb Componentsというものがよくわかっていなかったというのは内緒でお願いします(聞いたことはありましたよ)

ググってみたらWeb Componentsに関する記事が山ほどあったのでWeb Componentsの説明はもうしませんが、今回なぜWeb Componentsについて触れようと思ったのは今回のカンファレンスでGoogleの北村さんのセッション「Polymerで作る次世代ウェブサイト」を聞いてからフロントエンド技術の流れというのは本当に速くて、すでに取り残されていると感じたからです。

2012年にweb業界に入ってから技術に取り残されるという感覚を全く感じなかったわけではありません、
しかし、専門学校を卒業して会社に入り、それなりに業務をこなせるようになって気がついたら
HTMLコーダーからサーバー側でPHPとかを書くようになって、
自分なりに必死に勉強して、少しずつでもサーバー側のことも出来るようになってきて、
技術に取り残されるという感覚を忘れてしまっていたというか、しばらく味わっていなかった感覚でした。

この感覚って取り残されてると感じると同時に怖いという感情も湧いてきますよね。。。


という感情も束の間で、北村さんの「Polymerで作る次世代ウェブサイト」という話は冒頭で「21世紀はWeb Components革命」という言葉から始まり、Web Componentsの要素の説明、Web Componentsの「Polyfill」である「Polymer」とはなにか、そして実際に「Polymer」を使ったライブコーディング。


フロントエンド技術において化石と化していた僕は興奮していた。(バックエンドも化石みたいなもんだろという意見については受け付けません)




これは革命だ。。




怖いという感情から一変、ワクワクという感情に移り変わったのです(男というのは単純である)



興奮冷めやらぬまま、すべてのセッションが終わり気がつけば僕は

$ bower install polymer

を叩いた。














そしてコケた





bowerが入っていなかったのだ。
入れた気がしていたのでびっくりしたが、気を取り直して

$ npm install bower -g

(nodeは入っていた)

$ bower install polymer

今度こそpolymerがプロジェクト内に入ってきた。


さて何をやるかと考えたが、ここはやはり「Polymerで作る次世代ウェブサイト」でもやっていたTODOアプリにしようと決めた。
ただ全く同じモノを作るのはさすがにつまらないなと思ったのでどうしようと考えたら、「本当はローカルストレージに保存までできたら」と北村さんが言っていたのも思い出して、ローカルストレージに保存するTODOアプリにすることにしました。




で、実際に作ったものが下記です。
poymer.htmlを読みこめばモダンブラウザ以外もWeb Componentsを対応できるらしいのですが、Chrome以外動かないです。。
詳しい方教えて頂ければ幸いです。。。


Todo App



今回ローカルストレージも初めて使いましたが、いろいろ調べているうちにPolymerでは「ローカルストレージ要素」というのがあって何らかの更新があった際に
自動でコールされる関数が使えたりと幸せになれる要素がたくさんありましたが、既に作り終わっていたので、またの機会にしました。



そして今回、作るにあたって下記のサイトなどを参考にさせて頂きました。


Polymer Polytechnic CodeLab


そして今回のコードです。


cssなどだいぶ適当な感じになってしまいましたが、カンファレンスから一週間以内に作ってブログに上げるということを密かに決めていたので今回は見逃してください。

なんだかんだでPolymerでデザインを組み合わせるのが一番難しかったですが、これをきっかけに技術に取り残されないようHappy codingしていきます。

宅配便が来るまで暇なのでcanvasの練習しました。

今日は午前中の8時〜12時までの間に宅配便が届くとの事だったので8時から起きてるけど
なかなか来なくて暇なので昨日ドットインストールで見てたcanvasを使って遊んでみました。

壁にあたったら跳ね返るよくありそうなやつです。


<!doctype html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Canvas</title>
</head>
<body>

  <canvas style="width: 400px; height: 200px; border: 1px solid gray;" id="canvas"></canvas>

<script>
;(function(){

  var canvas, ctx;
  var x = 0;
  var y = 0;
  var radius = 6;
  var gx = true;
  var gy = true;

  var init = function(){
    canvas = document.getElementById("canvas");
    if( !canvas || !canvas.getContext ) return false;
    ctx = canvas.getContext("2d");
    ctx.fillStyle = "rgba(000, 000, 000, .6)";

    (function roop(){
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      if( x >= canvas.width - radius ) gx = false;
      if( y >= canvas.height - radius ) gy = false;
      if( gx ){
        x++;
      } else {
        x--;
        if( x <= radius ) gx = true;
      }
      if( gy ){
        y++;
      } else {
        y--;
        if( y <= radius ) gy = true;
      }
      ctx.beginPath();
      ctx.arc(x, y, radius, 0, Math.PI*2, false);
      ctx.closePath();
      ctx.fill();
      setTimeout(roop, 1);
    })();

  };

  window.onload = function(){
    init();
  };

})();

</script>

</body>
</html>


完全に今更!?ですがcanvasすごい楽しいので、ハマりそうです。

anguler jsでapi call

下記のような感じで実装しました。

;(function() {

  var apiAppModule = angular.module('apiApp', []);

  apiAppModule.value("urls", 
    {
      item: "http://workspace.com/anguler/hoge.json"
    }
  );

  apiAppModule.factory("APICall", function($http, urls){
    var func = function(url, method){
      return $http({
        url: url,
        method: method,
      })
      .success(function(res){
        return res;
      })
      .error(function(error){
        console.log(error);
        return false;
      });
    };
    var get = {
      item: func(urls.item, "GET")
    };
    return {
      item: get.item
    };
  });

  apiAppModule.controller("itemController", function($scope, APICall){

    APICall.item.then(function(response){
      // $scope.items = response.data.items みたいな
    });

  });

})();

jQueryだとこんな風に書きますよね。。?

;(function() {
   $.ajax({
      type : "GET",
      url : "http://workspace.com/anguler/hoge.json",
      dataType : "json",
      complete: function(res) {
      },
      success: function(res) {
        // 最終的にappendする
      },
      error: function(error) {
        console.log(error)
      }
    });
    return false;
  });
})();

印象としては、apiをcallする自体はそんなに変わりないないけれど、
受け取ったデータをviewに渡すのがangulerすばらしいな〜と思いました。

入社当時のこと

一昨年の9月くらいに専門学校時代の知り合いに声をかけて、今の会社に入ることになったのだけど
それまでは都内の某IT企業(ここではA社)でマークアップエンジニアとして働いていた。

マークアップエンジニアといえば、基本的にHTML、CSSコーディングが中心で、たまにJSとかも書かせてもらったりしてた、だけど僕はそれが4ヶ月くらいで飽きてしまった。
まだこの頃はPHPとかもさほど触っていないのに、もっとプログラミングっぽいことがしたいなあ。と思っていた僕は(今思えば馬鹿)休みの日や早上がりできるときにドットインストールなどで、PHPだったりRubyの勉強を始めるようになった。

ドットインストール - 3分動画でマスターする初心者向けプログラミング学習サイト

1年は続けようと思っていたけど、入社してから7ヶ月くらいの時に今の会社の人と会っておもしろそうだったので、「エンジニア募集してますか?」と聞いたらまだ募集しているとのことで、社長がご飯を食べようと言ってくれ一度オフィスに行ってみることになった。


で、その翌週くらいに行ってみたら社長と他の社員数名と共に松屋に牛丼を買いに行くことになった
ご飯って牛丼のことか。と思っていたら「一緒に働く?」と社長に言われたので、働きます。と言ってめでたく入社が決まった。
まだA社で働いてるということもあったので、アルバイトで週2〜3のスタートになった。
ちなみにオフィスに着いてからすぐ牛丼を買いにいったので、入社が決まるまで10分くらいで社長曰く未だにその入社最速記録は破られていないらしい。


そしてA社では良いタイミングで個人面談があったので、他の会社で働きたいので出社を週2回くらいにしてほしいと伝えたところ、
ちょうど僕メインでやってる案件もなかったので、来週からいいよと言ってくれた。


翌週、初めて出社してみたらほとんどの人が昼くらいから来るので、ベンチャーぽいなぁと思ったのを覚えてる。
ちょうどその時、Cっぽい謎の言語で作られたサイトのスマホ化の仕事を任されて、そこでまたHTMLとかを書くことになったんだけど、自分がなにできますとか明確に言えなかったから仕方ないかと思ったりもした。

そんな感じのことを1ヶ月くらいしたら、だんだんA社に行くのが面倒になってきたので部署の上司に相談したら、来週やめられることになって急すぎて驚いた。

それを後日、今の会社の社長に言いつつ週5で来ていいですか?と聞いたら「いいよ」と言ってくれ、社員になることになった。

最初にオフィスに行ってから2ヶ月もしないうちに退職から入社まで決まって、当時は追い風かとか思ってた気がする。(今思えば追い風ではないと思う)

そして、僕は晴れて正社員のエンジニアとして働くこととなった。

最近読んだ本

去年の12月にiPhone5からAndroid(nexus6)に変えてから、もっぱらkindle本ばかり買ってしまっている。
画面が大きいのはとても良い。

けど、個人的には紙の方が好きです(買いに行くのが面倒以外は)


というわけで、最近読んだ本を紹介します


クズの本懐(1) (ビッグガンガンコミックス)

クズの本懐(1) (ビッグガンガンコミックス)

表紙に惹かれて読んでみた本です。

主人公の高校生の男女が、互いに叶わない恋をしていてその寂しさ?を埋めるために偽装で付き合うという話です、
巻を重ねるごとに特に女の子の方が堕ちていく感じが、個人的に好きです


セリフがぐっとくるものがあって、特にいいなと思ったのは、男の子の方が中学生の時に女の先輩と関係を持って遊びで先輩が卒業するまで関係を持ち続ける、みたいな過去があった的な場面で「おれって思春期の玩具だね」というセリフが個人的にぐっときました(確か2巻だったと思います)



特に転職したいと思っていないけど、はあちゅうさんが好きなので読みました。

はあちゅうさんの言葉の使い回しがとにかく好きなので、新しく出る「半径5メートルの野望」も読みたいです
巻末には霜田明寛さんとの対談も載っていています。

「ゲスアワー」(下記YouTube参照)を見てからは霜田さんのファンにもなっていたので、とても俺得な内容でした。


【ゲス#01】はあちゅうとしもやんのゲスアワー(第1回) - YouTube



たのしいSwiftプログラミング―[iOS 8&Xcode 6対応]

たのしいSwiftプログラミング―[iOS 8&Xcode 6対応]

swiftを勉強したいと思い、書店でぱらぱら読んでいて「XMLJSONをtableに表示」「SNS連携」が面白そうだなと思って購入した本です。

iOSプログラミングをとりあえずやってみたかったので最適な本でした。







画面が大きいとついついkindleで買ってしまうけど、漫画とか続きがあるものだと1巻をkindleで持っていて、2巻が書籍みたいなことになってしまっているのでどちらかに統一したい。

2015年の抱負

2014年をさくっと振り返って、2015年の抱負を箇条書きしたいと思います。

2014年

健康について

やたら「厄年」という言葉を意識してしまい、

6回くらい風邪をひきました。(上京して初めて風邪で病院に行きました)








仕事について

2013年の10月からwebエンジニアとして働かせていただいていまして、

「エンジニア」として一年を過ごすことが出来たというのと、エンジニア一年目ということで様々な実装が初めてだったので、
試行錯誤できたかなあといった感じでした。








生活について

基本的に自炊をしなかったのが、年末には何かしら家で作るようになりました(餌レベルですが)

来年は2月くらいに引っ越しも控えてるので家で作ることが多くなるのかなあと思っています。








来年の抱負

・エンジニアとして自信を持てる強みを作る

言葉の通りですが、どんな強みになっていくのか具体的にはまだわかりません。








・言語仕様などを考えた設計、実装を心がける

1年エンジニアとして働いてみて、実装に対する疑問はだいぶ減りました。

ただ、どうしてもコアな部分(言語仕様に沿っているか、速度は?、イケてるコードか否か)には自信が持てないでいました。

しかし、そうやって悩んでいても納期は待ってくれないので、完成させることを第一に考えていましたが、常にモヤモヤしてる感じでした。

そういったモヤモヤを少しでも無くせればと思っています。








・勉強会など積極的に参加する(外にでる)

単純にあまり休日など、他のエンジニアの方たちと関わることが少なかったので、2015年は積極的にいきたいです。
エンジニアじゃない方とも交流をしていきたいです。








・健康に気を使った食事をとる

早くも生まれてから来年で25年になるというのと、先日同い年の幼馴染が痛風になったと聞いて怖くなったので、
少しずつでも健康に気を使った食事をしていこうと思いました。








・定期的にブログを書く

僕にとっては永遠の課題ですが、頑張ります。









今のところ、この5つを来年の抱負にしていこうと思っております、

来年も良いお年を!

webからiPhoneで撮影した画像をアップロードしたら回転した

表題の通りスマホサイトなどで、
iPhoneで撮影した画像をアップロードしたら回転してアップされてしまったのでその時の対処を書きます。




とりあえずGoogle先生に聞いてみたところ

iPhoneiPadではタテにもって写真をとった場合でも、内部的に横長のJPGでExifのOrientationタグに回転角度を埋め込んで保存しているという、「なぜ、そんなことをするの?」というツッコミを入れたくなるようなことをiPhone様がしている(して頂いている)と知りました。



Exifってなんだよ。。。?



わからないことはGoogle先生に聞けと学校で教わったので(本当です)またGoogle先生に聞きます


Exchangeable image file format - Wikipedia



Google先生Wikipediaさんによると、どうも画像のmeta情報ということが分かりました。
どうやらiPhoneで撮影した写真のmeta情報に「水平・垂直方向の単位あたり」という情報もあって、これが「Orientation」なんだな〜となんとなく認識しときます。


次にOrientationがどんな値なのかググると、すぐに答えにたどり着きました。

下記のとおり、1〜8まであるようです。

1     回転無し
2     左右反転
3     180°回転
4     上下反転
5     時計回りに90°回転した後、左右反転
6     時計回りに90°回転
7     反時計回りに90°回転した後、左右反転
8     反時計回りに90°回転




ここまでわかったので、iPhoneで撮影した画像のExif情報を取得しようと試みて、またググると、

exif_read_dataという今の僕にぴったりすぎる関数を発見。

PHP: exif_read_data - Manual



さっそく実装に移りたいと思います。



僕の働いている会社ではFuelPHPをよく使わせていただいていて、今回もFuelPHPで実装してるのでFuelPHPのclassありきで記述していきます。(アップロード部分は省きます)

<?php

  public static function upload_icon() {
    // Upload classでアップロード処理
    foreach(Upload::get_files() as $saved_file) {
      self::create_thumb($saved_file);
    }
  }

  public static function create_thumb($saved_file)
  {
    $thumb_size = array(
      "width"  => "150",
      "height" => "150"
    );

    $image = Image::load("assets/img/icon/" . $saved_file["saved_as"]);
    $filename = DOCROOT."assets/img/icon/" . $saved_file["saved_as"];

    if( $image->extension() == "jpg" && self::is_upload_iphone($filename) ){
      // iPhoneで撮影した画像なら時計回りに90度回転する
      $image->rotate(90);
    }
    return $image->crop_resize($thumb_size["width"], $thumb_size["height"])
                          ->save("assets/img/icon/resize_" . $save_file["saved_as"]);
  }

  public static function is_upload_iphone($filename) {
    $exif = exif_read_data( $filename );
    if( !empty($exif["Orientation"]) && $exif["Orientation"] == 6 ){
      return true;
    } else {
      return false;
    }
  }


アップロード済のアイコン画像をFuelのImageクラスで取得して、

サムネイルを作る際にiPhoneで撮影した画像であれば時計回りに90度回転するといった感じですが、
iPhoneで撮影した画像のOrientationは6のようだったので6限定でrotateをかけていますが、

例外が出てきた時の処理などしていないので、よろしくない部分が多々あるとは思いますが(メソッド名にupload_iconとか嫌ですね)とりあえず一旦こんな感じで対応しました。



追記として、稼働しているサーバーにも自分のPCにもImageMagickが入っていなかったのでこの方法をとりました。
ImageMagickが入っている環境であれば、他の方法もあるようです。(最初にググったらそっちばかり出てきました)