web-dev-qa-db-ja.com

モバイルデバイスの「ノッチ」の検出

IPhone Xの発売が間近に迫っているので、私はゲームを先取りし、デザインの変更を処理できるようにいくつかのWebアプリケーションを準備しようとしています。その最大のものはフロントカメラを収容する新しい「ノッチ」です。

Javascriptでこれをどうにかして検出する方法があるのか​​、またはある可能性があるのではないかと思っていました。

興味深いことに、Chris Coyierが The "Notch" and CSS についての記事を書いており、safe-area-inset-right 絶え間ない。これはJavaScriptでアクセスできる方法はありますか?これは信頼できるテストですか?.

if (window.constant.safeAreaInsetRight) {
  var notch = true;
}
13
kinggs

これは少しやりにくいかもしれませんが、画面の利用可能な高さと幅を取得し、これらをこの仕様に一致させることで、iPhone Xかどうかを判断できます。

ご注意ください

縦向きでは、iPhone Xのディスプレイの幅は、iPhone 6、iPhone 7、およびiPhone 8の4.7インチディスプレイの幅と一致します。ただし、iPhone Xのディスプレイは、4.7インチディスプレイよりも145 pt高いです...

enter image description here

したがって、最初に、それがuserAgentを介してiPhoneであるかどうかを確認します。次に、実際の画面の領域をチェックします(デフォルトで縦向きになっている方向を除く)。最後に、それが画面を介してiPhoneXであることがわかったら、方向を決定できる寸法(上のiPhone X図の下の表に基づく)

if (navigator.userAgent.match(/(iPhone)/)){
  if((screen.availHeight == 812) && (screen.availWidth == 375)){

    if((window.innerHeight == "375") && (window.innerWidth == "812")){
      // iPhone X Landscape

    }else{
      // iPhone X Portrait
    }
  }
}

参照:

avilHeight

avilWidth

iPhoneX仕様

CSSソリューションに関しては、私は昨日それについて有用なかもしれない興味深い記事を見つけました

固定位置のヘッダーバーがあり、iOS 10のCSSが現在次のようになっているとします。

header {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: 44px;

    padding-top: 20px; /* Status bar height */
}

IPhone Xおよびその他のiOS 11デバイス用に自動的に調整するには、viewportメタタグにviewport-fit = coverオプションを追加し、定数を参照するようにCSSを変更します。

header {
    /* ... */

    /* Status bar height on iOS 10 */
    padding-top: 20px;

    /* Status bar height on iOS 11+ */
    padding-top: constant(safe-area-inset-top);
}

Constant()構文の解釈方法がわからない古いデバイスでは、フォールバック値をそのままにしておくことが重要です。 CSSのcalc()式で定数を使用することもできます。

記事

7
Adriani6
// iphone X detection

function hasNotch() {
    if (CSS.supports('padding-bottom: env(safe-area-inset-bottom)')) {
      let div = document.createElement('div');
      div.style.paddingBottom = 'env(safe-area-inset-bottom)';
      document.body.appendChild(div);
      let calculatedPadding = parseInt(window.getComputedStyle(div).paddingBottom, 10);
      document.body.removeChild(div);
      if (calculatedPadding > 0) {
        return true;
      }
    }
    return false;
  }
5
Youssef Makboul

@ youssef-makboulの回答と@hjellekによるコメント以降、iOSはconstant()からenv()構文に変更され、現在のすべてのiPhone X iOSバージョンでこのアプローチをサポートするにはフォールバックが必要です。

const hasNotch = function () {
    var proceed = false;
    var div = document.createElement('div');
    if (CSS.supports('padding-bottom: env(safe-area-inset-bottom)')) {
        div.style.paddingBottom = 'env(safe-area-inset-bottom)';
        proceed = true;
    } else if (CSS.supports('padding-bottom: constant(safe-area-inset-bottom)')) {
        div.style.paddingBottom = 'constant(safe-area-inset-bottom)';
        proceed = true;
    }
    if (proceed) {
        document.body.appendChild(div);
        let calculatedPadding = parseInt(window.getComputedStyle(div).paddingBottom);
        document.body.removeChild(div);
        if (calculatedPadding > 0) {
            return true;
        }
    }
    return false;
};
4
Robert Waddell

最近これにぶつかった。 CSS環境変数(env())の値をCSSカスタムプロパティに設定し、JavaScriptを介してその値を読み取ることができます。

CSS:

:root {
    --sat: env(safe-area-inset-top);
    --sar: env(safe-area-inset-right);
    --sab: env(safe-area-inset-bottom);
    --sal: env(safe-area-inset-left);
}

JS:

getComputedStyle(document.documentElement).getPropertyValue("--sat")

ここに完全な情報: https://benfrain.com/how-to-get-the-value-of-phone-notches-environment-variables-env-in-javascript-from-css/

1
Ben Frain

0.7k notch-detected-event スクリプトをページに追加します。デバイスにノッチが含まれている場合は、notch-detectedイベントを発生させます。

window.addEventListener('notch-detected', function(e) {
  console.log("Notch detected, move shit around");
});

また、data-notch="true"要素にdata-orientation="portrait|landscape"および<html>を追加して、CSSを使用してレイアウトを微調整できるようにします。

