[JavaScript]flipsnapを用いた上で画像を重ねる

前回は、static修飾子についてご紹介しました。
今回は、HTMLでスワイプ動作を実現できるライブラリである、「flipsnap」についてご紹介いたします。

■flipsnapとは
HTML画面で、スワイプ動作を実現することが出来るライブラリです。
主に、スマートフォン向けのサイトを作成する際に利用することが出来ます。

■今回ご紹介する内容
「flipsnap」はスワイプ機能を実現するライブラリとして、とても使いやすいため、いくつかの案件で利用してきた経緯があるのですが、このたび、「複数の画像を重ねて表示した」上で、「flipsnap」を用いてスワイプ処理を行う、ということを実現してみましたので、記事としてご紹介します。

■flipsnapの簡単なご紹介
ただ flipsnap を利用する場合、非常に簡単にスワイプ機能をHTMLに組み込むことが出来ます。
※デモはこちら

<CSS>

.viewport {
    overflow:hidden;
    width:300px;
}

.flipsnap {
    overflow:hidden;
    width:1000%;
}

.item {
    float:left;
    width:60px;
}

<JavaScript>

$(function(){
    SampleClass.init();
});

var SampleClass = {
    init : function () {
        Flipsnap("#sampleFlipsnap", {distance:60, maxPoint:3});
    },
};

<HTML>

<html>
<head>
    <meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8" />
    <title>flipsnap サンプル</title>
    <script type="text/javascript" src="js/jquery.min.js"></script>
    <script type="text/javascript" src="js/flipsnap.js"></script>
    <script type="text/javascript" src="js/sample.js"></script>
    <link rel="stylesheet" href="css/sample.css" />
</head>
<body>
Flipsnapサンプル1<br>
<div id="sampleViewport" class="viewport">
    <div id="sampleFlipsnap" class="flipsnap">
        <div class="item"><img src="img/under.png"></div>
        <div class="item"><img src="img/under.png"></div>
        <div class="item"><img src="img/under.png"></div>
        <div class="item"><img src="img/under.png"></div>
        <div class="item"><img src="img/under.png"></div>
        <div class="item"><img src="img/under.png"></div>
        <div class="item"><img src="img/under.png"></div>
        <div class="item"><img src="img/under.png"></div>
    </div>
</div>
</body>
</html>

実現方法は、以下の通りです
1)flipsnap の対象となる部分を、「class=”flipsnap”」で定義
2)flipsnap 内の、個々のアイテムを「class=”item”」で定義
3)JavaScriptにて、Flipsnap(“#sampleFlipsnap”, {distance:60, maxPoint:3}); を実行

Flipsnapの第一引数に、divタグのidを指定します

第二引数に、パラメータを指定するのですが、
distance:60というのは、スワイプした際に、どの程度の量スクロールするのかを指定します
60と指定した場合は、60、120、180、…という節目で止まるようになります

maxPoint:3というのは、スワイプによってページをどこまで切り替えることが出来るのかを指定します
3と指定した場合は、0、60、120、180までスクロールさせることができます

■2つの画像を重ねる方法について
2つの画像を重ねる場合、普通のstyleでは実現することが出来ないため、
各タグを座標指定できる、以下いずれかのstyleを指定することになります

1)style=”position:fixed;top=0px;left=0px;”
本styleを適用したタグは、絶対座標「0,0」に配置されます
スクロールしても、座標が変わらないので、画面下部に広告を出す場合などに利用できます

2)style=”position:absolute;top=0px;left=0px;”
本styleを適用したタグは、絶対座標「0,0」に配置されます
もし、親のタグが static 以外であった場合は、親のタグ位置からの絶対座標になります

3)style=”position:relative;top=-10px;left=-10px;”
本styleを適用したタグは、相対座標「-10,-10」に配置されます
この相対座標は、「style=”position:static”」を指定した際に配置される場所からの相対座標になります

4)style=”position:static”
このstyleがデフォルトの設定になります
特にstyleを指定しないでHTMLファイルを作成した場合は、このスタイルが適用されています
※これでは画像を重ねることができません

2つの画像を重ねる場合、たとえば2)の指定を用いて、以下のように記載することが出来ます

<div style="position:absolute">
    <img src="img/under.png" style="position:absolute; top=0px; left=0px;">
    <img src="img/over.png"   style="position:absolute; top=0px; left=0px;">
</div>

