Angularでいい感じにfaviconを操作するお話。

#Angularでいい感じにfaviconを操作するお話。

完成図↓
![Untitled 4.png](https://qiita-image-store.s3.amazonaws.com/0/58613/852410fc-f7ea-cec3-ea49-c17f01960041.png)

faviconとは。
>favicon（ファビコン）は、ウェブサイトのシンボルマーク・イメージとして、ウェブサイト運営者がウェブサイトやウェブページに配置するアイコンの俗称である。favorite icon（フェイバリット・アイコン：お気に入りアイコン）という英語の語句を縮約したものである。(wikipediaより)

faviconってめんどくさいねん。
今の時代apple-touch-iconとかなんとかいっぱいあるし。。。
svgを使えるようになったらええんやけど、今んところサポートしてるんはFirefoxだけ。 → http://caniuse.com/#feat=link-icon-svg

##余談
favicon一括生成サイトというものがあるそうで → http://realfavicongenerator.net/
こいつはfaviconはもちろん、iPhoneやandroid、windows8とかとかいい感じに一括生成してくれる超便利サイト。

![Untitled.png](https://qiita-image-store.s3.amazonaws.com/0/58613/d63fd1b8-941c-1e0d-32e2-00b9378fbd0a.png "Untitled.png")

##序論
余談はさておき、今回はangularでfaviconをいい感じに操作するお話をします。
その名も ***favico.js*** → http://lab.ejci.net/favico.js/
faviconにバッチをつけたり、アニメーションさせたり、入れ替えたり、音量バッチとかとか。
webcamでインカメの動画をfaviconで再生したり(←何に使うねん)
↓↓↓
![Untitled.png](https://qiita-image-store.s3.amazonaws.com/0/58613/b2536043-37af-0dbd-07f7-a66da944359d.png "Untitled.png")

Works on Chrome, Firefox, Opera and IE11+ らしい。
僕はチャットツールを作ろうとしてて、未読の数を出すのにいいのないかなって思ってたら、favicon.jsを耳に挟んだので触ってみたことを書いていく。

##導入
メッセージの未読を検出する方法については以下に書きましたので、これを読んでください。
http://qiita.com/shinsukeimai/items/dd1e96456b7b51e32cce
ここでのスクリブトを元に書いていきます。

###初期状態

```index.html
<!DOCTYPE html>
<head>
    <link rel="stylesheet" href="app.css">
</head>
<body>
<div ng-app="myApp">
    <div ng-controller="MainCtrl as main">
        <ul ng-repeat="message in main.messages">
            <li msg content=message ng-class="{message: message.read }">{{message.text}}</li>
        </ul>
    </div>
</div>
<script src="./angular.min.js"></script>
<script src="./favico.js"></script>
<script src="app.js"></script>
</body>
```

```app.js
"use strict";

angular.module("myApp", []);

angular.module("myApp").directive("msg", ["$window", function($window){
  return {
    restrict: "A",
    scope: {
      content: "="
    },
    link: function(scope, element){
      angular.element($window).bind('scroll', function () {
        var elementY = element[0].offsetTop;
        var pageTop = this.pageYOffset;
        var pageBottom = this.pageYOffset + this.innerHeight - 50;
        if(elementY > pageTop && elementY < pageBottom){
          scope.content.read = true;
          scope.$apply();
        }
      });
    }
  }
}]);

angular.module("myApp").controller("MainCtrl", function(){
  this.messages = [];
  for(var i = 0; i < 100; i++){
    this.messages[i] = {
      text: "message" + i,
      read: false
    }
  }
});

```

```app.css
.message{
    color: red;
}
```

ここからスタートしていきます。

##環境
- faviconを用意します。
- angularを用意します。
- favico.jsを用意します。(githubから落として下さい。)

##実装
index.htmlを書いていきます。
linkにfaviconを設定します。

```index.html
<!DOCTYPE html>
<head>
    <meta charset="utf-8">
    <!-- ここ！！！-->
    <link rel="shortcut icon" href="favicon32.ico">
    <link rel="stylesheet" href="app.css">
</head>
<body>
<div ng-app="myApp">
    <div ng-controller="MainCtrl">
        <ul ng-repeat="message in messages">
            <li msg content=message ng-class="{message: message.read }">{{message.text}}</li>
        </ul>
    </div>
</div>
<script src="./angular.min.js"></script>
<script src="./favico.js"></script>
<script src="app.js"></script>
</body>
```

favico.js用にService(factory)を書いていきます。
詳しい動きを設定したい時はhttp://lab.ejci.net/favico.js/

```app.js
angular.module("myApp").factory("faviconService", function(){
  var favicon = new Favico({
    //animationを切る
    animation: "none"
  });
  var badge = function(num){
    favicon.badge(num);
  };

  return {
    badge: badge
  };
});
```

controllerを書き足します。
スクロールした時にfaviconのbadgeの値を変えていきます。

```app.js

angular.module("myApp").controller("MainCtrl", ["$scope", "$window", "$timeout", "faviconService", function($scope, $window, $timeout, faviconService){
  //初期値設定
  var num, scrollTimer;
  scrollTimer = false;
  $scope.messages = [];

  for(var i = 0; i < 100; i++){
    $scope.messages[i] = {
      text: "message" + i,
      read: false
    }
  }
  num = $scope.messages.length;
  faviconService.badge(num);
  //スクロール時の動き
  angular.element($window).bind('scroll', function () {
    //スクロール中の時の動きで100msの間を空けます。
    if(scrollTimer){
      $timeout.cancel(scrollTimer);
    }
    scrollTimer = $timeout(function(){
      var newNum = 0;
      //メッセージの既読を確認します。
      $scope.messages.forEach(function(message){
        if(!message.read){newNum++; }
      });
      if(num !== newNum){
        faviconService.badge(newNum);
        num = newNum;
      }
    },100);
  });
}]);
```

まとめますと。

```app.js
"use strict";

angular.module("myApp", []);

angular.module("myApp").directive("msg", ["$window", function($window){
  return {
    restrict: "A",
    scope: {
      content: "="
    },
    link: function(scope, element){
      angular.element($window).bind('scroll', function () {
        var elementY = element[0].offsetTop;
        var pageTop = this.pageYOffset;
        var pageBottom = this.pageYOffset + this.innerHeight - 30;
        if(elementY > pageTop && elementY < pageBottom){
          scope.content.read = true;
          scope.$apply();
        }
      });
    }
  }
}]);

angular.module("myApp").controller("MainCtrl", ["$scope", "$window", "$timeout", "faviconService", function($scope, $window, $timeout, faviconService){
  //初期値設定
  var num, scrollTimer;
  scrollTimer = false;
  $scope.messages = [];

  for(var i = 0; i < 100; i++){
    $scope.messages[i] = {
      text: "message" + i,
      read: false
    }
  }
  num = $scope.messages.length;
  faviconService.badge(num);
  //スクロール時の動き
  angular.element($window).bind('scroll', function () {
    //スクロール中の時の動きで100msの間を空けます。
    if(scrollTimer){
      $timeout.cancel(scrollTimer);
    }
    scrollTimer = $timeout(function(){
      var newNum = 0;
      $scope.messages.forEach(function(message){
        if(!message.read){newNum++; }
      });
      if(num !== newNum){
        faviconService.badge(newNum);
        num = newNum;
      }
    },100);
  });
}]);

angular.module("myApp").factory("faviconService", function(){
  var favicon = new Favico({
    animation: "none"
  });
  var badge = function(num){
    favicon.badge(num);
  };

  return {
    badge: badge
  };
});
```

こんな感じです。

##結果

###初期状態

![Untitled.png](https://qiita-image-store.s3.amazonaws.com/0/58613/08c380ae-3762-f5c2-2a25-d92348b8ccd6.png "Untitled.png")

###スクロールすると
![Untitled 2.png](https://qiita-image-store.s3.amazonaws.com/0/58613/2b522bbf-49a0-45be-93a3-f87c685a9c29.png "Untitled 2.png")

###faviconは
こういう感じです。
![Untitled 3.png](https://qiita-image-store.s3.amazonaws.com/0/58613/775e1851-ad5b-4d8f-f29b-69da1b960a2d.png "Untitled 3.png")

##感想
そんなにangularって感じでもなかったかな。
同じことしたい人には参考になるかも。
これ、ページを開いておくと、ブックマークバーにあるアイコンにもこのbadgeが現れて、増減を出してくれる。
おもろ
お試しアレ。
![Untitled 4.png](https://qiita-image-store.s3.amazonaws.com/0/58613/852410fc-f7ea-cec3-ea49-c17f01960041.png)