/* make room for the notch at the top */
html[data-notch][data-orientation="portrait"] body {
  padding-top: 44px;
  height: calc(100% - 44px);
}

/* make room for the notch at the sides */
html[data-notch][data-orientation="landscape"] body {
  padding-left: 44px;
  padding-right: 44px;
  width: calc(100% - 44px - 44px);
}

お役に立てれば!

0
John Doherty

追加するもののカップル:

Index.htmlに以下が含まれていることを確認してください

<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">

さらに:

これに関する素晴らしい記事: CSS Tricks Notch

0
Tsavo Knott

私はこれを使っています:

function hasNotch() {

    //iphone X 1.11
    if (document.documentElement.clientHeight == 812 && document.documentElement.clientHeight == 375 && !!window.matchMedia && window.matchMedia("only screen and (-webkit-device-pixel-ratio: 3)").matches && iOSversion()[0] == 11) {
        return true;
    }

    var proceed = false;
    var div = document.createElement('div');
    if (CSS.supports('padding-bottom: env(safe-area-inset-bottom)')) {

        div.style.paddingBottom = 'env(safe-area-inset-bottom)';
        proceed = true;
    } else if (CSS.supports('padding-bottom: constant(safe-area-inset-bottom)')) {

        div.style.paddingBottom = 'constant(safe-area-inset-bottom)';
        proceed = true;
    }
    if (proceed) {
        return true;
    }

    return false;
};

[〜#〜] css [〜#〜]はTypeScriptのグローバルインターフェイスライブラリです。

interface CSS {
    escape(value: string): string;
    supports(property: string, value?: string): boolean;
}
declare var CSS: CSS;

または[〜#〜] css [〜#〜]

$margin_max_constant_notch:unquote('max(-12px, constant(safe-area-inset-left))');
$margin_max_env_notch:unquote('max(-12px, env(safe-area-inset-left))');

/*** iphone X 1.11, iphone XS (quote is OR) ***/
@media only screen
and (device-width : 375px)
and (max-device-width : 812px)
and (-webkit-device-pixel-ratio : 3),
 /*** iphone XR ***/
screen and (device-width : 414px)
and (device-height : 896px)
and (-webkit-device-pixel-ratio : 2),
  /*** iphone XS Max ***/
screen and (device-width : 414px)
and (device-height : 896px)
and (-webkit-device-pixel-ratio : 3),
  /*** iphone XS Max Retina ***/
only screen and (-webkit-min-device-pixel-ratio: 3),
only screen and (   min--moz-device-pixel-ratio: 3),
only screen and (     -o-min-device-pixel-ratio: 3/1),
only screen and (        min-device-pixel-ratio: 3),
only screen and (                min-resolution: 458dpi),
only screen and (                min-resolution: 3dppx),
/** Google Pixel 3 XL  **/
screen and (device-width: 360px)
and (device-height: 740px)
and (-webkit-min-device-pixel-ratio: 4),
only screen and (   min--moz-device-pixel-ratio: 4),
only screen and (     -o-min-device-pixel-ratio: 4/1),
only screen and (        min-device-pixel-ratio: 4),
only screen and (                min-resolution: 523dpi),
only screen and (                min-resolution: 4dppx) {

    @media(orientation: portrait) {

       /* mobile - vertical */


        @media (max-width: 768px) {
         /* up to 768px */
        }

        @media (max-width: 480px) {
         /* up to 480px */
        }

       @media only screen and (max-width: 400px) {
           /* up to 400px */
        }


    }
    @media(orientation: landscape) {
        html,body {
            padding: $margin_max_constant_notch;
            padding: $margin_max_env_notch;
        }

        /* mobile - horizontal */

        @media screen and (max-width: 900px) {

          /* up to 900px */
        }

    }
}

/** iphone X 1.12 **/
@supports(padding: max(0px)) {
@media screen and (device-width : 375px)
and (device-height : 812px)
and (-webkit-device-pixel-ratio : 3) {
    @media(orientation: portrait) {

       /* mobile - vertical */

        @media (max-width: 768px) {
           //até 768px
        }

        @media (max-width: 480px) {
         /* up to 480px */
        }

        @media only screen and (max-width: 400px) {
        /* up to 400px */
        }

      }
      @media(orientation: landscape) {
        html, body {
          padding: $margin_max_constant_notch;
          padding: $margin_max_env_notch;
        }

        @media screen and (max-width: 900px) {
         /* up to 900px */
        }
      }
   }
}

/** iphone 8 **/
@media only screen
and (device-width : 375px)
and (device-height : 667px)
and (-webkit-device-pixel-ratio : 2),
  /** iphone 8 PLUS **/
screen  and (device-width : 414px)
and (device-height : 736px)
and (-webkit-device-pixel-ratio : 3) {
  @media(orientation: portrait) {

  /* mobile - vertical */

  }
  @media(orientation: landscape) {

  /* mobile - horizontal */
  }
}

@media only screen
  /** IPADS **/
and (min-device-width: 1024px)
and (max-device-width: 1366px)
and (-webkit-min-device-pixel-ratio: 2) {

 /* for ipads */

  @media(orientation: portrait) {

  /* ipad - vertical */

  }
  @media(orientation: landscape) {

  /* ipad - horizontal */
  }

}
0
Ivan Ferrer