IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    手机百度移动适配切图解决方案介绍

    三水清 (ksky521@gmail.com)发表于 2015-12-12 08:38:06
    love 0

    我们知道移动开发上面有个设备像素比:window.devicePixelRatio,现在在开发页面的时候,一定会在head中添加个viewport的meta类似下面的代码:

    <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
    

    但是随着手机屏幕越来越大,于是页面会遇见下面的问题:

    iPhone5页面
    iPhone6 Plus页面

    介绍下REM

    rem是以document.documentElement(即<html>标签)的font-size为基准的,举例说明:

    • html的font-size:10px
    • 那么1rem = 10px

    手百Rem切图方案

    为了切图方便,我们手百使用了Rem切图,首先类似淘宝的flexible方案,会在页面head中引入一个flexible.js。

    为了计算方便,我们将documentElement的font-size设置为页面宽度的10%,代码如下:

    var docEl = document.documentElement;
    var width = docEl.getBoundingClientRect().width;
    var rem = width / 10;
    docEl.style.fontSize = rem + 'px';
    

    同时配合js获取dpr动态设置的viewport。切图布局的时候,需要计算rem,为了方便我们使用sass写了一个rem函数和mixin:

    $rem-baseline: 75px !default;
    @function rem-convert($to, $values...) {
      $result: ();
      $separator: rem-separator($values);
    
      @each $value in $values {
        @if type-of($value) == "number" and unit($value) == ""{
            $value: $value * 1px;
        }
        @if type-of($value) == "number" and unit($value) == "rem" and $to == "px" {
          $result: append($result, $value / 1rem * $rem-baseline, $separator);
        } @else if type-of($value) == "number" and unit($value) == "px" and $to == "rem" {
          $result: append($result, $value / ($rem-baseline / 1rem), $separator);
        } @else if type-of($value) == "list" {
          $result: append($result, rem-convert($to, $value...), $separator);
        } @else {
          $result: append($result, $value, $separator);
        }
      }
    
      @return $result;
    }
    
    @function rem($values...) {
      @if $rem-px-only {
        @return rem-convert(px, $values...);
      } @else {
        @return rem-convert(rem, $values...);
      }
    }
    
    @mixin rem($properties, $values...) {
      @if type-of($properties) == "map" {
        @each $property in map-keys($properties) {
          @include rem($property, map-get($properties, $property));
        }
      } @else {
        @each $property in $properties {
          @if $rem-fallback or $rem-px-only {
            #{$property}: rem-convert(px, $values...);
          }
          @if not $rem-px-only {
            #{$property}: rem-convert(rem, $values...);
          }
        }
      }
    }
    //
    .demo{
        height: rem(300px);
        @include rem(padding, 10px 20px);
    }
    

    sass变量 $rem-baseline 是基准值,以设计图宽度/10为准,这样设计后,就可以直接用视觉稿的尺寸大小切图了。

    举个例子

    720px的视觉稿中有个360x360的div。

    普通切图

    使用普通方法切页面,设置:

    <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
    

    这样采用iPhone5为基准手机切图,需要计算:需要切图的图层width/(视觉稿width/基准手机设备宽度) 即:360/(720/320)=160px

    Rem切图

    • 设置$rem-baseline为720/10,即72px
    • 使用rem进行计算:width: rem(360px)

    算一算

    1. html字体:1rem=640px/10=64px
    2. viewport:scale = 1/dpr = 0.5
    3. css的宽:360px/72px = 5rem
    4. 5rem64px0.5 = 160px

    字体问题

    字体的大小是根据<body>标签的font-size,为了计算方便,$font-baseline设置为12px,所以需要根据不同的设备像素比设置不同的font-size,然后配合sass的mixin fontsize设置字体大小

    [data-dpr="1"] body{
        font-size: $font-baseline;
    }
    [data-dpr="2"] body{
        font-size: $font-baseline * 2;
    }
    [data-dpr="2.5"] body{
        font-size: $font-baseline * 2.5;
    }
    [data-dpr="2.75"] body{
        font-size: $font-baseline * 2.75;
    }
    [data-dpr="3"] body{
        font-size: $font-baseline * 3;
    }
    .demo{
        @include fontsize(24px);
    }
    

    总结

    关于设备上面的切图就说到这里,想了解更多,看下我之前的分析:移动适配切图方案



沪ICP备19023445号-2号
友情链接