实现效果

昨天泽泽分享了一篇有意思的文章:纯CSS根据图片取色设置背景色,主要分享了一个就是div嵌套img的时候,如何实现div的颜色为img中一点的颜色。

图片来源于泽泽的博客
图片来源于泽泽的博客

思路讲解

其思路也是很容易明白,看懂原理之后有种获益匪浅的感觉,这也说明了任何一点简单的知识只要可以搞得足够明白就能实现出很多一般人想不到的效果。如下图所示,在PS中打开一张图片,如果将这张图片一直放大,具体到每个像素点,会发现图片单个像素点内的颜色值都是唯一的。

原图
原图
放大很多倍后
放大很多倍后

这个时候如果你想一下其实就可以明白了,网页中如果出现一个div包裹img的情况,我们可以把div的背景设置成与img相同的图片(background-image: url();),然后再把div的背景放大很多倍(background-size: 200000%;),就可以实现以上的效果了。具体的实现代码如下所示:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .img-box {
            width: 1000px;
            margin: 100px auto;
            text-align: center;
            border: 1px solid black;
            padding: 50px 0;
            background: url('https://image.manyacan.com/202211221042805.png-wm04#vwid=1653&vhei=817') center center/20000%;
        }
        .img-box>img {
            width: 80%;
        }
    </style>
</head>

<body>
    <div class="img-box">
        <img src="https://image.manyacan.com/202211221042805.png-wm04#vwid=1653&vhei=817" alt="">
    </div>
</body>

</html>

效果图
效果图

这里有个注意点,就是CSS中background属性的写法。使用background的简写属性时:如果写了background-size的值,则必须写background-position的值,否则是没有效果的!!!另外,background-positionbackground-size 属性之间需使用/分隔, 且background-position值在前, background-size值在后,否则没有效果。具体语法结构如下所示:

.bg {
    background: [background-color] [background-image] [background-repeat] [background-attachment] [background-position] / [background-size] [background-origin] [background-clip]
}

现学现用

既然学到了这个不错的知识点,那么第一时间想到的就是如何应用在我自己的博客上。第一时间我想到的就是我的友链页面,页面结构的话就是:

<a class="board-item link-item">
    <div data-thumb="https://image.manyacan.com/202211122122994.png">
        <img src="https://image.manyacan.com/202211122122994.png">
    </div>
    <div class="board-title">
        918爱国网
    </div>
</a>

我想实现的效果就是每一个友链.board-item下面的文字部分背景色都是上面图片中的一点的颜色。

实现效果
实现效果

有了具体的思路了就是如何实现了,因为我这个页面是前后端渲染的动态页面,改PHP代码的话有点麻烦,所以我就考虑从前端入手,使用JQuery来实现:

  1. 获取每一个友链链接.board-item
  2. 然后通过显示迭代获取每一个友链中的背景图;
  3. 然后将下方文字的背景图设置为获取的背景图地址,同时,使用Math.random()产生一个随机数,这样的话就可以实现对图片中随机一点进行取色,且每次刷新都会产生不一样的效果。
$(".board-item").each(function (i) {
    var img_url = $(this).find(".board-thumb").attr("data-thumb");
    $(this).find(".board-title").css('background', 'url(' + img_url + ') ' + Math.random() * 100 + '% ' + Math.random() * 100 + '%/10000%')
})

知识点学习

jQuery操作css()的方法

参考「jQuery」基础 - 01中“1.4.1. 方法1: 操作 css 方法”与“1.4.2. 方法2: 设置类样式方法”(好记性不如烂笔头~?)。

JQuery方法.each()

简单来说,显示迭代与隐式迭代最简单的区别就是看给每一个对象设置的值是否相同,不同值的时候(或不同处理) 使用显示迭代,为每个匹配的元素执行不同函数,例如:

$('li').each(function (index,element) {
    console.log(index + element); //每一个li标签,是一个dom对象.
});

注意:返回 false 可用于停止循环:

<!DOCTYPE html>
<html>
<head>
  <style>
  div { width:40px; height:40px; margin:5px; float:left;
        border:2px blue solid; text-align:center; }
  span { color:red; }
  </style>
  <script src="https://code.jquery.com/jquery-latest.js"></script>
</head>
<body>
  <button>Change colors</button>
  <span></span>
  <div></div>
  <div></div>
 
  <div></div>
  <div></div>
  <div id="stop">Stop here</div>
  <div></div>
 
  <div></div>
  <div></div>
<script>
    $( "button" ).click(function () {
      $( "div" ).each(function ( index, domEle) {
        // domEle == this
        $( domEle ).css( "backgroundColor", "yellow" );
        if ( $(this).is( "#stop" ) ) {
          $( "span" ).text( "Stopped at div index #" + index );
          return false;
        }
      });
    });
 
</script>
 
</body>
</html>

给每一个对象设置相同值的时候(或相同处理)使用隐式迭代,例如:

$('li').css('border', '1px solid red')

官方文档:https://www.jquery123.com/each/