美文网首页
iPhone X的刘海发型和衍生的交互

iPhone X的刘海发型和衍生的交互

作者: 你期待的花开 | 来源:发表于2017-10-26 10:31 被阅读75次

    iPhone X造型上有个显著的特质,就是有个明显的刘海。
    然后,也出现了一些酷酷的交互。体验

    CSS3 Shapes实现元素滚动自动环绕iPhone X头部刘海效果

    方法一

    环绕齐刘海滚动实现原理

    CSS Shapes中有个CSS属性名为shape-outside,可以让内联元素以不规则的形状进行外部排列,其语法如下(参考自MDN):

    /* 关键字值 */
    shape-outside: none;
    shape-outside: margin-box;
    shape-outside: content-box;
    shape-outside: border-box;
    shape-outside: padding-box;
    
    /* 函数值 */
    shape-outside: circle();
    shape-outside: ellipse();
    shape-outside: inset(10px 10px 10px 10px);
    shape-outside: polygon(10px 10px, 20px 20px, 30px 30px);
    
    /* <url>值 */
    shape-outside: url(image.png);
    
    /* 渐变值 */
    shape-outside: linear-gradient(45deg, rgba(255, 255, 255, 0) 150px, red 150px);
    
    

    shape-outside属性要想生效,本身需要是浮动float元素。
    本文demo效果实现使用的是shape-outside:polygon(),通过点坐标勾勒出和齐刘海形状相似的多边形形状,CSS代码为:

    .shape {
      float: left;
      shape-outside: polygon(0 0, 0 150px, 16px 154px, 30px 166px, 30px 314px, 16px 326px, 0 330px, 0 0);
    }
    

    此时,后面没有设置BFC(块状格式化上下文)的列表元素就会自动环绕这个形状排列,也就是自动避开了齐刘海区域。

    然后,只要搞个假的iPhone X的齐刘海图片覆盖在区域上就可以了。

    下面关键的问题是如何让滚动的时候,列表元素动态的跟着环绕呢?

    由于shape-outside所在的元素是浮动元素,因此,必定会跟着容器一起滚动,我们需要的效果是我们所绘制的这个刘海区域需要是固定的,怎么办?此时,我是借助JavaScript处理的。

    原理很简单,监听容器的滚动事件,让我们的shape-outside绘制的区域实时偏移滚动的大小。此时肉眼看上去的效果就是shape-outside区域永远固定在了滚动容器clientHeight的中间。

    整个效果就这么实现了,相关JS如下:

    box.addEventListener('scroll', function () {
      var scrollTop = box.scrollTop;
      // 滚动偏移应用在shape-outside上
      shape.style.shapeOutside = 'polygon(0 0, 0 '+ (150 + scrollTop) +'px, 16px '+ (154 + scrollTop) +'px, 30px '+ (166 + scrollTop) +'px, 30px '+ (314 + scrollTop) +'px, 16px '+ (326 + scrollTop) +'px, 0 '+ (330 + scrollTop) +'px, 0 0)';
    });
    

    详尽代码

    CSS代码:
    .box {
        max-width: 414px;
        height: 480px;
        border: solid #000;
        margin: auto;
        overflow: auto;
    }
    .shape {
        float: left;
        width: 30px; height: 340px;
        shape-outside: polygon(0 0, 0 150px, 16px 154px, 30px 166px, 30px 314px, 16px 326px, 0 330px, 0 0);
        transition: shape-outside .15s;
    }
    .liuhai {
        width: 24px; height: 180px;
        background: url(liu.png) no-repeat left center;
        position: absolute;
        margin-top: 150px;
    }
    .content ul {
        list-style: none;
        padding: 0;
        margin: 0;
    }
    .content li {
        border-bottom: 1px solid #eee;
        padding: .5em;
    }
    HTML代码:
    <div id="box" class="box">
        <i id="shape" class="shape"></i>
        <i class="liuhai"></i>
        <div class="content">
            <ul>
                <li>为了防止看花眼</li>
                <li>我就手动敲下面的文字</li>
                <li>原本我偷懒</li>
                ...
                <li>理论上还可以使用CSS region实现</li>
                <li>但没有这个方法容易理解</li>
            </ul>
        </div>
    </div>
    JS代码:
    var eleShape = document.getElementById('shape');
    var eleBox = document.getElementById('box');
    // 保证shape元素高度足够
    eleShape.style.height = eleBox.scrollHeight + 'px';
    
    var funShape = function () {
        var scrollTop = eleBox.scrollTop;
        // 滚动偏移应用在shape-outside上
        var shapeOutside = 'polygon(0 0, 0 '+ (150 + scrollTop) +'px, 16px '+ (154 + scrollTop) +'px, 30px '+ (166 + scrollTop) +'px, 30px '+ (314 + scrollTop) +'px, 16px '+ (326 + scrollTop) +'px, 0 '+ (330 + scrollTop) +'px, 0 0)';
        eleShape.style.shapeOutside = shapeOutside;
    };
    // 滚动时候实时改变shape形状
    eleBox.addEventListener('scroll', funShape);
    funShape();
    

    方法二

    我们还可以使用shape-outside:url(image.png)语法实现类似的效果,其中'image.png'就是用来被环绕的图片,环绕与否是基于计算alpha通道决定,用句简单的话描述,就是沿着图片非透明区域环绕。

    由于使用url()的形状计算是基于图片元素,和inset(), circle(), ellipse()或者polygon()这些基础形状方法的计算性质不一样,因此,可以直接使用垂直方向的margin进行偏移。这要比polygon()这样实时计算坐标位置要好理解的多。

    .shape {
      float: left;
      shape-outside: url(liu-outside.png);
      margin-top: 150px;
    }
    box.addEventListener('scroll', function () {
      var scrollTop = box.scrollTop;
      // 滚动偏移应用在margin-top上
      shape.style.marginTop = (150 + scrollTop) + 'px';
    });
    

    可以看到,当我们滚动容器的时候,改变的就一个marginTop值就好了;而上面的 shape-outside:polygon()实现需要同时改变多个坐标值。

    详尽代码

    CSS代码:
    .box {
        max-width: 414px;
        height: 480px;
        border: solid #000;
        margin: auto;
        overflow: auto;
    }
    .shape {
        float: left;
        width: 30px; height: 180px;
        margin-top: 150px;
        -webkit-shape-outside: url(liu-outside.png);
        shape-outside: url(liu-outside.png);
        transition: margin-top .15s;
    }
    .liuhai {
        width: 24px; height: 180px;
        background: url(liu.png) no-repeat left center;
        position: absolute;
        margin-top: 150px;
    }
    .content ul {
        list-style: none;
        padding: 0;
        margin: 0;
    }
    .content li {
        border-bottom: 1px solid #eee;
        padding: .5em;
    }
    HTML代码:
    <div id="box" class="box">
        <i id="shape" class="shape"></i>
        <i class="liuhai"></i>
        <div class="content">
            <ul>
                <li>为了防止看花眼</li>
                <li>我就手动敲下面的文字</li>
                <li>原本我偷懒</li>
                ...
                <li>理论上还可以使用CSS region实现</li>
                <li>但没有这个方法容易理解</li>
            </ul>
        </div>
    </div>
    JS代码:
    var eleShape = document.getElementById('shape');
    var eleBox = document.getElementById('box');
    
    var funShape = function () {
        var scrollTop = eleBox.scrollTop;
        // 滚动偏移应用在margin-top上
        eleShape.style.marginTop = (150 + scrollTop) + 'px';
    };
    // 滚动时候实时改变shape形状
    eleBox.addEventListener('scroll', funShape);
    funShape();
    

    四、CSS Shapes的兼容性

    兼容性

    以上参考此处

    五、css Shapes 的更多应用

    链接

    示例
    示例

    相关文章

      网友评论

          本文标题:iPhone X的刘海发型和衍生的交互

          本文链接:https://www.haomeiwen.com/subject/levhpxtx.html