2015年4月5日日曜日

[Ratchet] sliders.jsをみる

display: inline-block;のスクロール制御で実装されている
/* ========================================================================
 * Ratchet: sliders.js v2.0.2
 * http://goratchet.com/components#sliders
 * ========================================================================
   Adapted from Brad Birdsall's swipe
 * Copyright 2014 Connor Sears
 * Licensed under MIT (https://github.com/twbs/ratchet/blob/master/LICENSE)
 * ======================================================================== */

!(function () {
  'use strict';

  var pageX;
  var pageY;
  var slider;
  var deltaX;
  var deltaY;
  var offsetX;
  var lastSlide;
  var startTime;
  var resistance;
  var sliderWidth;
  var slideNumber;
  var isScrolling;
  var scrollableArea;

  var getSlider = function (target) {
    var i;
//.sliderのしたslide-groupにslideたちがありそれが対象する
    var sliders = document.querySelectorAll('.slider > .slide-group');

    for (; target && target !== document; target = target.parentNode) {
      for (i = sliders.length; i--;) {
        if (sliders[i] === target) {
          return target;
        }
      }
    }
  };

  var getScroll = function () {
    if ('webkitTransform' in slider.style) {
      var translate3d = slider.style.webkitTransform.match(/translate3d\(([^,]*)/);
      var ret = translate3d ? translate3d[1] : 0;
      return parseInt(ret, 10);
    }
  };

  var setSlideNumber = function (offset) {
    var round = offset ? (deltaX < 0 ? 'ceil' : 'floor') : 'round';
    slideNumber = Math[round](getScroll() / (scrollableArea / slider.children.length));
    slideNumber += offset;
    slideNumber = Math.min(slideNumber, 0);
    slideNumber = Math.max(-(slider.children.length - 1), slideNumber);
  };

//初期位置の値のセット
  var onTouchStart = function (e) {
    slider = getSlider(e.target);

    if (!slider) {
      return;
    }

    var firstItem  = slider.querySelector('.slide');

    scrollableArea = firstItem.offsetWidth * slider.children.length;
    isScrolling    = undefined;
    sliderWidth    = slider.offsetWidth;
    resistance     = 1;
    lastSlide      = -(slider.children.length - 1);
    startTime      = +new Date();
    pageX          = e.touches[0].pageX;
    pageY          = e.touches[0].pageY;
    deltaX         = 0;
    deltaY         = 0;

    setSlideNumber(0);

    slider.style['-webkit-transition-duration'] = 0;
  };

  var onTouchMove = function (e) {
    if (e.touches.length > 1 || !slider) {
      return; // Exit if a pinch || no slider
    }

    deltaX = e.touches[0].pageX - pageX;
    deltaY = e.touches[0].pageY - pageY;
    pageX  = e.touches[0].pageX;
    pageY  = e.touches[0].pageY;

    if (typeof isScrolling === 'undefined') {
      isScrolling = Math.abs(deltaY) > Math.abs(deltaX);
    }

    if (isScrolling) {
      return;
    }

    offsetX = (deltaX / resistance) + getScroll();

    e.preventDefault();

    resistance = slideNumber === 0         && deltaX > 0 ? (pageX / sliderWidth) + 1.25 :
                 slideNumber === lastSlide && deltaX < 0 ? (Math.abs(pageX) / sliderWidth) + 1.25 : 1;

    slider.style.webkitTransform = 'translate3d(' + offsetX + 'px,0,0)';
  };


//Slideを位置に合わせて移動
  var onTouchEnd = function (e) {
    if (!slider || isScrolling) {
      return;
    }

    setSlideNumber(
      (+new Date()) - startTime < 1000 && Math.abs(deltaX) > 15 ? (deltaX < 0 ? -1 : 1) : 0
    );

    offsetX = slideNumber * sliderWidth;

//cssでアニメーション
    slider.style['-webkit-transition-duration'] = '.2s';
    slider.style.webkitTransform = 'translate3d(' + offsetX + 'px,0,0)';

//Slideイベントを発生
    e = new CustomEvent('slide', {
      detail: { slideNumber: Math.abs(slideNumber) },
      bubbles: true,
      cancelable: true
    });

    slider.parentNode.dispatchEvent(e);
  };


//Eventの紐付け
  window.addEventListener('touchstart', onTouchStart);
  window.addEventListener('touchmove', onTouchMove);
  window.addEventListener('touchend', onTouchEnd);

}());

2015年4月4日土曜日

[Ratchet] segmented-controllersを見る

/* ========================================================================
 * Ratchet: segmented-controllers.js v2.0.2
 * http://goratchet.com/components#segmentedControls
 * ========================================================================
 * Copyright 2014 Connor Sears
 * Licensed under MIT (https://github.com/twbs/ratchet/blob/master/LICENSE)
 * ======================================================================== */

!(function () {
  'use strict';

  var getTarget = function (target) {
    var i;

//modal.js,popover.jsとちがい直接的に指定することで限定している。
    var segmentedControls = document.querySelectorAll('.segmented-control .control-item');

    for (; target && target !== document; target = target.parentNode) {
      for (i = segmentedControls.length; i--;) {
        if (segmentedControls[i] === target) {
          return target;
        }
      }
    }
  };

//touchendEventに紐付け
  window.addEventListener('touchend', function (e) {
    var activeTab;
    var activeBodies;
    var targetBody;
    var targetTab     = getTarget(e.target);
    var className     = 'active';
    var classSelector = '.' + className;

    if (!targetTab) {
      return;
    }

//activeなものを検索
    activeTab = targetTab.parentNode.querySelector(classSelector);

    if (activeTab) {
//一旦削除
//一つしかactiveがない想定(変なhtmlはだめ)
      activeTab.classList.remove(className);
    }

//自分をactiveに
    targetTab.classList.add(className);

    if (!targetTab.hash) {
      return;
    }

//href でターゲットを指定
    targetBody = document.querySelector(targetTab.hash);

    if (!targetBody) {
      return;
    }

// 大きなくくりの中に、各ページが用意されている必要がある
    activeBodies = targetBody.parentNode.querySelectorAll(classSelector);

    for (var i = 0; i < activeBodies.length; i++) {
      activeBodies[i].classList.remove(className);
    }
//activeを一つへ
    targetBody.classList.add(className);
  });

  window.addEventListener('click', function (e) { if (getTarget(e.target)) {e.preventDefault();} });
}());

[Ratchet] popoverをみる

/* ========================================================================
 * Ratchet: popovers.js v2.0.2
 * http://goratchet.com/components#popovers
 * ========================================================================
 * Copyright 2014 Connor Sears
 * Licensed under MIT (https://github.com/twbs/ratchet/blob/master/LICENSE)
 * ======================================================================== */

!(function () {
  'use strict'; //厳密モード

  var popover;

/*
Modalと同じ
*/
  var findPopovers = function (target) {
    var i;
    var popovers = document.querySelectorAll('a');

    for (; target && target !== document; target = target.parentNode) {
      for (i = popovers.length; i--;) {
        if (popovers[i] === target) {
          return target;
        }
      }
    }
  };

/*
閉じる
*/
  var onPopoverHidden = function () {
    popover.style.display = 'none';
    popover.removeEventListener('webkitTransitionEnd', onPopoverHidden);
  };

/*
後ろに薄い背景のこと
*/
  var backdrop = (function () {
    var element = document.createElement('div');
    element.classList.add('backdrop');

/*
backdropをタッチでクローズ処理
*/
    element.addEventListener('touchend', function () {
//element.addEventListener('touchend', function (e) {
      popover.addEventListener('webkitTransitionEnd', onPopoverHidden);
      popover.classList.remove('visible');
      popover.parentNode.removeChild(backdrop);
//e.preventDefault(); 
    });

    return element;
  }());

/*
Modalと基本ロジック同じだが、例外処理(try/catch)をしている
*/
  var getPopover = function (e) {
    var anchor = findPopovers(e.target);

    if (!anchor || !anchor.hash || (anchor.hash.indexOf('/') > 0)) {
      return;
    }

    try {
      popover = document.querySelector(anchor.hash);
    }
    catch (error) {
      popover = null;
    }

    if (popover === null) {
      return;
    }

    if (!popover || !popover.classList.contains('popover')) {
      return;
    }
    return popover;
  };

/*
PopOverを表示するよう登録
*/
  var showHidePopover = function (e) {
    var popover = getPopover(e);

    if (!popover) {
      return;
    }

    popover.style.display = 'block';
    popover.offsetHeight;
    popover.classList.add('visible');

    popover.parentNode.appendChild(backdrop);
  };

//touchendイベントにbind
  window.addEventListener('touchend', showHidePopover);

}());

2015年3月31日火曜日

[Ratchet] modalをみる

Open modal


href="#myModalexample" と div id="myModalexample" がポイント
/* ========================================================================
 * Ratchet: modals.js v2.0.2
 * http://goratchet.com/components#modals
 * ========================================================================
 * Copyright 2014 Connor Sears
 * Licensed under MIT (https://github.com/twbs/ratchet/blob/master/LICENSE)
 * ======================================================================== */

!(function () {
  'use strict';

/**イベント発生したものが、処理の対象になるか検索する。**/
  var findModals = function (target) {
    var i;
//selecterでelementを検索し、取得
    var modals = document.querySelectorAll('a');

/**
イベント発生したところから、documentに向けて、親に向かって上がっていき、
aタグのリストの中で一致するものを探します。
**/
    for (; target && target !== document; target = target.parentNode) {
      for (i = modals.length; i--;) {
        if (modals[i] === target) {
          return target;
        }
      }
    }
  };

/**表示するモーダルを特定**/
  var getModal = function (event) {
    var modalToggle = findModals(event.target);

    if (modalToggle && modalToggle.hash) {
  //modalToggle.hashがそのままモーダルのIDとして指定される
      return document.querySelector(modalToggle.hash);
    }
  };


/** touchend イベントにListener登録**/
  window.addEventListener('touchend', function (event) {
    var modal = getModal(event);
    if (modal) {
/**
getModalの時点でcontains('modal')とかの判定もしてよい気もするが、設計上の意味があるかしれないので、留意しておく。
**/
      if (modal && modal.classList.contains('modal')) {
/**
classList.toggleでcssListに'active'がなければ追加、あったら削除する
**/
        modal.classList.toggle('active');
      }
   //通常事項されるアクションをキャンセルする
  //この場合ページ遷移
      event.preventDefault(); // prevents rewriting url (apps can still use hash values in url)
    }
  });
}());

どうやらactiveの追加、削除だけでmodalの動作を実装している
class="modal"
class="modal active"

/*!
 * =====================================================
 * Ratchet v2.0.2 (http://goratchet.com)
 * Copyright 2014 Connor Sears
 * Licensed under MIT (https://github.com/twbs/ratchet/blob/master/LICENSE)
 *
 * v2.0.2 designed by @connors.
 * =====================================================
 */

/*! normalize.css v3.0.1 | MIT License | git.io/normalize */
.modal {
  position: fixed;
  top: 0;
  z-index: 11;
  width: 100%;
  min-height: 100%;
  overflow: hidden;
  background-color: #fff;
  opacity: 0;//←

/* //カンマで区切って2つ指定している(-transition) */
  -webkit-transition: -webkit-transform .25s,       opacity 1ms .25s;
     -moz-transition:    -moz-transform .25s, opacity 1ms .25s;
          transition:         transform .25s, opacity 1ms .25s;

  -webkit-transform: translate3d(0, 100%, 0);
      -ms-transform: translate3d(0, 100%, 0);
          transform: translate3d(0, 100%, 0);
}
.modal.active {
  height: 100%;
  opacity: 1;  //←
  -webkit-transition:  -webkit-transform .25s;
     -moz-transition:    -moz-transform .25s;
          transition:         transform .25s;

  -webkit-transform: translate3d(0, 0, 0);
      -ms-transform: translate3d(0, 0, 0);
          transform: translate3d(0, 0, 0);
}

[Ratchet] Ratchetをみると決めた

https://github.com/withstandist/hagoita は、webUIだけでなく、Unityとかでもしかしたら動くかも(そしてもしかして主力?) と思いながらも、webUIからはじめてみます。
実際使ってみながら修正して、使えないでもなんらかの判断ができれてばという感じです。

見た目がよいとテンションが上がるので、framework的なものをさがしました。しかし、だいたいこれで、いつも疲れて、やっぱりnative最高ってなるのです。


今回、調べて使おうかとおもったもの
Onsen-UI
famework7
ratchet(http://goratchet.com/)

ratchetはそんなに中身がゴテゴテしないというコンセプトです。

最初、macのsafariで動かしてみたら、動かなくて困りましたが、単純にタッチイベントをブラウザが送らなかったからでした。実は、ちゃんと英語のreadmeに書いてあります。
chromeのエミュレータモード?で動作をみてます。




2015年3月28日土曜日

gitHubでなにか公開したかったから、UIWebViewとiOSの連携を考えなおしてみた

iOSとWebViewとの連携の仕方は
- shouldstartloadwithrequestでフックして、カスタムスキーマを動かす
- UIWebViewでjavascriptdでオブジェクトを制御して連携する
等ぐらいは知っていた。
でもこのやり方がどうしても馴染めなかった。

きっと自分はwebサーバと一緒の時間が長かったというのもあるのだけれども、
普通にajaxをなげて、サーバがデータを返すようにiOSが情報を返してくれるものが欲しかった。

といったものを
3年前ぐらいに考えて放っておいたものを
githubでなにか公開したいという理由で作ってみました。


動作フローは以下のとおりです
1, ajax等でex) http://xxxx.xxxx.xx:7777/test/ssss.jsonでアクセス
  htmlは普通のサーバとのやりとりのように書くことができます。
2, NSURLProtocolが、登録しているURIでロジックオブジェクトへハンドリング
3, ロジックオブジェクトが処理をし返却するデータを準備
  iOS側のロジックもhtmlのDOMとか気にしなくてよくなります。
4, まるで通信した結果のように、JSONとしてデータを受け取る

もしかしたら、
一回、iOS側のロジックをとおして、サーバに通信することで、セキュリティ向上できるかもしれません。

こんなことやるより、直接やる方が効率がよさそうですが、
馴染んでいる方法を選択するのも一つという

プロトタイプとして
https://github.com/withstandist/hagoita
においてあります。

できれば、このやり方で一回アプリを出してみたいと思います。








2015年1月3日土曜日

いろいろと手をだしていきたい

明日に進んでいくために現状を整理してみました。

去年の末にはLINEスタンプもリリースできました。

2014.12.27 release
 モヒカン猫 - LINE クリエイターズスタンプ
 https://store.line.me/stickershop/product/1054849/ja

■ 現在手をだしているものリスト
- youtube (動画配信)
- pixiv
- twitter
- facebook
- blog
- アプリ開発(5つ公開中、iOSハンドル1つ)
- LINE クリエイターズスタンプ(8つ申請中)
- swift言語
- iPhonePLUS (http://iphone.ascii.jp)(開発者投稿)
- 切り絵(専用はさみ購入)

いろいろと手を出していますが、やってるだけで、質と頻度が低いですね。
でも、やらないより、やったほうがわかることが多い。
ちゃんとした人はやらなくても検証ができるらしいが、私にはできません。
それぞれの質を向上させながらも、今年もいろいろと手をだしていきたい。

去年末、悩んだFireFoxOSは、いまのところやめてます。
■ 手を出すかもしれないもの
- enchantMoom
- FireFoxOS

以上、今年も宜しくお願いします。