3004


メニュー付きのコンテンツ表示ページを作ろうと考えています。

ピンチイン・アウトで画像を自由に拡大縮小が可能。画面の上下に常時メニューが表示される。メニューはコンテンツを拡大縮小しても固定位置・サイズである。コンテンツの拡大縮小はブラウザの処理に任せる。

という条件のUIを考えておりまして、以下の様なサンプルを作ってみました。

<http://fushi.x0.com/php_system/20141227-stackoverflow-question/sample.html>  
中身はこんな感じです。

[code]

    <!doctype html>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
    #a{
        width:100%;
        height: 30px;
        position: fixed;
        bottom: 0;
        left:0;
        background: red
    }
    #c{
        width:100%;
        height: 30px;
        position: fixed;
        top: 0;
        left:0;
        background: red
    }
    #b{
        width: 100%;
        overflow: hidden;
        height: 200px;
    }
    #b div{
        height: 200px;
        width: 1000px;
        background: blue;
    }
    </style>
    <script>
    document.addEventListener("touchmove",function(){
        var p=innerHeight/outerHeight;
        document.querySelector("#a").style.zoom=p;
        document.querySelector("#c").style.zoom=p;
    });
    </script>
    <body>
        <br><br><br><br><br><br>
        <div id="a"><div>ほげ<button>kage</button>まげ</div></div>
        <div id="c"><div>ほげ<button>kage</button>まげ</div></div>
        <div id="b"><div></div></div>
        <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
    </body>
    </html>
    
[/code]

ページをピンチインすると画面上下の赤いメニューエリアのheightが固定されて狙い通りなのですが  
赤いメニューエリアの中の文字やbutton要素のサイズがメニューエリアのそれと食い違ってしまいます。

左が初期状態、右がピンチインした状態。右側のメニューの高さはほぼ維持されているが、テキストやボタンのサイズの比率が異常になってしまう  
![](https://i.stack.imgur.com/YKTLN.png)

ボタンやテキスト、その他全ての要素のサイズを％で指定する方法を教えて頂けますでしょうか。

* * *

回答を元に再度考えなおしてみた結果、いい感じのコードが書けましたので追記しクローズ 自己解決とさせて頂きます。  
問題を単純化すると、zoom:50%
と指定しているのになぜボタンやテキストは正確に半分のサイズにならないのか？という事になり、zoomプロパティを使わずtransform:scaleプロパティで拡大率を指定する方法にしました。

注意点として、widthも調節する必要がある。transform-originを調節したりと環境によっては差異が出る可能性があるという点があります。

本来はzoomプロパティについて詳しく調べて何故50％で半分にならないのかを突き止めるべきですが、またの機会という事で。

ありがとうございます。

[code]

    <!doctype html>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
    html{min-height:100%;}
    #header{
        width:100%;
        height: 30px;
        position: fixed;
        top: 0;
        left:0;
        background: red;
        transform-origin: 0% 0%;
    }
    #footer{
        width:100%;
        height: 30px;
        position: fixed;
        bottom: 0;
        left:0;
        background: red;
        transform-origin: 0% 100%;
    }
    #content{
        margin-top:35px;
        margin-bottom:35px;
    }
    img {
        max-width: 100%;
    }
    </style>
    <script>
    document.addEventListener("touchmove",function(){
        var o=innerHeight/outerHeight;
        var p=(o*100)+"%";
        document.querySelector("#footer button").innerText=p;
        document.querySelector("#header").style.transform="scale("+o+")";
        document.querySelector("#footer").style.transform="scale("+o+")";
        document.querySelector("#header").style.width=((1/o)*100)+"%";
        document.querySelector("#footer").style.width=((1/o)*100)+"%";
    });
    </script>
    <body>
        <div id="header"><div>ほげ<button>kage</button>まげ</div></div>
        <div id="footer"><div>ほげ<button>kage</button>まげ</div></div>
        <div id="content">
            <img src="1.png"/>
            <img src="2.png"/>
            http://taneppa.net/footerbottom/
        </div>
    </body>
    </html>
    
[/code]


CC BY-SA 3.0
2014-12-27T04:23:23.863
2673
2015-01-05T02:47:01.117
2015-01-05T02:47:01.117
805
805
question
javascript android css html html5
モバイルブラウザでピンチインしても位置・サイズの変わらない固定要素を作る方法


「コンテンツの拡大縮小はブラウザの処理に任せる」に反しますが、zoomの対象を逆転すれば解決するように見えます。Viewportを固定して、

[code]

    <meta name="viewport"
      content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
    
[/code]

その上で、ピンチジェスチャーのエミュレーションをJavaScriptで行います。例えばこんな感じになるでしょうか。単純に、ピンチ開始時の2点の距離と、指の移動中の2点の距離の比をそのままzoomに指定しています。

[code]

    var pinching = false;
    var d0 = 1;
    var d1 = 1;
    document.addEventListener("touchmove", function(e){
      if (e.touches.length == 2) {
        if (!pinching) {
          pinching = true;
          d0 = Math.sqrt(
            Math.pow(e.touches[1].screenX - e.touches[0].screenX, 2) +
            Math.pow(e.touches[1].screenY - e.touches[0].screenY, 2)
          );
        } else {
          d1 = Math.sqrt(
            Math.pow(e.touches[1].screenX - e.touches[0].screenX, 2) +
            Math.pow(e.touches[1].screenY - e.touches[0].screenY, 2)
          );
          document.querySelector("#b").style.zoom = d1 / d0;
        }
      }
    });
    document.addEventListener("touchend", function(e){
      pinching = false;
    });
    
[/code]

サンプルを[Gist](https://gist.github.com/cognitom/de11ba8cf4f4b98ac8ab)に置いておきます。ブラウザから直接確認するには、[こちらのリンク](https://rawgit.com/cognitom/de11ba8cf4f4b98ac8ab/raw/2492f488474aa7a7b03b6577af819dbe27aad2b5/index.html)をどうぞ。


CC BY-SA 3.0
2015-01-03T17:42:00.800
3004
2015-01-03T17:42:00.800
390
2673
answer