美文网首页web 前端psWeb前端之路
实现微信对话框的图片样式

实现微信对话框的图片样式

作者: 小菜燕 | 来源:发表于2016-12-28 10:50 被阅读2883次

    不知道大家有没有注意到,微信里面,我们聊天的时候,发文字和发图片的时候,气泡对话框样式是有所不同的。有啥不同呢?且看下图。

    Paste_Image.png

    可以看到,发图片的时候,气泡对话框箭头的背景也是图片的一部分。出于好奇和需求,我试着尝试实现这一样式。实现是在移动端下进行的。

    用到的css属性

    background: inherit: 表示继承父级的背景属性,其中包括背景图片。
    background-origin: 规定 background-position 属性相对于什么位置来定位。
    background-clip: 设置元素的背景(背景图片或颜色)是否延伸到边框下面。

    方法一

    原理是,定义一个块级元素,把图片设置为块级元素的背景图片,图片位置左移20px,然后使用伪元素,把三角形实现出来,同时继承父级的背景图片,border的宽度是20px,和上面的左移尺寸一样,这样图片拼接才顺畅。代码如下:

    <div class="dialog"></div>
    
    <style>
    .dialog {
        position: relative;
        width: 200px;
        height: 200px;
        border-radius: 10px;
        margin-left: 40px;
        background: url("card.png") -20px 0 no-repeat;
        background-size: 220px auto;
    }
     .dialog:after {
         content: '';
         position: absolute;
         top: 30px;
         left: -40px;
         border: solid #ccc;
         border-width: 20px;
         border-right-color: transparent;
         background: inherit;
         background-size: auto;
         background-clip: border-box;
         background-origin: border-box;
         background-position: 20px -30px;
    }
    </style>
    

    实现的效果图是这样的:


    Paste_Image.png

    看起来还不错,达到了预期效果。但是,仔细看下代码,里面的宽度和高度都是固定的,也就是说,不同的图片,在这里显示尺寸都是一样的,这个展示不太友好。

    方法二

    为了做到自适应,我选择使用img来自动控制大小。对img指定宽度,然后高度自适应。原理跟方法一有点类似。这里大家可以先思考下,如何做。
    实现的代码如下:

    <div class="dialog">
        <div class="pic-wrap">
            <img src="test.png" alt="">
        </div>
    </div>
    <style>
        .dialog {
            position: relative;
            width: 200px;
            border-radius: 10px;
            margin-left: 40px;
            background-size: 2px 2px;
            background: url(test.png) -9999px 0 no-repeat;
            img{
                width: 100%;
                position: relative;
                left: -20px;
                bottom: 0;
                top: 0;
                border-radius: 10px;
                display: block;
            }
            .pic-wrap{
                overflow: hidden;
                border-radius: 10px;
            }
        }
    
        .dialog:after {
            content: '';
            position: absolute;
            top: 30px;
            left: -38px;
            border: solid #ccc;
            border-width: 10px 20px;
            background: inherit;
            border-right-color: transparent;
            background-clip: border-box;
            background-origin: border-box;
            background-position: 20px -30px;
        }
    </style>
    

    简单说下原理,三角形的做法还是跟方法一一样,不同的是对话框内图片的处理。这次采用了img标签,并且在img外包了一层,以控制img的展示。首先,img先设置position:absolute,然后,设置left: -20px。然后外层设置宽度,高度由图片控制,设置overflow:hidden,裁剪掉多余的图片部分。
    实现的效果如下图:

    Paste_Image.png

    ok ,这次可以自适应了,但是图片必须要固定宽度,这个展示也不是那么好。最好是可以根据图片的比例,来自动设置宽度和高度,于是就有了方法三。

    方法三

    在这个方法里面,我的想法是可以做到,图片的高宽可以按照图片的比例来进行展示,而不是固定宽度和高度。这个也是可以实现的,但是需要使用javascript来配合。

    原理是这样的:等图片load完之后,拿到图片的大小,然后对图片的展示宽度按照一定的规则进行计算,我这里是采用 (图片的高度/屏幕的高度) * 图片的高度 * 0.5。然后动态设置dialogwidthbackground-size

    实现的代码如下:

    <!-- html & css -->
    <div class="dialog">
        <div class="pic-wrap">
            <img src="test.png" alt="">
        </div>
    </div>
    <style>
        .dialog {
            position: relative;
            border-radius: 10px;
            margin-left: 40px;
            background: url(test.png) -9999px 0 no-repeat;
            img{
                width: 100%;
                position: relative;
                left: -20px;
                bottom: 0;
                top: 0;
                border-radius: 10px;
                display: block;
            }
            .pic-wrap{
                overflow: hidden;
                border-radius: 10px;
            }
        }
    
        .dialog:after {
            content: '';
            position: absolute;
            top: 30px;
            left: -38px;
            border: solid #ccc;
            border-width: 10px 20px;
            background: inherit;
            background-size: inherit;
            border-right-color: transparent;
            background-clip: border-box;
            background-origin: border-box;
        }
    </style>
    
    
    /** javascript **/
    var dialog = (function(){
        $('img').load(function(){
            var img_real_height = parseInt($(this).height());
            var win_height = parseInt(window.innerHeight);
    
            var img_width = img_real_height / win_height * (img_real_height) * 0.5;
    
            $(this).parents('.dialog').css(
                {
                    'width': img_width,
                    backgroundSize: img_width+'px auto'
                }
            );
        })
    })()
    

    但是这个方式也有缺点,就是图片的展示宽度很难用一个比较合理的公式去计算,如果你的图片规格都是差不多的,那可以用这种方法,但是如果你的图片规格多种,就不建议用这种方式了。

    方法四

    在经过一番思考之后,我决定再去仔细看看微信的处理方法。发现了一个规则:微信里面,如果图片的高度大于宽度,则固定高度,如果图片的高度小于宽度,则固定宽度

    ok,那我就来实现一番。

    <!-- html & css -->
    <div class="dialog" style="background-image: url(../images/test1.jpg)">     
        <div class="pic-wrap">
            <img src="../images/test1.jpg">
        </div>
    </div>
    
    <style>
     .dialog {
        position: relative;
        border-radius: 10px;
        background-position: -9999px 0;
        background-repeat: no-repeat;
        margin-left: 10px;
    
        img{
           position: relative;
           left: -20px;
           border-radius: 10px;
           display: block;
         }
    
         // 横向
         &.landscape {
             height: auto;
             background-size: px2rem(180px) auto;
             img{
                 width: px2rem(180px);
             }
         }
    
         // 竖向
         &.vertical{
             height: px2rem(180px);
             background-size: auto px2rem(180px);
             img{
                 height: px2rem(180px);
             }
         }
    
         .pic-wrap{
             overflow: hidden;
             border-radius: 10px;
          }
      }
    
    .dialog:after {
        z-index: -2;
        content: '';
        position: absolute;
        top: 10px;
        left: -12px;
        border: solid $bgGrey;
        border-right-color: transparent;
        border-width: 8px 6px;
        background-image: inherit;
        background-size: inherit;
        background-repeat: no-repeat;
        background-clip: border-box;
        background-origin: border-box;
        background-position: 0px -6px;
    }
    
    /**  javascript **/
    var dialog = (function(){
        function loadImg() {
            $('img').load(function(){
                var img_real_height = parseInt($(this).height());
                var img_real_width = parseInt($(this).width());
    
                var max_width = '180px';
                var max_height = '180px';
    
                if(img_real_width / img_real_height > 1) {
                    // 横向处理
                    $(this).parents('.dialog').addClass('landscape');
                }else{
                    // 竖向处理
                    $(this).parents('.dialog').addClass('vertical');
                }
    
            })
        }
    
        loadImg();
    })()
    

    实现的效果如下:

    Paste_Image.png

    补充

    在上述获取图片大小的时候,我使用了load()方法,但是我发现这个方法不太靠谱,会偶尔出现获取不到图片尺寸的情况。要解决这个情况,最好是通过后台接口来取得图片的尺寸,这样会靠谱点。

    相关文章

      网友评论

      • 洋_洋lemon:我试了你的方法,没有实现预期的效果,是不是代码没贴完整

      本文标题:实现微信对话框的图片样式

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