根据轮播图修改背景渐变

1,848 阅读2分钟

工作中遇到过这种需求,轮播图背景需要根据轮播图片动态改变,轮播图设计都是左右渐变的图片。

方案一

把渐变色与图片地址存放在一起,这样前端处理较少,但是每次修改图片都要后端存入相应的渐变色值。

方案二

前端可以利用canvas读取图片颜色,然后将读取的色值绘制渐变,前端工作增加。 这里就写下方案二的做法。轮播使用的是vant的插件。实现效果如下图:

1590565705(1)
页面结构如下:

<template>
  <div class="home">
    <van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
      <van-swipe-item v-for="item in banners" :key="item.index" :style="'background:'+item.bc">
        <div>
          <img :src="item.src" />
        </div>
      </van-swipe-item>
    </van-swipe>
    <!-- 用于读取图片颜色的canvas -->
    <canvas ref="getPicColor" style="display:none;"></canvas>
  </div>
</template>

js实现如下:

<script>
export default {
  name: "Home",
  data() {
    return {
      banners: [
        {
          src: require("../assets/img/banner1.jpg"),
          bc: ""
        },
        {
          src: require("../assets/img/banner2.jpg"),
          bc: ""
        },
        {
          src: require("../assets/img/banner3.jpg"),
          bc: ""
        },
        {
          src: require("../assets/img/banner4.jpg"),
          bc: ""
        }
      ]
    };
  },
  methods: {
    getImgColor(canvas, index, $this) {
      const img = new Image();
      img.crossOrigin = ""; //处理canvas图片跨域问题
      img.src = $this.banners[index].src;
      img.onload = function() {
        canvas.width = img.width;
        canvas.height = img.height;
        const context = canvas.getContext("2d");
        context.drawImage(img, 0, 0);
        // 获取像素数据
        const data1 = context.getImageData(0, 0, 1, 1).data;
        const data2 = context.getImageData(
          img.width - 1,
          img.height - 1,
          img.width,
          img.height
        ).data;
        // 取所有像素的平均值
        let r1 = 0,
          r2 = 0,
          g1 = 0,
          g2 = 0,
          b1 = 0,
          b2 = 0;
        const index1 = 0;
        // 取开始像素的颜色
        r1 += data1[index1 * 4 + 0];
        g1 += data1[index1 * 4 + 1];
        b1 += data1[index1 * 4 + 2];

        // 将最终的值取整
        r1 = Math.round(r1);
        g1 = Math.round(g1);
        b1 = Math.round(b1);
        const index2 = 0;

        r2 += data2[index2 * 4 + 0];
        g2 += data2[index2 * 4 + 1];
        b2 += data2[index2 * 4 + 2];

        // 将最终的值取整
        r2 = Math.round(r2);
        g2 = Math.round(g2);
        b2 = Math.round(b2);
        const color1 = "rgb(" + r1 + "," + g1 + "," + b1 + ")";
        const color2 = "rgb(" + r2 + "," + g2 + "," + b2 + ")";
        //rgb转16进制 位运算
        // const color = ((r << 16) | (g << 8) | b).toString(16);
        const style = "linear-gradient(to right," + color1 + "," + color2 + ")";
        $this.banners[index].bc = style;
      };
    }
  },
  mounted() {
    //下面是vue中读取banners图片颜色
    const $this = this;
    const canvas = this.$refs.getPicColor;
    for (let i = 0; i < $this.banners.length; i++) {
      $this.getImgColor(canvas, i, $this);
    }
  }
};
</script>

本菜鸟也是百度了canvas如何读取图片颜色写的上述代码,可能有些冗余。其中读取的是图片左上角和右下角的颜色,然后绘制的渐变。