Uniapp微信小程序实现,背景跟随轮播图变色

420 阅读2分钟

直接百度也能百度到,但是百度出现uniapp获取图片信息的接口会出现开发工具可以,真机不行的情况,看了下文档,获取图片信息的api变了,这里记录一下,只记录主要代码。

实现轮播图变色:

  1. 获取轮播图颜色信息。

通过轮播图路径将轮播图绘制到canvas画布,以获取像素信息得到平均色值。 代码如下

工具类:

export function getImageThemeColor(path, that,canvasId, callback) {
	wx.createSelectorQuery()
		.select('#'+canvasId) // 在 WXML 中填入的 id
		.fields({ node: true, size: true })
		.exec((res) => {
			// Canvas 对象
			const canvas = res[0].node;
			// 渲染上下文
			const ctx = canvas.getContext('2d');
			// 图片对象
			const image = canvas.createImage();
			// 设置图片src
			image.src = path;
			// 图片加载完成回调
			image.onload = () => {
			    // 将图片绘制到 canvas 上
			    ctx.drawImage(image, 0, 0,300,150);
				const imageData = ctx.getImageData(0, 0, 300, 150);
				const imgHeight = imageData.height;
				const imgWidth = imageData.width;
				let data = imageData.data;
				let arr = [];
				let r = 1,
					g = 1,
					b = 1; 
				// 取所有像素的平均值
				 for (let row = 0; row < imgHeight; row++) {
				   for (let col = 0; col < imgWidth; col++) {
				     if (row == 0) {
				       r += data[imgWidth * row + col];
				       g += data[imgWidth * row + col + 1];
				       b += data[imgWidth * row + col + 2];
				       arr.push([r, g, b]);
				     } else {
				       r += data[(imgWidth * row + col) * 4];
				       g += data[(imgWidth * row + col) * 4 + 1];
				       b += data[(imgWidth * row + col) * 4 + 2];
				       arr.push([r, g, b]);
				     }
				   }
				 }
				  // 求取平均值
				  r /= imgWidth * imgHeight;
				  g /= imgWidth * imgHeight;
				  b /= imgWidth * imgHeight;
				  // 将最终的值取整
				  r = Math.round(r);
				  g = Math.round(g);
				  b = Math.round(b);

				  if (!!callback) {
					// 返回图片主题色的 RGB 颜色值
					callback(`${r},${g},${b}`);
				  }
			}
		})
}

画布

    <!-- 画布,用于获取主题色 -->
    <canvas
      canvas-id="getThemeColorCanvas"
      id="getThemeColorCanvas"
      type="2d"
      style="position: absolute; left: -600rpx; top: -600rpx">
    </canvas>

2.将返回的颜色添加到数组,切换轮播图时改变当前背景色,通过css变量实现。

      <view class="background" :style="{ '--main-bg-color': nowBgColor }">
      // 如果要渐变,直接叠一层基础色渐变,css变量可以使用渐变色,但是
        <view class="background-linear"></view>
      </view>
      
  .background {
    --main-bg-color: #ffffff;
    width: 100%;
    height: 500rpx;
    position: relative;
    z-index: -10;
    background-size: 100% 500rpx;
    background-color: var(--main-bg-color);
    // 动画
    transition: background 1s linear;  
  }

3.其他

如果要实现有动画的渐变色效果,以叠加一层基础色的方式实现。因为css的渐变色函数是background-image,不是background-color,transition对background-image无反应。

但是对于部分老旧手机,基础色叠加颜色显示可能有问题。这种情况直接改成背景为轮播大图更简单。