■flipsnapを適用させつつ、2つの画像を重ねる
上述の2つの方法を組み合わせることで、flipsnapを適用させつつ、2つの画像を重ねられるかと考え、以下の通り実装してみます
※デモはこちら

<div id="sampleViewport" class="viewport">
    <div id="sampleFlipsnap" class="flipsnap">
        <div class="item">
            <div style="position:absolute">
                <img src="img/under.png" class="item1" style="position:absolute; left:0px;">
                <img src="img/over.png" class="item2" style="position:absolute; left:0px;">
            </div>
        </div>
        <div class="item">
            <div style="position:absolute">
                <img src="img/under.png" class="item1" style="position:absolute; left:0px;">
                <img src="img/over.png" class="item2" style="position:absolute; left:0px;">
            </div>
        </div>
    </div>
</div>

私が想定した理屈では、
1)div class=”item” は、flipsnapで綺麗に横に並べるために、style=”position:absolute” 指定は出来ない
2)よって、div class=”item” の中に、もう1つdivタグを用意して、これを style=”position:absolute” とする
3)その中に配置する部品を、■2つの画像を重ねる方法について で記載した内容にすれば、動くはず
というものでした。

しかし、実際にこれをブラウザで表示したところ、画面が真っ白になってしまいました。
また、上記の書き方をした上で、flipsnap を適用しなかった場合は、2つの画像が重なってしまいます。

これは、style=”position:absolute” は、「親のタグが static 以外であった場合は、親のタグ位置からの絶対座標に」なると先程説明した通りで、「親のタグが static であった場合は、画面全体での絶対座標に」なってしまう上に、そこに flipsnap を適用してしまって、上手く動作しなくなったためです。

かといって、div class=”item” 自体に style=”position:absolute” を適用してしまうと、このリストをプログラムで動的に変動させたいとなった場合に、全ての div タグの座標を計算することになってしまいます。

■この方法が良い
div class=”item” のstyleをstaticのままに出来れば、flipsnapでアイテムを並べること自体には、気をつかわなくてよくなるため、出来ればその中身のスタイルだけを一意に定めて変更したいです。

丁度、style=”position:relative;” を使えば、「style=”position:static”」を指定した際に配置される場所からの相対座標指定になるので、上手く flipsnap と共存できそうです。

そこで、今度は以下のように指定してみました。

※デモはこちら

<div id="sampleViewport" class="viewport">
    <div id="sampleFlipsnap" class="flipsnap">
        <div class="item">
            <img src="img/under.png" class="item1">
            <img src="img/over.png" class="item2" style="position:relative; top:-36px; left:13px;">
        </div>
        <div class="item">
            <img src="img/under.png" class="item1">
            <img src="img/over.png" class="item2" style="position:relative; top:-36px; left:13px;">
        </div>
        <div class="item">
            <img src="img/under.png" class="item1">
            <img src="img/over.png" class="item2" style="position:relative; top:-36px; left:13px;">
        </div>
        <div class="item">
            <img src="img/under.png" class="item1">
            <img src="img/over.png" class="item2" style="position:relative; top:-36px; left:13px;">
        </div>
        <div class="item">
            <img src="img/under.png" class="item1">
            <img src="img/over.png" class="item2" style="position:relative; top:-36px; left:13px;">
        </div>
        <div class="item">
            <img src="img/under.png" class="item1">
            <img src="img/over.png" class="item2" style="position:relative; top:-36px; left:13px;">
        </div>
        <div class="item">
            <img src="img/under.png" class="item1">
            <img src="img/over.png" class="item2" style="position:relative; top:-36px; left:13px;">
        </div>
        <div class="item">
            <img src="img/under.png" class="item1">
            <img src="img/over.png" class="item2" style="position:relative; top:-36px; left:13px;">
        </div>
    </div>
</div>

上記を実行すると、今度は期待通り、flipsnapの動作をさせつつも、div class=”item” の中に記載した under.png と over.png を重ねて表示することが出来ました。

■終わりに
今回取り上げた、flipsnap を利用しながら画像を重ねる、という方法は、たとえば、一覧を flipsnap で表示して、アイテムを選択されたときに「チェックマーク」を重ねる、というような場合に利用できます。

個人的には、style=”position:relative;” という指定はほぼ、利用しないのですが、今回のように親の div タグは static であってほしい、というようなケースで利用できます。
最後までご覧頂き、ありがとうございました。


弊社では全国各地の請負い(ご自宅)で作業協力頂ける、フリーランスエンジニアの方を常時探しております。
ご興味ある方は、お気軽にお問い合わせ下さい。


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*