4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

FORKAdvent Calendar 2018

Day 17

コンテンツをスクロールさせたくないようなWebアプリをつくるコツ

Last updated at Posted at 2018-12-16

コンテンツをスクロールさせたくないようなWebアプリを作りたい場合
頭を悩めることがあるかもしれません。

そういった場合は
※内接リサイズを取り入れたデザインで解決できそうです。

※内接リサイズとは
画像の長辺を枠に合わせ画像全体が枠内に収まるようにリサイズする。
https://qiita.com/suin/items/8de26866a8ab6ca65ba4

iphoneXRと iphoneSE
4.gif

上記の場合表示領域比率を保ちながら、縦or横に最大になるように配置することで
コンテンツが入り切らない、またはコンテンツが小さすぎるといった問題に対応できるように思われます。

ソースコードは下記のように実装しました。

CheckWindow.js
export default class CheckWindow{
  constructor(store){
    this.name = 'SP_checkWindow';
    this.isReverse = false;
    this.store = store;
    if (navigator.userAgent.indexOf('Android') > 0) {
      let orientation = screen.orientation || screen.mozOrientation || screen.msOrientation;
      if (orientation.type === "portrait-secondary" || orientation.type === "landscape-primary") {
        this.isReverse = true;
      }
    }
    window.addEventListener('resize',()=> this.setWindow);
    window.addEventListener("orientationchange", ()=> this.check);
    this.setWindow();
    this.check();
  }

  setWindow(){
    const wRaito = 375;
    const hRaito = 553;
    const design_device_rait = hRaito/wRaito;
    const design_device_hraito = wRaito/hRaito;
    const devicerait = Math.floor(window.innerHeight/window.innerWidth * 100)/100;
    let device_rate ={};
    if(design_device_rait <= devicerait){
      device_rate.width = "100vw";
      device_rate.height = String(design_device_rait * 100) + "vw";
    } else {
      device_rate.width = String(window.innerHeight * design_device_hraito) + "px";
      device_rate.height = "100%";
    }
    let winObj = {
      width : window.innerWidth,
      height : window.innerHeight,
      device_rate : device_rate
    };
    this.store.dispatch("setWindowAction",winObj);
  }

  check(){
    if (this.isReverse) {
      this.orientCheckReverse();
    } else {
      this.orientCheck();
    }
  }
  orientCheck() {
    let orientation = window.orientation;
    let isPort = (orientation === 0);
    this.store.dispatch("setPortraitAction",isPort)
  }
  orientCheckReverse() {
    let orientation = window.orientation;
    let isPort= (orientation === 0);
    this.store.dispatch("setPortraitAction",isPort)
  };
}

Vueのテンプレートに組み込むのも良いのですが
今回は別jsファイル化しました。

const wRaito = 375;
const hRaito = 553;

の部分は

こちらの記事のviewportの値を参考にしました。
https://note.unshift.jp/n/n3eae1f28a41d

iphoneはスクロール処理が入ることで
アドレスバーが縮みます。
つまりスクロールしないことでアドレスバーは縮まらず
通常より表示領域が小さいということになります。

store.js
const store = new Vuex.Store({
  state:{
    window:{
      width:0,
      height:0,
      device_rate:{
        width : "100vw",
        height : "147.2vw",
      },
      isPortrait:true
    }
  },
  getters:{
    getWindowRate(state){
      return state.window.device_rate
    }
  },
  mutations:{
    setWindowWH(state,payload){
      state.window.width = payload.width;
      state.window.height = payload.height;
      state.window.device_rate.width = payload.device_rate.width;
      state.window.device_rate.height = payload.device_rate.height;
    },
    setPortrait(state,payload){
      state.window.isPortrait = payload;
    },
  },
  actions:{
    setWindowAction({commit},winObj){
      commit("setWindowWH",{
       width : winObj.width,
       height : winObj.height,
       device_rate : winObj.device_rate
     });
    },
    setPortraitAction({commit},flg){
      commit("setPortrait",flg);
    }
  }
})
new CheckWindow(store);
app.vue
<template lang="pug">
  div.wrapper(v-cloak, :style="{width:window.device_rate.width, height:window.device_rate.height}")
    |アプリ
</template>

<style lang="stylus" scoped>
.wrapper
  position fixed
  top 50%
  left 50%
  width 100%
  height 100%
  transform translate(-50%,-50%)
  background-color #affff1
  overflow hidden
</style>

<script>
  import {mapState} from "vuex";
  export default {
    data(){
      return {
      }
    },
    computed : {
      ...mapState([
        "window"
      ])
    }
  }
</script>

:style="{width:window.device_rate.width, height:window.device_rate.height}"
こうすることで.wrapperに内接リサイズの値が入ってくるので
上記の画像にあったような領域を確保しながら、
スクロールしないアプリエリアを確保する事ができます。

ちなみに

position: fixed;

することで、慣性スクロールも消しています。
window.isPortraitをv-ifで出し分ければ
横画面にしたときに特別な表示(縦にして操作してくださいの表示など)を出すこともできます。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?