bata's log

フロントエンド系のTipsとかメモ

アニメーション用のタイムライン管理

Javascriptで何場面もあるようアニメーションを実装する場合に、シーンごとにアクションと発火点をタイムラインのように管理できたらよいのかなと思って書いてみた。

(function(window,namespace,$){

    window[namespace] = {

        play: function(){
            var len = this.frame.length;
            for(var i=0; i<len; i++){
                setTimeout(this.frame[i].scene, this.frame[i].timeline);
            }
        },

        frame: [
            {
                scene: function(){
                    console.log(1)
                },
                timeline: 1200
            },
            {
                scene: function(){
                    console.log(2)
                },
                timeline: 2000
            },
            {
                scene: function(){
                    console.log(3)
                },
                timeline: 2200
            },
            {
                scene: scene04,
                timeline: 3500
            }
        ]
    }

    function scene04(){
        console.log(4)
        console.log(this)
        console.log($)
    }

})(this,'FlameAnime',jQuery);


FlameAnime.play();

frame:[] の部分でシーン毎のアニメーションと発火までの時間を設定します。
シーンにアニメが多い場合は外側に関数として切り出してもよいかも。

フェード付きの画像ロールオーバーを作ってみた

画像のロールオーバーでフェードエフェクトがついたものを書いてみた。
ロールオーバー用のクローン画像を生成して元画像の後ろに配置して、元画像をフェードすることで効果を出します。

汎用性が出るように画像と親要素に直接CSSが付加されるようにしています。

(function(window,namespace,$){

    window[namespace] = {

        init: function(el,suffix,time){
            var el = el || '.imgOver';
            var suffix = suffix || '_o';
            if(time === undefined){
                var time = 200;
            };

            this.setImg(el,suffix);
            this.event(el,suffix,time);
        },

        event: function(el,suffix,time){
            var that = this;
            $(el).on({
                mouseover: function(){
                    var self = $(this);
                    self.fadeTo(time,0);
                },
                mouseout: function(){
                    var self = $(this);
                    self.fadeTo(time,1);
                }
            });
        },

        setImg: function(self,suffix){
            $(self).each(function(){
                var $baseImg = $(this);
                var imgWidth = $baseImg.width();
                var imgheight = $baseImg.height();
                var $parentEle = $baseImg.parent();
                var src = $baseImg.attr('src');
                var overSrc = src.replace(/^(.+)(\.[a-z]+)$/, '$1' + suffix + '$2');
                var overImg = $baseImg.clone().attr('src', overSrc).css({
                    position: 'absolute',
                    left: 0,
                    top: 0,
                    zIndex:10
                }).addClass('on');

                $baseImg.css({
                    position: 'absolute',
                    left: 0,
                    top: 0,
                    zIndex:20
                });
                $parentEle.css({
                    position: 'relative',
                    width: imgWidth,
                    height: imgheight
                }).append( overImg );
            });
        }
    };

})(this,'imgOverWithFade',jQuery);

実行

$(function(){
    imgOverWithFade.init('.sample', '_o', 200);
});

引数に'ターゲット','ロールオーバー後の画像の接尾語','フェードのスピード'を設定します。
デフォルト値は'.imgOver','_o','200'

注意点

画像にposition: absolute;をつけて重ねるので、親要素がないと画像がおかしなところに表示されます。

<li><img src="hogehoge.png" width="240" height="110" alt="" class="sample" /></li>

とか

<div><img src="hogehoge.png" width="240" height="110" alt="" class="sample" /></div>

のようにimgを親要素で囲って下さい。

オブジェクト指向の書き方

オブジェクト指向の書き方を練習するために前に作ったやつ。

HTML

<div id="wrap"></div>

JavaScript

(function($){

    var n = 99;
    var wrap = $('#wrap');


    var Box = function(i,selector, x, time){
        this.i = i;
        this.x = i*10;
        this.selector = selector;
        this.time = time;
        this.init();
    };

    Box.prototype = {

        init: function(){
            this.createHtml();
            this.setAction();
        },

        createHtml: function(){
            wrap.append('<div class=\"obj obj' + this.i + '\" style=\"left:' + this.x + 'px;\"></div>');
        },

        setAction: function(){
            var selector = $(this.selector);
            selector.css({
                background: '#0000ff',
                position: 'absolute',
                width: 10,
                height: 10,
                top: 0
            }).delay(this.time).animate({
                left: this.x + 'px',
                top: '400px'
            } , 5000, 'easeOutBounce');
        }
    };

    var arrayBox = [];
    for( var i = 0; i < n; i++){
        arrayBox[i] = new Box(i,'.obj' + i, i*10, i*100);
    }

})(jQuery);

実際に動かすとこんな感じ。

画像を使わずに矢印を作る

スマートフォンサイトでよくある、右側に矢印があるリストを画像を使わずに作った。

HTML

       <ul class="list">
            <li><a href="">リスト01</a></li>
            <li><a href="">リスト02</a></li>
            <li><a href="">リスト03</a></li>
            <li><a href="">リスト04</a></li>
            <li><a href="">リスト05</a></li>
        </ul>

SCSS

 .list{

        li{
            list-style: none;
            font-size: 12px;

            a{
                position: relative;
                display: block;
                margin-bottom: -1px;
                height: 30px;
                border: 1px solid #000;
                background-color: rgba(#000,0.8);
                color: #fff;
                text-align: left;
                text-decoration: none;
                text-indent: 10px;
                line-height: 2.8;

                &:before{
                    position: absolute;
                    top: 13px;
                    right: 10px;
                    display: block;
                    width: 6px;
                    height: 1px;
                    background: #fff;
                    content: "";
                    -webkit-transform: rotate(45deg);
                    transform: rotate(45deg);
                }

                &:after{
                    position: absolute;
                    top: 17px;
                    right: 10px;
                    display: block;
                    width: 6px;
                    height: 1px;
                    background: #fff;
                    content: "";
                    -webkit-transform: rotate(135deg);
                    transform: rotate(135deg);
                }
            }
        }
    }

実際の表示はこんな感じ。

※Sassのシンタックスハイライトってまだ対応してないんですね。

即時関数の引数を使って名前空間を作る

即時関数の引数を使った名前空間の作り方を教えてもらったのでメモ。

(function(window, namespace){
    
    window[namespace] = {
        fuga : function(){
            document.write('Hello!');
        }
    };
    
})(this, 'Hoge');

Hoge.fuga();

グローバルオブジェクトにHogeを追加して名前空間を作ります。
中の変数や関数はHogeを通じて呼び出すので、名前の衝突を避ける事ができます。

windowを引数にしてthisを代入する理由はこれ。

・window ではなく this を使う理由
"window" がブラウザ依存の名前だから。
例えば、node.js では global ですし、WSH では グローバルオブジェクトに名前がありません。
this は ECMAScript 規定なので JavaScript ならどの実装でも必ずアクセスできます。
http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1054661400